// app.jsx — main shell const ACCENT = '#5B7CFA'; function App() { const [route, setRoute] = React.useState('home'); const [openAsset, setOpenAsset] = React.useState(null); const [openProject, setOpenProject] = React.useState(null); const [showNewRecorder, setShowNewRecorder] = React.useState(false); const [dataReady, setDataReady] = React.useState(false); const [loadError, setLoadError] = React.useState(null); const [sidebarCollapsed, setSidebarCollapsed] = React.useState(() => { try { const stored = localStorage.getItem('df.sidebar.collapsed'); if (stored != null) return stored === '1'; // Default: collapsed on mobile, expanded on desktop. return typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 768px)').matches; } catch { return false; } }); const toggleSidebar = React.useCallback(() => { setSidebarCollapsed(prev => { const next = !prev; try { localStorage.setItem('df.sidebar.collapsed', next ? '1' : '0'); } catch {} return next; }); }, []); React.useEffect(() => { document.documentElement.style.setProperty('--accent', ACCENT); document.documentElement.style.setProperty('--accent-soft', hexToRgba(ACCENT, 0.14)); document.documentElement.style.setProperty('--accent-soft-2', hexToRgba(ACCENT, 0.22)); document.documentElement.style.setProperty('--accent-text', lighten(ACCENT, 0.25)); document.documentElement.style.setProperty('--accent-hover', lighten(ACCENT, 0.08)); }, []); React.useEffect(() => { window.ZAMPP_API.loadData() .then(() => setDataReady(true)) .catch(err => { console.error('[Dragonflight] load failed:', err); setLoadError(err.message || 'Failed to load'); setDataReady(true); }); }, []); const navigate = (id) => { setOpenAsset(null); setRoute(id); }; const openProjectFromAnywhere = (p) => { setOpenAsset(null); setOpenProject(p); setRoute('library'); }; const crumbs = React.useMemo(() => { if (openAsset) return [ { label: 'Library', to: 'library' }, { label: openAsset.project || 'Library', to: 'library' }, { label: openAsset.name }, ]; if (openProject) return [ { label: 'Projects', to: 'projects' }, { label: openProject.name }, ]; const labels = { home: ['Home'], dashboard: ['Dashboard'], library: ['Library'], projects: ['Projects'], upload: ['Ingest', 'Upload'], recorders: ['Ingest', 'Recorders'], schedule: ['Ingest', 'Schedule'], youtube: ['Ingest', 'YouTube'], capture: ['Ingest', 'Capture'], monitors: ['Ingest', 'Monitors'], jobs: ['Jobs'], editor: ['Editor'], users: ['Admin', 'Users & Groups'], tokens: ['Admin', 'Tokens'], containers: ['Admin', 'Containers'], cluster: ['Admin', 'Cluster'], settings: ['Admin', 'Settings'], }; return (labels[route] || ['Home']).map(label => ({ label })); }, [route, openAsset, openProject]); if (!dataReady) { return ( <>