98 lines
3.2 KiB
TypeScript
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>
|
|
);
|
|
}
|