Spaces:
Sleeping
Sleeping
| import { NavLink } from 'react-router-dom'; | |
| import { BarChart3, FileText, GitBranch, Home, MessageSquare, Network, ShieldAlert, Workflow } from 'lucide-react'; | |
| import { useRepoStore } from '../../store/useRepoStore'; | |
| import { repoShortName } from '../../utils/formatters'; | |
| const NAV_ITEMS = [ | |
| { path: '/', icon: Home, label: 'Home', always: true }, | |
| { path: '/dashboard', icon: BarChart3, label: 'Dashboard' }, | |
| { path: '/architecture', icon: GitBranch, label: 'Architecture' }, | |
| { path: '/workflow', icon: Workflow, label: 'Workflow' }, | |
| { path: '/assistant', icon: MessageSquare, label: 'Assistant' }, | |
| { path: '/impact', icon: ShieldAlert, label: 'Impact' }, | |
| { path: '/documentation', icon: FileText, label: 'Docs' }, | |
| ]; | |
| export default function Sidebar() { | |
| const { repoId, ingestionData } = useRepoStore(); | |
| const isActive = Boolean(repoId); | |
| return ( | |
| <aside className="fixed left-0 top-0 z-40 hidden h-full w-64 flex-col border-r border-white/10 bg-[#0a0f1a]/95 backdrop-blur lg:flex"> | |
| <div className="border-b border-white/10 p-5"> | |
| <div className="flex items-center gap-3"> | |
| <div className="flex h-9 w-9 items-center justify-center rounded-lg bg-cyan-500/15 ring-1 ring-cyan-400/30"> | |
| <Network className="h-5 w-5 text-cyan-300" /> | |
| </div> | |
| <div> | |
| <p className="font-display text-sm font-bold leading-tight text-white">CodeAtlas</p> | |
| <p className="text-[10px] uppercase tracking-[0.2em] text-slate-500">Enterprise</p> | |
| </div> | |
| </div> | |
| </div> | |
| {isActive && ( | |
| <div className="m-3 rounded-lg border border-emerald-500/20 bg-emerald-500/8 p-3"> | |
| <div className="mb-1 flex items-center gap-2"> | |
| <span className="h-2 w-2 rounded-full bg-emerald-400 pulse-dot" /> | |
| <span className="text-xs font-medium text-emerald-300">Repository Active</span> | |
| </div> | |
| <p className="path-text font-mono text-[11px] leading-4 text-slate-400">{repoShortName(ingestionData?.github_url || '')}</p> | |
| </div> | |
| )} | |
| <nav className="flex-1 space-y-1 p-3"> | |
| {NAV_ITEMS.map(({ path, icon: Icon, label, always }) => { | |
| const disabled = !always && !isActive; | |
| return ( | |
| <NavLink | |
| key={path} | |
| to={disabled ? '#' : path} | |
| aria-disabled={disabled} | |
| className={({ isActive: navActive }) => | |
| [ | |
| 'flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm transition-colors', | |
| disabled ? 'pointer-events-none opacity-35' : 'hover:bg-white/6', | |
| navActive && !disabled | |
| ? 'border border-cyan-400/20 bg-cyan-500/12 text-cyan-200' | |
| : 'text-slate-400 hover:text-slate-100', | |
| ].join(' ') | |
| } | |
| > | |
| <Icon className="h-4 w-4 flex-shrink-0" /> | |
| <span>{label}</span> | |
| </NavLink> | |
| ); | |
| })} | |
| </nav> | |
| <div className="border-t border-white/10 p-4"> | |
| <div className="rounded-lg border border-blue-500/15 bg-blue-500/8 px-3 py-2"> | |
| <div className="flex items-center gap-2"> | |
| <span className="flex h-6 w-6 items-center justify-center rounded-md bg-blue-500/20 text-[10px] font-bold text-blue-200">AI</span> | |
| <div> | |
| <p className="text-xs font-medium text-blue-200">IBM Bob</p> | |
| <p className="text-[10px] text-slate-500">Inference Intelligence</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </aside> | |
| ); | |
| } | |