import { useCallback, useEffect, useState } from 'react' import { useLocation } from 'react-router-dom' import { LayoutGrid, Network, Clock, FileOutput, BarChart3, TrendingUp, Settings, PanelLeftClose, PanelLeftOpen, MessageSquareText, ListChecks, BookOpen, Code2, Library, AlertTriangle, } from 'lucide-react' import { cn } from '@/lib/utils' import { useUserPreferencesStore } from '@/store/userPreferencesStore' import { sidebarApi } from '@/api' import type { SidebarStatsResponse } from '@/api/sidebar' import { NavItem } from './NavItem' // Semantic icon colors — each nav item gets a unique color for visual landmarks const NAV_COLORS = { dashboard: '#22d3ee', // cyan-400 flows: '#a78bfa', // violet-400 sessions: '#34d399', // emerald-400 exports: '#60a5fa', // blue-400 stepLib: '#fb923c', // orange-400 scripts: '#2dd4bf', // teal-400 analytics: '#38bdf8', // sky-400 guides: '#a3e635', // lime-400 feedback: '#818cf8', // indigo-400 } as const export function Sidebar() { const sidebarCollapsed = useUserPreferencesStore(s => s.sidebarCollapsed) const toggleSidebar = useUserPreferencesStore(s => s.toggleSidebar) const location = useLocation() const [stats, setStats] = useState(null) const refreshStats = useCallback(() => { sidebarApi.getStats().then(setStats).catch(() => {}) }, []) // Fetch sidebar stats — refreshes on navigation useEffect(() => { refreshStats() }, [location.pathname, refreshStats]) // Refresh when sessions are created or completed useEffect(() => { window.addEventListener('session-changed', refreshStats) return () => window.removeEventListener('session-changed', refreshStats) }, [refreshStats]) const handleSidebarWheel = (e: React.WheelEvent) => { const sidebar = e.currentTarget const canSidebarScroll = sidebar.scrollHeight > sidebar.clientHeight const atTop = sidebar.scrollTop <= 0 const atBottom = sidebar.scrollTop + sidebar.clientHeight >= sidebar.scrollHeight - 1 // If sidebar can't consume wheel movement, forward it to main content scroller. if (!canSidebarScroll || (e.deltaY < 0 && atTop) || (e.deltaY > 0 && atBottom)) { const main = document.querySelector('.main-content') as HTMLElement | null if (main) { main.scrollTop += e.deltaY e.preventDefault() } } } return ( ) }