veza/apps/web/src/components/layout/Sidebar.tsx

92 lines
3.1 KiB
TypeScript
Raw Normal View History

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>
);
}