63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
'use client';
|
|
|
|
import Link from 'next/link';
|
|
import { Boxes, Settings2, ShieldCheck, Users } from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
import { PublicUser } from '@/lib/api';
|
|
|
|
const links = [
|
|
{
|
|
href: '/admin/users',
|
|
label: 'Пользователи',
|
|
icon: Users,
|
|
permissions: ['canViewUsers', 'canManageUsers'] as const
|
|
},
|
|
{
|
|
href: '/admin/oauth',
|
|
label: 'OAuth',
|
|
icon: Boxes,
|
|
permissions: ['canViewOAuth', 'canManageOAuth'] as const
|
|
},
|
|
{
|
|
href: '/admin/rbac',
|
|
label: 'Роли',
|
|
icon: ShieldCheck,
|
|
permissions: ['canManageRoles'] as const,
|
|
superAdminOnly: true
|
|
},
|
|
{
|
|
href: '/admin/settings',
|
|
label: 'Настройки',
|
|
icon: Settings2,
|
|
permissions: ['canManageSettings'] as const
|
|
}
|
|
];
|
|
|
|
export function AdminNav({ active, user }: { active: string; user: PublicUser }) {
|
|
const visible = links.filter((link) => {
|
|
if (link.superAdminOnly && !user.canManageRoles) return false;
|
|
return link.permissions.some((permission) => Boolean(user[permission])) || user.isSuperAdmin;
|
|
});
|
|
|
|
return (
|
|
<nav className="mb-8 flex flex-wrap gap-2">
|
|
{visible.map((link) => {
|
|
const isActive = active === link.href;
|
|
return (
|
|
<Link
|
|
key={link.href}
|
|
href={link.href}
|
|
className={cn(
|
|
'inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-colors',
|
|
isActive ? 'bg-black !text-white shadow-sm' : 'bg-[#f4f5f8] text-[#1f2430] hover:bg-[#eceef4]'
|
|
)}
|
|
>
|
|
<link.icon className={cn('h-4 w-4', isActive ? '!text-white' : 'text-current')} />
|
|
<span className={isActive ? '!text-white' : undefined}>{link.label}</span>
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
);
|
|
}
|