diff --git a/frontend/index.html b/frontend/index.html index 1a51cb8..7d8fbf6 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -20,9 +20,9 @@ var c = localStorage.getItem('umbra-accent-color'); if (c) { var p = JSON.parse(c); - if (p.h) h = p.h; - if (p.s) s = p.s; - if (p.l) l = p.l; + if (p.h && /^\d+$/.test(p.h)) h = p.h; + if (p.s && /^\d+\.?\d*%$/.test(p.s)) s = p.s; + if (p.l && /^\d+\.?\d*%$/.test(p.l)) l = p.l; } } catch(e) {} document.getElementById('umbra-accent').textContent = diff --git a/frontend/src/hooks/usePrefetch.ts b/frontend/src/hooks/usePrefetch.ts index 96dbf60..db78bab 100644 --- a/frontend/src/hooks/usePrefetch.ts +++ b/frontend/src/hooks/usePrefetch.ts @@ -12,14 +12,24 @@ export function usePrefetch(enabled: boolean) { const queryClient = useQueryClient(); const { settings } = useSettings(); const hasPrefetched = useRef(false); + const prevEnabled = useRef(false); + + // Reset on re-lock so subsequent unlocks refresh stale data (W-02) + useEffect(() => { + if (prevEnabled.current && !enabled) { + hasPrefetched.current = false; + } + prevEnabled.current = enabled; + }, [enabled]); useEffect(() => { - if (!enabled || hasPrefetched.current) return; + // Wait for settings to load so upcoming_days is accurate (S-05) + if (!enabled || hasPrefetched.current || !settings) return; hasPrefetched.current = true; const now = new Date(); const clientDate = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`; - const days = settings?.upcoming_days || 7; + const days = settings.upcoming_days || 7; // Prefetch all main page queries (no-op if already cached and fresh) queryClient.prefetchQuery({ @@ -58,5 +68,5 @@ export function usePrefetch(enabled: boolean) { queryKey: ['locations'], queryFn: () => api.get('/locations').then(r => r.data), }); - }, [enabled, queryClient, settings?.upcoming_days]); + }, [enabled, queryClient, settings]); }