mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:41:09 +02:00
fix(web): fix userSettings.nav undefined error in guest mode
- Clock: Replace local user-settings store with shared theme store from @manacore/shared-theme to support nav settings properly - All apps: Add optional chaining and fallback values when accessing userSettings.nav.desktopPosition and userSettings.nav.hiddenNavItems to prevent TypeError when user is not authenticated Apps fixed: calendar, chat, clock, contacts, manacore, manadeck, picture, todo Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
753e6fd17f
commit
6713919e09
9 changed files with 40 additions and 117 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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<UserSettings>(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<K extends keyof UserSettings>(key: K, value: UserSettings[K]) {
|
||||
settings = { ...settings, [key]: value };
|
||||
saveSettings(settings);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update multiple settings
|
||||
*/
|
||||
updateMany(updates: Partial<UserSettings>) {
|
||||
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(),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@
|
|||
onModeChange={handleModeChange}
|
||||
{isCollapsed}
|
||||
onCollapsedChange={handleCollapsedChange}
|
||||
desktopPosition={userSettings.nav.desktopPosition}
|
||||
desktopPosition={userSettings.nav?.desktopPosition || 'bottom'}
|
||||
showThemeToggle={true}
|
||||
showThemeVariants={true}
|
||||
{themeVariantItems}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue