/* ============ App root ============ */ const NAV = [ { id: 'dashboard', label: 'Dashboard', icon: 'dashboard' }, { id: 'clients', label: 'Clients', icon: 'people' }, { id: 'signings', label: 'Signings', icon: 'calendar' }, { id: 'mileage', label: 'Mileage', icon: 'car' }, { id: 'reports', label: 'Reports', icon: 'chart' }, { id: 'settings', label: 'Settings', icon: 'gear' }, ]; function App() { const state = useStore(); const saving = useSavingFlag(); const [view, setView] = React.useState(() => location.hash.replace('#','') || 'dashboard'); const [search, setSearch] = React.useState(''); const searchRef = React.useRef(null); // Apply accent from settings React.useEffect(() => { document.body.dataset.accent = state.settings.accent || 'blue'; }, [state.settings.accent]); // Persist view in hash React.useEffect(() => { location.hash = view; }, [view]); React.useEffect(() => { const h = () => setView(location.hash.replace('#','') || 'dashboard'); window.addEventListener('hashchange', h); return () => window.removeEventListener('hashchange', h); }, []); // ⌘K / Ctrl-K to focus search React.useEffect(() => { const h = (e) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); searchRef.current?.focus(); } }; document.addEventListener('keydown', h); return () => document.removeEventListener('keydown', h); }, []); // Clear search when switching views React.useEffect(() => { setSearch(''); }, [view]); const counts = { clients: state.clients.length, signings: state.signings.filter(s => s.date >= todayISO() && s.status === 'Scheduled').length, mileage: state.mileage.length, }; const title = NAV.find(n => n.id === view)?.label || 'Dashboard'; const renderView = () => { switch (view) { case 'dashboard': return ; case 'clients': return ; case 'signings': return ; case 'mileage': return ; case 'reports': return ; case 'settings': return ; default: return null; } }; const showSearch = ['clients','signings','mileage'].includes(view); // Quick "New" action by view const newAction = () => { if (view === 'clients') Store.Clients.add({}); if (view === 'signings') Store.Signings.add({}); if (view === 'mileage') Store.Mileage.add({}); }; const newLabel = { clients: 'New client', signings: 'New signing', mileage: 'Log trip' }[view]; return (
{/* Sidebar */} {/* Main */}

{title}

{showSearch && ( setSearch(e.target.value)} /> )} {newLabel && ( )}
{renderView()}
); } const root = ReactDOM.createRoot(document.getElementById('root')); root.render();