import React, { useEffect, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { FEATURES } from '../features'; import './Layout.css'; interface LayoutProps { children: React.ReactNode; } interface NavItem { path: string; label: string; icon: string; } /** The five thumb-reachable destinations in the bottom bar. */ const NAV: NavItem[] = [ { path: '/', label: '今日', icon: '◱' }, { path: '/health', label: '健康', icon: '♡' }, { path: '/daily', label: '每日', icon: '◉' }, { path: '/trends', label: '趋势', icon: '◈' }, { path: '/achievements', label: '成就', icon: '▽' }, ]; /** Secondary destinations: the bottom bar only holds five. */ const SECONDARY: NavItem[] = [ { path: '/sleep', label: '睡眠', icon: '☾' }, ...(FEATURES.ai ? [{ path: '/recommendations', label: '建议', icon: '✦' }] : []), { path: '/sync', label: '同步', icon: '⟳' }, { path: '/settings', label: '设置', icon: '⚙' }, ]; type Theme = 'light' | 'dark' | 'system'; /* Dark mode is a deliberate, validated palette rather than an inverted one, so the choice is stamped on and the tokens swap in one place. */ function useTheme(): [Theme, (t: Theme) => void] { const [theme, setTheme] = useState( () => (localStorage.getItem('ghl_theme') as Theme) || 'system' ); useEffect(() => { const root = document.documentElement; if (theme === 'system') root.removeAttribute('data-theme'); else root.setAttribute('data-theme', theme); localStorage.setItem('ghl_theme', theme); }, [theme]); return [theme, setTheme]; } const isActive = (pathname: string, path: string) => path === '/' ? pathname === '/' : pathname.startsWith(path); function Layout({ children }: LayoutProps) { const location = useLocation(); const [theme, setTheme] = useTheme(); const cycle = () => setTheme(theme === 'system' ? 'light' : theme === 'light' ? 'dark' : 'system'); const themeLabel = { system: '自动', light: '浅色', dark: '深色' }[theme]; return (
Garmin Health Lab {/* Wide screens show every destination in one row; narrow screens use the bottom bar instead, where the thumb already is. */}
{children}
); } export default Layout;