包含与我相关、产品、项目、版本主导航和成员管理入口,路由高亮当前页面。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
'use client';
|
|
|
|
import { usePathname, useRouter } from 'next/navigation';
|
|
|
|
const NAV_ITEMS = [
|
|
{ label: '与我相关', path: '/workspace', icon: '📋' },
|
|
{ label: '产品', path: '/products', icon: '📦' },
|
|
{ label: '项目', path: '/projects', icon: '📁' },
|
|
{ label: '版本', path: '/versions', icon: '🏷️' },
|
|
];
|
|
|
|
const ADMIN_ITEMS = [
|
|
{ label: '成员管理', path: '/admin/members', icon: '👥' },
|
|
];
|
|
|
|
export function Sidebar() {
|
|
const pathname = usePathname();
|
|
const router = useRouter();
|
|
|
|
const isActive = (path: string) => pathname.startsWith(path);
|
|
|
|
return (
|
|
<aside className="flex h-screen w-56 flex-col border-r border-gray-200 bg-white">
|
|
<div className="flex h-14 items-center px-4">
|
|
<h1 className="text-lg font-bold text-gray-900">FTB 项目管理</h1>
|
|
</div>
|
|
|
|
<nav className="flex-1 space-y-1 px-2 py-4">
|
|
{NAV_ITEMS.map((item) => (
|
|
<button
|
|
key={item.path}
|
|
onClick={() => router.push(item.path)}
|
|
className={`flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors ${
|
|
isActive(item.path)
|
|
? 'bg-blue-50 font-medium text-blue-700'
|
|
: 'text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
<span>{item.icon}</span>
|
|
<span>{item.label}</span>
|
|
</button>
|
|
))}
|
|
</nav>
|
|
|
|
<div className="border-t border-gray-200 px-2 py-4">
|
|
<p className="mb-2 px-3 text-xs font-medium text-gray-400">管理</p>
|
|
{ADMIN_ITEMS.map((item) => (
|
|
<button
|
|
key={item.path}
|
|
onClick={() => router.push(item.path)}
|
|
className={`flex w-full items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors ${
|
|
isActive(item.path)
|
|
? 'bg-blue-50 font-medium text-blue-700'
|
|
: 'text-gray-700 hover:bg-gray-100'
|
|
}`}
|
|
>
|
|
<span>{item.icon}</span>
|
|
<span>{item.label}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|