import { useState } from 'react'
import { NavLink } from 'react-router-dom'
import { Command, Activity, FolderKanban, Monitor, Settings, Menu, X, Wifi, WifiOff, Loader } from 'lucide-react'
import { useSSEContext } from '../contexts/SSEContext'
import type { SSEStatus } from '../hooks/useSSE'
const navItems = [
{ to: '/', icon: Command, label: 'Hub' },
{ to: '/logs', icon: Activity, label: 'Logs' },
{ to: '/projects', icon: FolderKanban, label: 'Projects' },
{ to: '/sessions', icon: Monitor, label: 'Sessions' },
{ to: '/settings', icon: Settings, label: 'Settings' },
]
/** Small status pill shown in the sidebar footer and mobile header. */
function SSEStatusBadge({ status, showLabel = false }: { status: SSEStatus; showLabel?: boolean }) {
const cfg = {
connected: { icon: Wifi, color: 'text-green-500', label: 'Live' },
connecting: { icon: Loader, color: 'text-yellow-500 animate-spin', label: 'Connecting' },
reconnecting: { icon: Loader, color: 'text-yellow-500 animate-spin', label: 'Reconnecting' },
error: { icon: WifiOff, color: 'text-red-500', label: 'Disconnected' },
}[status]
const Icon = cfg.icon
return (
{showLabel && {cfg.label}}
)
}
export default function Layout({ children }: { children: React.ReactNode }) {
const [expanded, setExpanded] = useState(false)
const [mobileOpen, setMobileOpen] = useState(false)
const { sseStatus } = useSSEContext()
return (
{/* Desktop Nav Rail */}
{/* Mobile Header + Bottom Nav */}
Control Center
{/* Mobile drawer */}
{mobileOpen && (
{navItems.map((item) => (
setMobileOpen(false)}
className={({ isActive }) =>
`flex items-center gap-3 px-4 py-3 rounded-lg ${
isActive
? 'bg-primary/10 text-primary'
: 'text-on-surface-variant'
}`
}
>
{item.label}
))}
)}
{children}
{/* Mobile Bottom Nav */}
)
}