diff --git a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte index bbbee4d8e..2e5d29ecd 100644 --- a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte @@ -302,9 +302,9 @@ { href: '/feedback', label: 'Feedback', icon: 'chat' }, ]); - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('calendar', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('calendar', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // Active tab based on sidebar state: 'tasks' when sidebar is open, 'calendar' when closed diff --git a/apps/chat/apps/web/src/routes/(protected)/+layout.svelte b/apps/chat/apps/web/src/routes/(protected)/+layout.svelte index 339103bb1..2ebd468c9 100644 --- a/apps/chat/apps/web/src/routes/(protected)/+layout.svelte +++ b/apps/chat/apps/web/src/routes/(protected)/+layout.svelte @@ -100,9 +100,9 @@ { href: '/feedback', label: 'Feedback', icon: 'chat' }, ]; - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('chat', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('chat', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // User email for user dropdown @@ -244,7 +244,7 @@ onModeChange={handleModeChange} {isCollapsed} onCollapsedChange={handleCollapsedChange} - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} showThemeToggle={true} showThemeVariants={true} {themeVariantItems} diff --git a/apps/clock/apps/web/src/lib/stores/user-settings.svelte.ts b/apps/clock/apps/web/src/lib/stores/user-settings.svelte.ts index 7cf6b65e0..f88fb5453 100644 --- a/apps/clock/apps/web/src/lib/stores/user-settings.svelte.ts +++ b/apps/clock/apps/web/src/lib/stores/user-settings.svelte.ts @@ -1,105 +1,28 @@ /** - * User Settings Store - Manages user preferences using Svelte 5 runes + * User Settings Store for Clock + * + * This store syncs settings with mana-core-auth and provides: + * - Global settings that apply to all apps + * - Per-app overrides for customization + * - localStorage caching for offline support */ import { browser } from '$app/environment'; +import { createUserSettingsStore } from '@manacore/shared-theme'; +import { authStore } from './auth.svelte'; -export interface UserSettings { - timeFormat: '12h' | '24h'; - firstDayOfWeek: 0 | 1; // 0 = Sunday, 1 = Monday - showSeconds: boolean; - defaultAlarmSound: string; - vibrationEnabled: boolean; -} - -const DEFAULT_SETTINGS: UserSettings = { - timeFormat: '24h', - firstDayOfWeek: 1, // Monday (European default) - showSeconds: false, - defaultAlarmSound: 'default', - vibrationEnabled: true, -}; - -const STORAGE_KEY = 'clock_user_settings'; - -// Load settings from localStorage -function loadSettings(): UserSettings { - if (!browser) return DEFAULT_SETTINGS; - - try { - const stored = localStorage.getItem(STORAGE_KEY); - if (stored) { - return { ...DEFAULT_SETTINGS, ...JSON.parse(stored) }; - } - } catch (e) { - console.error('Failed to load user settings:', e); +// Get auth URL dynamically at runtime +function getAuthUrl(): string { + if (browser && typeof window !== 'undefined') { + const injectedUrl = (window as unknown as { __PUBLIC_MANA_CORE_AUTH_URL__?: string }) + .__PUBLIC_MANA_CORE_AUTH_URL__; + return injectedUrl || 'http://localhost:3001'; } - return DEFAULT_SETTINGS; + return 'http://localhost:3001'; } -// Save settings to localStorage -function saveSettings(settings: UserSettings) { - if (!browser) return; - - try { - localStorage.setItem(STORAGE_KEY, JSON.stringify(settings)); - } catch (e) { - console.error('Failed to save user settings:', e); - } -} - -// State -let settings = $state(loadSettings()); - -export const userSettings = { - // Getters - get timeFormat() { - return settings.timeFormat; - }, - get firstDayOfWeek() { - return settings.firstDayOfWeek; - }, - get showSeconds() { - return settings.showSeconds; - }, - get defaultAlarmSound() { - return settings.defaultAlarmSound; - }, - get vibrationEnabled() { - return settings.vibrationEnabled; - }, - get all() { - return settings; - }, - - /** - * Update a single setting - */ - update(key: K, value: UserSettings[K]) { - settings = { ...settings, [key]: value }; - saveSettings(settings); - }, - - /** - * Update multiple settings - */ - updateMany(updates: Partial) { - settings = { ...settings, ...updates }; - saveSettings(settings); - }, - - /** - * Reset to defaults - */ - reset() { - settings = DEFAULT_SETTINGS; - saveSettings(settings); - }, - - /** - * Initialize (reload from storage) - */ - initialize() { - settings = loadSettings(); - }, -}; +export const userSettings = createUserSettingsStore({ + appId: 'clock', + authUrl: getAuthUrl(), + getAccessToken: () => authStore.getAccessToken(), +}); diff --git a/apps/clock/apps/web/src/routes/(app)/+layout.svelte b/apps/clock/apps/web/src/routes/(app)/+layout.svelte index 9dd20e459..632ffe1e6 100644 --- a/apps/clock/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/clock/apps/web/src/routes/(app)/+layout.svelte @@ -188,9 +188,9 @@ { href: '/feedback', label: 'Feedback', icon: 'chat' }, ]; - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('clock', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('clock', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // Navigation shortcuts (Ctrl+1-9) - use base items for consistent shortcuts @@ -309,7 +309,7 @@ currentPath={$page.url.pathname} appName="Clock" homeRoute="/" - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} onToggleTheme={handleToggleTheme} {isDark} {isSidebarMode} diff --git a/apps/contacts/apps/web/src/routes/(app)/+layout.svelte b/apps/contacts/apps/web/src/routes/(app)/+layout.svelte index c5df82450..77e4b8e38 100644 --- a/apps/contacts/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/contacts/apps/web/src/routes/(app)/+layout.svelte @@ -145,9 +145,9 @@ { href: '/help', label: 'Hilfe', icon: 'help-circle' }, ]; - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('contacts', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('contacts', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // Navigation shortcuts (Ctrl+1-5) - use base items for consistent shortcuts diff --git a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte index f6ad1c0ef..2b628aa49 100644 --- a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte @@ -212,7 +212,7 @@ onModeChange={handleModeChange} {isCollapsed} onCollapsedChange={handleCollapsedChange} - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} showThemeToggle={true} showThemeVariants={true} {themeVariantItems} diff --git a/apps/manadeck/apps/web/src/routes/(app)/+layout.svelte b/apps/manadeck/apps/web/src/routes/(app)/+layout.svelte index a199c8d44..89d73738f 100644 --- a/apps/manadeck/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/manadeck/apps/web/src/routes/(app)/+layout.svelte @@ -41,9 +41,9 @@ { href: '/progress', label: 'Progress', icon: 'chart' }, ]; - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('manadeck', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('manadeck', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // Get pinned themes from user settings (extended themes only) @@ -208,7 +208,7 @@ onModeChange={handleModeChange} {isCollapsed} onCollapsedChange={handleCollapsedChange} - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} showThemeToggle={true} showThemeVariants={true} {themeVariantItems} diff --git a/apps/picture/apps/web/src/routes/app/+layout.svelte b/apps/picture/apps/web/src/routes/app/+layout.svelte index 447101cca..64d4ce04e 100644 --- a/apps/picture/apps/web/src/routes/app/+layout.svelte +++ b/apps/picture/apps/web/src/routes/app/+layout.svelte @@ -105,9 +105,9 @@ { href: '/app/archive', label: 'Archiv', icon: 'archive' }, ]; - // Navigation items filtered by visibility settings + // Navigation items filtered by visibility settings (with fallback for guest mode) const navItems = $derived( - filterHiddenNavItems('picture', baseNavItems, userSettings.nav.hiddenNavItems) + filterHiddenNavItems('picture', baseNavItems, userSettings.nav?.hiddenNavItems || {}) ); // View mode options for tab group @@ -267,7 +267,7 @@ onModeChange={handleModeChange} {isCollapsed} onCollapsedChange={handleCollapsedChange} - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} showThemeToggle={true} showThemeVariants={true} {themeVariantItems} diff --git a/apps/todo/apps/web/src/routes/(app)/+layout.svelte b/apps/todo/apps/web/src/routes/(app)/+layout.svelte index b1821dbd4..4b8ce2cd6 100644 --- a/apps/todo/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/todo/apps/web/src/routes/(app)/+layout.svelte @@ -177,8 +177,8 @@ // Navigation items (base items + dynamic label items in sidebar mode, filtered by visibility settings) const navItems = $derived.by(() => { - // Start with base items, filter out hidden ones - let items = filterHiddenNavItems('todo', baseNavItems, userSettings.nav.hiddenNavItems); + // Start with base items, filter out hidden ones (with fallback for guest mode) + let items = filterHiddenNavItems('todo', baseNavItems, userSettings.nav?.hiddenNavItems || {}); // In sidebar mode, add tags as sub-items if available if (isSidebarMode && labelsStore.labels.length > 0) { @@ -408,7 +408,7 @@ onModeChange={handleModeChange} {isCollapsed} onCollapsedChange={handleCollapsedChange} - desktopPosition={userSettings.nav.desktopPosition} + desktopPosition={userSettings.nav?.desktopPosition || 'bottom'} showThemeToggle={true} showThemeVariants={true} {themeVariantItems}