132 lines
3.3 KiB
TypeScript
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>
|
|
)
|
|
} |