diff --git a/apps/manacore/apps/web/src/lib/i18n/index.ts b/apps/manacore/apps/web/src/lib/i18n/index.ts index 913950ab1..8287b37f9 100644 --- a/apps/manacore/apps/web/src/lib/i18n/index.ts +++ b/apps/manacore/apps/web/src/lib/i18n/index.ts @@ -15,20 +15,21 @@ const defaultLocale = 'de'; function registerLocale(lang: SupportedLocale) { register(lang, async () => { - const [common, dashboard, credits, profile, subscription, todo, app_slider] = await Promise.all( - [ + const [common, nav, dashboard, credits, profile, subscription, todo, app_slider] = + await Promise.all([ import(`./locales/common/${lang}.json`), + import(`./locales/nav/${lang}.json`), import(`./locales/dashboard/${lang}.json`), import(`./locales/credits/${lang}.json`), import(`./locales/profile/${lang}.json`), import(`./locales/subscription/${lang}.json`), import(`./locales/todo/${lang}.json`), import(`./locales/app_slider/${lang}.json`), - ] - ); + ]); return { common: common.default, + nav: nav.default, dashboard: dashboard.default, credits: credits.default, profile: profile.default, diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/nav/de.json b/apps/manacore/apps/web/src/lib/i18n/locales/nav/de.json new file mode 100644 index 000000000..df738e2dc --- /dev/null +++ b/apps/manacore/apps/web/src/lib/i18n/locales/nav/de.json @@ -0,0 +1,16 @@ +{ + "home": "Home", + "dashboard": "Dashboard", + "spiral": "Spiral", + "observatory": "Observatory", + "credits": "Credits", + "gifts": "Geschenke", + "api_keys": "API Keys", + "profile": "Profil", + "settings": "Einstellungen", + "tags": "Tags", + "admin": "Admin", + "all_themes": "Alle Themes", + "menu": "Menü", + "sign_out": "Abmelden" +} diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/nav/en.json b/apps/manacore/apps/web/src/lib/i18n/locales/nav/en.json new file mode 100644 index 000000000..0f03b6ba1 --- /dev/null +++ b/apps/manacore/apps/web/src/lib/i18n/locales/nav/en.json @@ -0,0 +1,16 @@ +{ + "home": "Home", + "dashboard": "Dashboard", + "spiral": "Spiral", + "observatory": "Observatory", + "credits": "Credits", + "gifts": "Gifts", + "api_keys": "API Keys", + "profile": "Profile", + "settings": "Settings", + "tags": "Tags", + "admin": "Admin", + "all_themes": "All Themes", + "menu": "Menu", + "sign_out": "Sign out" +} diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/nav/es.json b/apps/manacore/apps/web/src/lib/i18n/locales/nav/es.json new file mode 100644 index 000000000..573ac0bfe --- /dev/null +++ b/apps/manacore/apps/web/src/lib/i18n/locales/nav/es.json @@ -0,0 +1,16 @@ +{ + "home": "Inicio", + "dashboard": "Panel", + "spiral": "Spiral", + "observatory": "Observatorio", + "credits": "Créditos", + "gifts": "Regalos", + "api_keys": "API Keys", + "profile": "Perfil", + "settings": "Ajustes", + "tags": "Tags", + "admin": "Admin", + "all_themes": "Todos los temas", + "menu": "Menú", + "sign_out": "Cerrar sesión" +} diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/nav/fr.json b/apps/manacore/apps/web/src/lib/i18n/locales/nav/fr.json new file mode 100644 index 000000000..5b902dd21 --- /dev/null +++ b/apps/manacore/apps/web/src/lib/i18n/locales/nav/fr.json @@ -0,0 +1,16 @@ +{ + "home": "Accueil", + "dashboard": "Tableau de bord", + "spiral": "Spiral", + "observatory": "Observatoire", + "credits": "Crédits", + "gifts": "Cadeaux", + "api_keys": "Clés API", + "profile": "Profil", + "settings": "Paramètres", + "tags": "Tags", + "admin": "Admin", + "all_themes": "Tous les thèmes", + "menu": "Menu", + "sign_out": "Déconnexion" +} diff --git a/apps/manacore/apps/web/src/lib/i18n/locales/nav/it.json b/apps/manacore/apps/web/src/lib/i18n/locales/nav/it.json new file mode 100644 index 000000000..9f33a8f1c --- /dev/null +++ b/apps/manacore/apps/web/src/lib/i18n/locales/nav/it.json @@ -0,0 +1,16 @@ +{ + "home": "Home", + "dashboard": "Dashboard", + "spiral": "Spiral", + "observatory": "Osservatorio", + "credits": "Crediti", + "gifts": "Regali", + "api_keys": "Chiavi API", + "profile": "Profilo", + "settings": "Impostazioni", + "tags": "Tag", + "admin": "Admin", + "all_themes": "Tutti i temi", + "menu": "Menu", + "sign_out": "Esci" +} diff --git a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte index 82f9cd9ec..9f0f8e4fd 100644 --- a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte @@ -5,7 +5,7 @@ import { onDestroy, setContext } from 'svelte'; import KeyboardShortcutsModal from '$lib/components/KeyboardShortcutsModal.svelte'; import SessionWarning from '$lib/components/SessionWarning.svelte'; - import { locale } from 'svelte-i18n'; + import { locale, _ } from 'svelte-i18n'; import { PillNavigation, TagStrip, @@ -83,7 +83,7 @@ })), { id: 'all-themes', - label: 'Alle Themes', + label: $_('nav.all_themes'), icon: 'palette', onClick: () => goto('/themes'), active: false, @@ -95,15 +95,28 @@ let currentLocale = $derived($locale || 'de'); function handleLocaleChange(newLocale: string) { setLocale(newLocale as any); + userSettings.updateGlobal({ locale: newLocale }); AppEvents.languageChanged(newLocale); } + + // Sync locale from user settings (backend) after login + $effect(() => { + if (userSettings.loaded && userSettings.locale) { + const settingsLocale = userSettings.locale; + if (supportedLocales.includes(settingsLocale as any) && settingsLocale !== $locale) { + setLocale(settingsLocale as any); + } + } + }); let languageItems = $derived( getLanguageDropdownItems(supportedLocales, currentLocale, handleLocaleChange) ); let currentLanguageLabel = $derived(getCurrentLanguageLabel(currentLocale)); // ── User / Guest awareness ────────────────────────────── - let userEmail = $derived(authStore.isAuthenticated ? authStore.user?.email || 'Menü' : ''); + let userEmail = $derived( + authStore.isAuthenticated ? authStore.user?.email || $_('nav.menu') : '' + ); // ── Tags ──────────────────────────────────────────────── const allTags = useAllTags(); @@ -124,30 +137,30 @@ }); // ── Navigation ────────────────────────────────────────── - const baseNavItems: PillNavItem[] = [ - { href: '/home', label: 'Home', icon: 'home' }, - { href: '/dashboard', label: 'Dashboard', icon: 'grid' }, - { href: '/spiral', label: 'Spiral', icon: 'spiral' }, - { href: '/observatory', label: 'Observatory', icon: 'eye' }, - { href: '/credits', label: 'Credits', icon: 'creditCard' }, - { href: '/gifts', label: 'Geschenke', icon: 'gift' }, - { href: '/api-keys', label: 'API Keys', icon: 'key' }, - { href: '/profile', label: 'Profil', icon: 'user' }, - { href: '/settings', label: 'Settings', icon: 'settings' }, + let baseNavItems = $derived([ + { href: '/home', label: $_('nav.home'), icon: 'home' }, + { href: '/dashboard', label: $_('nav.dashboard'), icon: 'grid' }, + { href: '/spiral', label: $_('nav.spiral'), icon: 'spiral' }, + { href: '/observatory', label: $_('nav.observatory'), icon: 'eye' }, + { href: '/credits', label: $_('nav.credits'), icon: 'creditCard' }, + { href: '/gifts', label: $_('nav.gifts'), icon: 'gift' }, + { href: '/api-keys', label: $_('nav.api_keys'), icon: 'key' }, + { href: '/profile', label: $_('nav.profile'), icon: 'user' }, + { href: '/settings', label: $_('nav.settings'), icon: 'settings' }, { href: '/', - label: 'Tags', + label: $_('nav.tags'), icon: 'tag', onClick: handleTagStripToggle, active: isTagStripVisible, }, - ]; + ]); let isAdmin = $derived(authStore.user?.role === 'admin'); let navItems = $derived( isAdmin ? [...baseNavItems, { href: '/admin', label: 'Admin', icon: 'shield' }] : baseNavItems ); - const navRoutes = navItems.map((item) => item.href); + let navRoutes = $derived(navItems.map((item) => item.href)); function handleKeydown(event: KeyboardEvent) { const target = event.target as HTMLElement;