11'use client' ;
22
3+ import { useState } from 'react' ;
34import Link from 'next/link' ;
45import { usePathname , useRouter } from 'next/navigation' ;
5- import { LayoutDashboard , Globe , Key , LogOut , Zap } from 'lucide-react' ;
6+ import { LayoutDashboard , Globe , Key , LogOut , Zap , ChevronLeft , ChevronRight } from 'lucide-react' ;
67import { useAuthStore } from '@/store/authStore' ;
78import { Button } from './ui/button' ;
89import { cn } from '@/lib/utils' ;
@@ -11,6 +12,7 @@ export default function DashboardSidebar() {
1112 const pathname = usePathname ( ) ;
1213 const router = useRouter ( ) ;
1314 const { user, logout } = useAuthStore ( ) ;
15+ const [ isCollapsed , setIsCollapsed ] = useState ( false ) ;
1416
1517 const menuItems = [
1618 {
@@ -41,70 +43,107 @@ export default function DashboardSidebar() {
4143 } ;
4244
4345 return (
44- < aside className = "w-64 border-r bg-card flex flex-col" >
46+ < aside
47+ className = { cn (
48+ "border-r bg-card flex flex-col transition-all duration-300 sticky top-0 h-screen" ,
49+ isCollapsed ? "w-20" : "w-64"
50+ ) }
51+ >
4552 { /* Header */ }
46- < div className = "border-b px-6 py-5" >
47- < div className = "flex items-center gap-3" >
48- < div className = "h-10 w-10 rounded-xl bg-gradient-to-br from-blue-600 to-purple-600 flex items-center justify-center shadow-lg" >
53+ < div className = "border-b px-6 py-5 relative" >
54+ < div className = { cn (
55+ "flex items-center transition-all duration-300" ,
56+ isCollapsed ? "justify-center" : "gap-3"
57+ ) } >
58+ < div className = "h-10 w-10 rounded-xl bg-gradient-to-br from-blue-600 to-purple-600 flex items-center justify-center shadow-lg flex-shrink-0" >
4959 < Zap className = "h-5 w-5 text-white" />
5060 </ div >
51- < div >
52- < h2 className = "font-bold text-base" > Krakens</ h2 >
53- < p className = "text-xs text-muted-foreground" > Analytics Platform</ p >
54- </ div >
61+ { ! isCollapsed && (
62+ < div className = "overflow-hidden" >
63+ < h2 className = "font-bold text-base whitespace-nowrap" > Krakens</ h2 >
64+ < p className = "text-xs text-muted-foreground whitespace-nowrap" > Analytics Platform</ p >
65+ </ div >
66+ ) }
5567 </ div >
68+
69+ { /* Toggle Button */ }
70+ < button
71+ onClick = { ( ) => setIsCollapsed ( ! isCollapsed ) }
72+ className = "absolute -right-3 top-1/2 -translate-y-1/2 h-6 w-6 rounded-full border bg-card shadow-md flex items-center justify-center hover:bg-muted transition-colors"
73+ >
74+ { isCollapsed ? (
75+ < ChevronRight className = "h-4 w-4" />
76+ ) : (
77+ < ChevronLeft className = "h-4 w-4" />
78+ ) }
79+ </ button >
5680 </ div >
5781
5882 { /* Navigation */ }
59- < div className = "flex-1 px-3 py-4" >
83+ < div className = "flex-1 px-3 py-4 overflow-y-auto " >
6084 < div className = "space-y-1" >
61- < p className = "px-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2" >
62- Main Menu
63- </ p >
85+ { ! isCollapsed && (
86+ < p className = "px-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2" >
87+ Main Menu
88+ </ p >
89+ ) }
6490 { menuItems . map ( ( item ) => (
6591 < Link
6692 key = { item . url }
6793 href = { item . url }
6894 className = { cn (
69- 'flex items-center gap-3 px-3 py-2.5 rounded-lg transition-all group' ,
95+ 'flex items-center gap-3 px-3 py-2.5 rounded-lg transition-all group relative ' ,
7096 isActive ( item . url )
7197 ? 'bg-primary text-primary-foreground'
72- : 'hover:bg-muted text-muted-foreground hover:text-foreground'
98+ : 'hover:bg-muted text-muted-foreground hover:text-foreground' ,
99+ isCollapsed && 'justify-center'
73100 ) }
101+ title = { isCollapsed ? item . title : undefined }
74102 >
75103 < item . icon
76104 className = { cn (
77- 'h-5 w-5 transition-transform group-hover:scale-110' ,
105+ 'h-5 w-5 transition-transform group-hover:scale-110 flex-shrink-0 ' ,
78106 isActive ( item . url ) ? 'text-primary-foreground' : ''
79107 ) }
80108 />
81- < span className = "font-medium text-sm" > { item . title } </ span >
109+ { ! isCollapsed && (
110+ < span className = "font-medium text-sm whitespace-nowrap" > { item . title } </ span >
111+ ) }
82112 </ Link >
83113 ) ) }
84114 </ div >
85115 </ div >
86116
87117 { /* Footer */ }
88118 < div className = "border-t p-4 space-y-2" >
89- < div className = "flex items-center gap-3 px-3 py-2.5 rounded-lg bg-muted/50" >
119+ < div className = { cn (
120+ "flex items-center gap-3 px-3 py-2.5 rounded-lg bg-muted/50" ,
121+ isCollapsed && "justify-center px-0"
122+ ) } >
90123 < div className = "h-9 w-9 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center flex-shrink-0" >
91124 < span className = "text-white font-semibold text-sm" >
92125 { user ?. email ?. [ 0 ] ?. toUpperCase ( ) || 'U' }
93126 </ span >
94127 </ div >
95- < div className = "flex-1 min-w-0" >
96- < p className = "text-sm font-semibold truncate" > { user ?. email || 'User' } </ p >
97- < p className = "text-xs text-muted-foreground truncate" > Account</ p >
98- </ div >
128+ { ! isCollapsed && (
129+ < div className = "flex-1 min-w-0" >
130+ < p className = "text-sm font-semibold truncate" > { user ?. email || 'User' } </ p >
131+ < p className = "text-xs text-muted-foreground truncate" > Account</ p >
132+ </ div >
133+ ) }
99134 </ div >
100135
101136 < Button
102137 variant = "ghost"
103- className = "w-full justify-start text-muted-foreground hover:text-destructive hover:bg-destructive/10"
138+ className = { cn (
139+ "w-full text-muted-foreground hover:text-destructive hover:bg-destructive/10" ,
140+ isCollapsed ? "justify-center px-0" : "justify-start"
141+ ) }
104142 onClick = { handleLogout }
143+ title = { isCollapsed ? "Logout" : undefined }
105144 >
106- < LogOut className = "h-4 w-4 mr-2 " />
107- < span className = "text-sm font-medium" > Logout</ span >
145+ < LogOut className = "h-4 w-4" />
146+ { ! isCollapsed && < span className = "text-sm font-medium ml-2 " > Logout</ span > }
108147 </ Button >
109148 </ div >
110149 </ aside >
0 commit comments