🐛 fix(clock): fix i18n initialization and add missing nav icons

- Fix svelte-i18n locale loading error by waiting for locale before render
- Add isLocaleLoading check to prevent rendering before translations ready
- Export waitLocale from i18n module for proper async initialization

- Add missing icons to PillNavigation component:
  - bell, timer, stopwatch, target, globe for Clock app
  - inbox, check, checkCircle, plus for Todo app

- Update Clock navItems to use proper icons:
  - Timer: clock → timer
  - Stoppuhr: activity → stopwatch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Till-JS 2025-12-03 16:11:01 +01:00
parent 2126cd5d3c
commit 8dcf543ed4
3 changed files with 37 additions and 6 deletions

View file

@ -40,7 +40,7 @@ function getInitialLocale(): SupportedLocale {
return 'de';
}
// Initialize
// Initialize i18n at module scope (required for SSR)
init({
fallbackLocale: 'de',
initialLocale: getInitialLocale(),
@ -53,3 +53,6 @@ export function setLocale(newLocale: SupportedLocale) {
localStorage.setItem('clock-locale', newLocale);
}
}
// Wait for locale to be loaded (useful for SSR)
export { waitLocale } from 'svelte-i18n';

View file

@ -2,7 +2,7 @@
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { locale } from 'svelte-i18n';
import { locale, isLoading as isLocaleLoading } from 'svelte-i18n';
import { PillNavigation } from '@manacore/shared-ui';
import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui';
import { theme } from '$lib/stores/theme.svelte';
@ -14,7 +14,7 @@
} from '$lib/stores/navigation';
import { getLanguageDropdownItems, getCurrentLanguageLabel } from '@manacore/shared-i18n';
import { getPillAppItems } from '@manacore/shared-branding';
import { setLocale, supportedLocales } from '$lib/i18n';
import { setLocale, supportedLocales, waitLocale } from '$lib/i18n';
import ToastContainer from '$lib/components/ToastContainer.svelte';
import '../app.css';
@ -77,8 +77,8 @@
const navItems: PillNavItem[] = [
{ href: '/', label: 'Übersicht', icon: 'home' },
{ href: '/alarms', label: 'Wecker', icon: 'bell' },
{ href: '/timers', label: 'Timer', icon: 'clock' },
{ href: '/stopwatch', label: 'Stoppuhr', icon: 'activity' },
{ href: '/timers', label: 'Timer', icon: 'timer' },
{ href: '/stopwatch', label: 'Stoppuhr', icon: 'stopwatch' },
{ href: '/pomodoro', label: 'Pomodoro', icon: 'target' },
{ href: '/world-clock', label: 'Weltzeituhr', icon: 'globe' },
{ href: '/settings', label: 'Einstellungen', icon: 'settings' },
@ -137,6 +137,9 @@
}
onMount(async () => {
// Wait for locale to be loaded
await waitLocale();
// Initialize theme
theme.initialize();
@ -165,10 +168,21 @@
<ToastContainer />
{#if isAuthRoute}
{#if $isLocaleLoading}
<!-- Wait for locale to be loaded -->
<div class="flex min-h-screen items-center justify-center bg-background">
<div class="text-center">
<div
class="mb-4 inline-block h-12 w-12 animate-spin rounded-full border-4 border-solid border-primary border-r-transparent"
></div>
<p class="text-muted-foreground">Laden...</p>
</div>
</div>
{:else if isAuthRoute}
<!-- Auth routes: no navigation, just render content -->
{@render children()}
{:else if loading}
<!-- App initialization loading -->
<div class="flex min-h-screen items-center justify-center bg-background">
<div class="text-center">
<div

View file

@ -259,6 +259,20 @@
// Icon SVG paths
const icons: Record<string, string> = {
// Clock app icons
bell: 'M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9',
clock: 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z',
timer: 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z',
stopwatch: 'M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0zM9 3h6m-3-1v2',
activity: 'M13 10V3L4 14h7v7l9-11h-7z',
target: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-14c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z',
globe: 'M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9',
// Todo app icons
inbox: 'M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4',
check: 'M5 13l4 4L19 7',
checkCircle: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z',
plus: 'M12 4v16m8-8H4',
// Original icons
mic: 'M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z',
calendar:
'M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z',