Public Access
feat(ui): modern shadcn/ui theme with violet accent across all pages
Add shadcn/ui (Radix + Tailwind 4) components, zinc/violet theme tokens and self-hosted Inter. New header with user menu, Steam cover art, skeletons and toasts. Replace @mdi/font with lucide-react. Fix: top-owned list on the landing page only showed with top-played entries; numbers use the app language.
This commit is contained in:
1 parent
76a9ac3e6f
commit
e480369a98
43 files changed
+3804
-979
No files matched your search
@@ -1,18 +1,18 @@
|
||||
import {useState} from 'react';
|
||||
import {useNavigate} from 'react-router-dom';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {toast} from 'sonner';
|
||||
|
||||
const RELOAD_DELAY_MS = 4000;
|
||||
|
||||
/**
|
||||
* Starts a library sync (POST /api/library/sync) and calls onStarted after a short delay,
|
||||
* so the caller can reload once Steam data has arrived.
|
||||
* Starts a library sync (POST /api/library/sync), reports the result as a toast and calls
|
||||
* onStarted after a short delay, so the caller can reload once Steam data has arrived.
|
||||
*/
|
||||
export default function useForceSync(onStarted) {
|
||||
const {t} = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [message, setMessage] = useState(null);
|
||||
|
||||
const trigger = async () => {
|
||||
const token = localStorage.getItem('tbp_jwt');
|
||||
@@ -21,7 +21,6 @@ export default function useForceSync(onStarted) {
|
||||
return;
|
||||
}
|
||||
setBusy(true);
|
||||
setMessage(null);
|
||||
try {
|
||||
const response = await fetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/sync`, {
|
||||
method: 'POST',
|
||||
@@ -29,22 +28,22 @@ export default function useForceSync(onStarted) {
|
||||
});
|
||||
if (response.status === 429) {
|
||||
const json = await response.json().catch(() => ({}));
|
||||
setMessage(t('LIBRARY.SYNC_COOLDOWN', {seconds: json.retryAfterSeconds ?? 60}));
|
||||
toast.warning(t('LIBRARY.SYNC_COOLDOWN', {seconds: json.retryAfterSeconds ?? 60}));
|
||||
return;
|
||||
}
|
||||
if (!response.ok) {
|
||||
setMessage(t('LIBRARY.SYNC_FAILED'));
|
||||
toast.error(t('LIBRARY.SYNC_FAILED'));
|
||||
return;
|
||||
}
|
||||
setMessage(t('LIBRARY.SYNC_STARTED'));
|
||||
toast.success(t('LIBRARY.SYNC_STARTED'));
|
||||
setTimeout(onStarted, RELOAD_DELAY_MS);
|
||||
} catch (err) {
|
||||
console.error('sync trigger error:', err);
|
||||
setMessage(t('INFO.ERROR.NETWORK_FAILURE'));
|
||||
toast.error(t('INFO.ERROR.NETWORK_FAILURE'));
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
return {trigger, busy, message};
|
||||
return {trigger, busy};
|
||||
}
|
||||
Reference in new issue
Block a user