Files
sdb-front/src/components/AppSidebar.tsx

132 lines
3.3 KiB
TypeScript

import { Link, useLocation } from 'react-router'
import { Button } from '@/components/ui/button'
import {
Sidebar,
SidebarHeader,
SidebarContent,
SidebarFooter,
SidebarNav,
SidebarNavItem
} from '@/components/ui/sidebar'
import { useAuth } from '@/contexts/AuthContext'
import { useSidebar } from '@/contexts/SidebarContext'
import {
Home,
Settings,
Users,
Activity,
LogOut
} from 'lucide-react'
const navigationItems = [
{
title: 'Dashboard',
href: '/dashboard',
icon: Home,
},
{
title: 'Activity',
href: '/activity',
icon: Activity,
},
{
title: 'Settings',
href: '/settings',
icon: Settings,
},
]
const adminNavigationItems = [
{
title: 'Users',
href: '/admin/users',
icon: Users,
},
]
export function AppSidebar() {
const { user, logout } = useAuth()
const { isOpen } = useSidebar()
const location = useLocation()
const handleLogout = async () => {
try {
await logout()
} catch (error) {
console.error('Logout failed:', error)
}
}
if (!user) return null
const allNavItems = [
...navigationItems,
...(user.role === 'admin' ? adminNavigationItems : [])
]
return (
<Sidebar className={`border-r transition-all duration-300 ${isOpen ? 'w-64' : 'w-16'}`}>
<SidebarHeader>
<div className="flex items-center space-x-2">
<div className="w-8 h-8 bg-primary rounded-lg flex items-center justify-center">
<span className="text-primary-foreground font-bold text-sm">SB</span>
</div>
{isOpen && (
<div>
<h2 className="text-lg font-semibold">Soundboard</h2>
<p className="text-xs text-muted-foreground">v2.0</p>
</div>
)}
</div>
</SidebarHeader>
<SidebarContent>
<SidebarNav>
{allNavItems.map((item) => {
const Icon = item.icon
const isActive = location.pathname === item.href
return (
<Link key={item.href} to={item.href}>
<SidebarNavItem
active={isActive}
title={!isOpen ? item.title : undefined}
>
<Icon className="h-4 w-4" />
{isOpen && item.title}
</SidebarNavItem>
</Link>
)
})}
</SidebarNav>
</SidebarContent>
<SidebarFooter>
<div className="flex items-center gap-3 p-3 rounded-md bg-sidebar-accent/50">
{user.picture && (
<img
src={user.picture}
alt="Profile"
className="w-8 h-8 rounded-full"
/>
)}
{isOpen && (
<div className="flex-1 min-w-0">
<p className="text-sm font-medium truncate">{user.name}</p>
<p className="text-xs text-muted-foreground truncate">{user.email}</p>
</div>
)}
</div>
<Button
variant="ghost"
onClick={handleLogout}
className={`w-full ${isOpen ? 'justify-start' : 'justify-center'}`}
>
<LogOut className="h-4 w-4" />
{isOpen && <span className="ml-2">Sign out</span>}
</Button>
</SidebarFooter>
</Sidebar>
)
}