diff --git a/public/i18n/de.json b/public/i18n/de.json index a5fa5ae..4f1dc50 100644 --- a/public/i18n/de.json +++ b/public/i18n/de.json @@ -80,7 +80,11 @@ "PREV": "Zurück", "NEXT": "Weiter", "PAGE_OF": "Seite {{current}} von {{total}}", - "GAMES": "Spiele" + "GAMES": "Spiele", + "SYNCING": "Synchronisiere mit Steam …", + "SYNCING_FIRST_TIME": "Erste Synchronisation mit Steam läuft. Deine Spiele erscheinen gleich.", + "SYNC_FAILED": "Synchronisation fehlgeschlagen. Bitte später erneut versuchen.", + "LAST_SYNCED": "Zuletzt synchronisiert {{when}}" }, "MAIN": { "WELCOME": "Dein Game-Backlog unter Kontrolle", diff --git a/public/i18n/en.json b/public/i18n/en.json index 076e52d..d9ecdae 100644 --- a/public/i18n/en.json +++ b/public/i18n/en.json @@ -80,7 +80,11 @@ "PREV": "Previous", "NEXT": "Next", "PAGE_OF": "Page {{current}} of {{total}}", - "GAMES": "games" + "GAMES": "games", + "SYNCING": "Syncing with Steam …", + "SYNCING_FIRST_TIME": "First sync with Steam in progress. Your games will appear here shortly.", + "SYNC_FAILED": "Sync failed. Please try again later.", + "LAST_SYNCED": "Last synced {{when}}" }, "MAIN": { "WELCOME": "Control your game backlog", diff --git a/src/pages/Dashboard.jsx b/src/pages/Dashboard.jsx index 206b2d3..fcebf59 100644 --- a/src/pages/Dashboard.jsx +++ b/src/pages/Dashboard.jsx @@ -1,7 +1,9 @@ -import React, {useEffect, useState} from 'react'; +import React, {useCallback, useEffect, useState} from 'react'; import {Link, useNavigate} from 'react-router-dom'; import {useTranslation} from 'react-i18next'; import SteamGameCount from '../components/SteamGameCount'; +import SyncStatusBadge from '../components/SyncStatusBadge.jsx'; +import useLibrarySync from '../hooks/useLibrarySync.js'; const Dashboard = () => { const {t} = useTranslation(); @@ -11,6 +13,24 @@ const Dashboard = () => { const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); + const fetchSteamCount = useCallback(async () => { + const token = localStorage.getItem('tbp_jwt'); + if (!token) return; + try { + const r = await fetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/games-count`, { + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + if (r.ok) { + setSteamData(await r.json()); + } + } catch (err) { + console.error('Error fetching steam data:', err); + } + }, []); + useEffect(() => { const fetchUserData = async () => { const token = localStorage.getItem('tbp_jwt'); @@ -33,23 +53,8 @@ const Dashboard = () => { const data = await profileResponse.json(); setUserData(data); - // If user has a steamId, fetch game count from Core Service if (data.steamId) { - try { - const steamResponse = await fetch(`${import.meta.env.VITE_CORE_API_URL}/api/library/games-count`, { - method: 'GET', - headers: { - 'Authorization': `Bearer ${token}`, - 'Content-Type': 'application/json' - } - }); - if (steamResponse.ok) { - const steamJson = await steamResponse.json(); - setSteamData(steamJson); - } - } catch (steamErr) { - console.error('Error fetching steam data:', steamErr); - } + await fetchSteamCount(); } } else if (profileResponse.status === 401) { localStorage.removeItem('tbp_jwt'); @@ -66,7 +71,14 @@ const Dashboard = () => { }; fetchUserData(); - }, [navigate, t]); + }, [navigate, t, fetchSteamCount]); + + const expectInitialSync = !!userData?.steamId && steamData.count === 0; + const sync = useLibrarySync({ + enabled: !!userData?.steamId, + expectInitialSync, + onComplete: fetchSteamCount, + }); if (isLoading) { return ( @@ -95,6 +107,15 @@ const Dashboard = () => {

{userData?.dashboardMessage}

+ {userData?.steamId && ( +
+ +
+ )}
@@ -125,4 +146,4 @@ const Dashboard = () => { ); }; -export default Dashboard; \ No newline at end of file +export default Dashboard;