import { useState } from 'react' import { NavLink, useNavigate, useLocation } from 'react-router-dom' import { LayoutGrid, Users, Activity, Settings, LogOut, ChevronDown, ShieldCheck, Building2 } from 'lucide-react' import { AppIcon } from './AppIcon' import type { User, App } from '../types' interface Props { user: User; activeSlug?: string } export function Sidebar({ user, activeSlug }: Props) { const navigate = useNavigate() const location = useLocation() // Determine active app's category so its group auto-stays open const routeSlug = location.pathname.startsWith('/app/') ? location.pathname.split('/')[2] : null const activeApp = user.apps.find(a => a.slug === routeSlug) const activeCat = activeApp?.category ?? null // Separate uncategorised from categorised const uncategorised = user.apps.filter(a => !a.category) const grouped = user.apps.reduce>((acc, app) => { if (!app.category) return acc if (!acc[app.category]) acc[app.category] = [] acc[app.category].push(app) return acc }, {}) const categoryNames = Object.keys(grouped).sort() // All categories open by default; track collapsed ones const [collapsed, setCollapsed] = useState>(new Set()) function toggleCat(cat: string) { // Never collapse the active category if (cat === activeCat) return setCollapsed(prev => { const next = new Set(prev) next.has(cat) ? next.delete(cat) : next.add(cat) return next }) } async function logout() { await fetch('/api/auth/logout', { method: 'POST', credentials: 'include' }) navigate('/login', { replace: true }) } return ( ) } function AppNavLink({ app, indent = false }: { app: App; indent?: boolean }) { return ( ({ ...navItem(isActive), paddingLeft: indent ? '1.5rem' : '1rem', })}> {app.name} ) } function SectionLabel({ children }: { children: React.ReactNode }) { return (
{children}
) } function navItem(active: boolean): React.CSSProperties { return { display: 'flex', alignItems: 'center', gap: '0.6rem', padding: '0.5rem 1rem', fontSize: '0.85rem', color: active ? 'var(--gold)' : 'var(--text-muted)', background: active ? 'var(--surface)' : 'transparent', borderLeft: active ? '2px solid var(--gold)' : '2px solid transparent', transition: 'color 0.1s, background 0.1s', } }