96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
'use client'
|
|
|
|
import { usePathname, useRouter } from 'next/navigation'
|
|
import Link from 'next/link'
|
|
import { createClient } from '@/lib/supabase/client'
|
|
import {
|
|
LayoutDashboard,
|
|
BookOpen,
|
|
Plus,
|
|
BarChart3,
|
|
Settings,
|
|
LogOut,
|
|
} from 'lucide-react'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
interface SidebarProps {
|
|
username: string
|
|
role: string
|
|
}
|
|
|
|
const navLinks = [
|
|
{ href: '/dashboard', label: 'Dashboard', icon: LayoutDashboard },
|
|
{ href: '/dashboard/quizzes', label: 'Mes Quizzes', icon: BookOpen },
|
|
{ href: '/dashboard/sessions/create', label: 'Créer Session', icon: Plus },
|
|
{ href: '/dashboard/reports', label: 'Rapports', icon: BarChart3 },
|
|
{ href: '/dashboard/settings', label: 'Paramètres', icon: Settings },
|
|
]
|
|
|
|
export default function Sidebar({ username, role }: SidebarProps) {
|
|
const pathname = usePathname()
|
|
const router = useRouter()
|
|
|
|
const handleLogout = async () => {
|
|
const supabase = createClient()
|
|
await supabase.auth.signOut()
|
|
router.push('/login')
|
|
router.refresh()
|
|
}
|
|
|
|
return (
|
|
<aside className="w-64 bg-background-secondary border-r border-border flex flex-col h-screen sticky top-0">
|
|
{/* Brand */}
|
|
<div className="p-6 border-b border-border">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-12 h-12 bg-primary rounded-xl flex items-center justify-center shadow-lg shadow-primary/30 flex-shrink-0">
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 14H9V8h2v8zm4 0h-2V8h2v8z" fill="white"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<p className="font-bold text-text-primary leading-tight">SolyQuiz</p>
|
|
<p className="text-xs text-text-muted capitalize">{role === 'admin' ? 'Admin Portal' : 'Trainer Portal'}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<nav className="flex-1 p-4 space-y-1 overflow-y-auto">
|
|
{navLinks.map(({ href, label, icon: Icon }) => {
|
|
const isActive = pathname === href || (href !== '/dashboard' && pathname.startsWith(href))
|
|
return (
|
|
<Link
|
|
key={href}
|
|
href={href}
|
|
className={cn('sidebar-link', isActive && 'sidebar-link-active')}
|
|
>
|
|
<Icon size={18} />
|
|
<span>{label}</span>
|
|
</Link>
|
|
)
|
|
})}
|
|
</nav>
|
|
|
|
{/* User profile + logout */}
|
|
<div className="border-t border-border p-4">
|
|
<div className="flex items-center gap-3 mb-3">
|
|
<div className="w-9 h-9 bg-primary/20 rounded-full flex items-center justify-center text-primary font-semibold text-sm flex-shrink-0">
|
|
{username.slice(0, 2).toUpperCase()}
|
|
</div>
|
|
<div className="min-w-0">
|
|
<p className="text-sm font-medium text-text-primary truncate">{username}</p>
|
|
<p className="text-xs text-text-muted truncate">{username}@solyquiz.local</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
onClick={handleLogout}
|
|
className="sidebar-link w-full text-red-400 hover:text-red-300 hover:bg-red-500/10"
|
|
>
|
|
<LogOut size={18} />
|
|
<span>Déconnexion</span>
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
)
|
|
}
|