veza/apps/web/src/components/layout/Sidebar.tsx
2025-12-12 21:34:34 -05:00

98 lines
3.2 KiB
TypeScript

import { Link, useLocation } from 'react-router-dom';
import { useUIStore } from '@/stores/ui';
import { useAuthStore } from '@/stores/auth';
import { useTranslation } from '@/hooks/useTranslation';
import { cn } from '@/lib/utils';
import {
Home,
MessageSquare,
Library,
Users,
Settings,
Shield,
} from 'lucide-react';
export function Sidebar() {
const { sidebarOpen } = useUIStore();
const { user } = useAuthStore();
const { t } = useTranslation();
const location = useLocation();
// Vérifier si l'utilisateur est admin
const isAdmin = user?.role === 'admin' || user?.role === 'super_admin';
const navigation = [
{ name: t('navigation.dashboard'), href: '/dashboard', icon: Home },
{ name: t('navigation.chat'), href: '/chat', icon: MessageSquare },
{ name: t('navigation.library'), href: '/library', icon: Library },
{ name: t('navigation.profile'), href: '/profile', icon: Users },
{ name: t('navigation.settings'), href: '/settings', icon: Settings },
];
// Ajouter les liens admin si l'utilisateur est admin
if (isAdmin) {
navigation.push({
name: 'Roles',
href: '/admin/roles',
icon: Shield,
});
}
return (
<aside
className={cn(
'fixed inset-y-0 left-0 z-40 w-64 bg-background border-r transform transition-transform duration-200 ease-in-out',
sidebarOpen ? 'translate-x-0' : '-translate-x-full',
'md:translate-x-0',
)}
role="navigation"
aria-label={t('navigation.menu')}
>
<div className="flex flex-col h-full">
{/* Logo */}
<div className="flex items-center h-16 px-6 border-b">
<div
className="h-8 w-8 rounded-lg bg-primary flex items-center justify-center"
aria-hidden="true"
>
<span className="text-primary-foreground font-bold text-lg">V</span>
</div>
<span className="ml-2 font-bold text-xl">Veza</span>
</div>
{/* Navigation */}
<nav className="flex-1 px-4 py-6 space-y-2" role="menubar">
{navigation.map((item) => {
const isActive = location.pathname === item.href;
return (
<Link
key={item.name}
to={item.href}
role="menuitem"
tabIndex={0}
aria-current={isActive ? 'page' : undefined}
className={cn(
'flex items-center px-3 py-2 text-sm font-medium rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
isActive
? 'bg-primary text-primary-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-accent',
)}
>
<item.icon className="mr-3 h-5 w-5" aria-hidden="true" />
{item.name}
</Link>
);
})}
</nav>
{/* Footer */}
<footer className="p-4 border-t">
<div className="text-xs text-muted-foreground">
<p>Veza v1.0.0</p>
<p>© 2024 Veza Team</p>
</div>
</footer>
</div>
</aside>
);
}