'use client'; import { usePathname, useRouter } from 'next/navigation'; import { Inbox, Package, FolderKanban, Tag, Users, LayoutGrid, Search, Lightbulb, Clock, Shield, Settings, Sparkles, TriangleAlert } from 'lucide-react'; import { useHasPermission } from '@/components/auth/Guard'; import { useAuthStore } from '@/stores/useAuthStore'; import { useMemberStore } from '@/stores/useMemberStore'; const NAV_GROUPS = [ { label: '工作区', items: [ { label: '小宝预警', path: '/xiaobao-warning', icon: TriangleAlert, permission: 'xiaobao.warning:view' }, { label: '与我相关', path: '/workspace', icon: Inbox, permission: null as string | null }, { label: '产品', path: '/products', icon: Package, permission: 'product:view' }, { label: '项目', path: '/projects', icon: FolderKanban, permission: 'project:view' }, { label: '版本', path: '/versions', icon: Tag, permission: 'version:view' }, { label: '需求池', path: '/requirements', icon: Lightbulb, permission: 'requirement:view' }, { label: '加班记录', path: '/overtime', icon: Clock, permission: 'overtime:view' }, ], }, { label: '管理', items: [ { label: '成员', path: '/admin/members', icon: Users, permission: 'member:view' }, { label: '角色', path: '/admin/roles', icon: Shield, permission: 'role:view' }, { label: 'AI 配置', path: '/admin/ai-config', icon: Sparkles, permission: '*' }, ], }, ]; export function Sidebar() { const pathname = usePathname(); const router = useRouter(); const isActive = (path: string) => pathname === path || (path !== '/' && pathname.startsWith(path)); return ( ); } function UserBlock() { const router = useRouter(); const user = useAuthStore((s) => s.user); const role = useMemberStore((s) => s.roles.find((r) => r.id === user?.roleId)); if (!user) { return (
?

未登录

); } return (
{user.name?.[0] ?? '?'}

{user.name}

{role?.name ?? '-'}

); } function NavGroup({ label, items, isActive, onNavigate }: { label: string; items: { label: string; path: string; icon: any; permission: string | null }[]; isActive: (p: string) => boolean; onNavigate: (p: string) => void; }) { const visibleItems = items.filter((item) => item.permission === null || /* eslint-disable-next-line react-hooks/rules-of-hooks */ true); if (visibleItems.length === 0) return null; return (

{label}

{items.map((item) => ( ))}
); } function NavItem({ item, active, onNavigate }: { item: { label: string; path: string; icon: any; permission: string | null }; active: boolean; onNavigate: (p: string) => void; }) { const hasPerm = useHasPermission(item.permission ?? ''); if (item.permission && !hasPerm) return null; const Icon = item.icon; return ( ); }