/* Sidebar + topbar. Navigation is hash-based so every task and review has a URL that can be pasted into Slack. */ const NAV = [ { label: 'Work', items: [ { route: 'board', title: 'Board', icon: 'board' }, { route: 'my', title: 'My tasks', icon: 'list' }, { route: 'workload', title: 'Workload', icon: 'target' }, ], }, { label: 'Manage', items: [ { route: 'clients', title: 'Clients', icon: 'building', adminOnly: true }, { route: 'team', title: 'Team', icon: 'users', adminOnly: true }, ], }, ]; function Sidebar({ route, go, me, myCount, open, closeMobile }) { return ( ); } function NotificationBell() { const [data, setData] = React.useState({ items: [], unread: 0 }); const [open, setOpen] = React.useState(false); const load = React.useCallback(() => { api.get('/api/notifications?limit=20').then(setData).catch(() => {}); }, []); React.useEffect(() => { load(); const t = setInterval(load, 60000); return () => clearInterval(t); }, [load]); const openPanel = () => { setOpen((v) => !v); if (!open && data.unread) api.post('/api/notifications/read').then(load).catch(() => {}); }; return (