22
33import Link from 'next/link'
44import { usePathname , useSearchParams } from 'next/navigation'
5+ import { useState } from 'react'
56import { Button } from '@/components/ui/button'
67import { useSidebarState , useAuthStore , useStoreHydration , useActionItemsStore } from '@/stores'
78import { ChevronRight , Clock , LogOut , MessageSquare , Sparkles , Star , Target , Zap } from 'lucide-react'
@@ -18,31 +19,31 @@ export function Sidebar() {
1819 const { isConnected, logout } = useAuthStore ( )
1920
2021 // Action items state
21- const { getCountByType, getTotalCount, loading } = useActionItemsStore ( )
22+ const { getCountByType, loading } = useActionItemsStore ( )
23+
24+ // Accordion states - MUI style
25+ const [ actionRequiredOpen , setActionRequiredOpen ] = useState ( true )
26+ const [ quickWinsOpen , setQuickWinsOpen ] = useState ( true )
2227
2328 // Get current tab from URL params
2429 const currentTab = searchParams ?. get ( 'tab' ) || 'assigned'
25- const isDashboardPage = pathname ? pathname . startsWith ( '/dashboard' ) : false
30+ const isDashboardPage = pathname ? .startsWith ( '/dashboard' )
2631
27- // Badge count helpers
32+ // Badge count helpers - Dinamik hesaplama
2833 const getBadgeCount = ( type : 'assigned' | 'mentions' | 'stale' | 'goodFirstIssues' | 'easyFixes' ) => getCountByType ( type )
29- const getTotalActionCount = ( ) => getTotalCount ( )
34+ const getActionRequiredTotal = ( ) => getBadgeCount ( 'assigned' ) + getBadgeCount ( 'mentions' ) + getBadgeCount ( 'stale' )
35+ const getQuickWinsTotal = ( ) => getBadgeCount ( 'goodFirstIssues' ) + getBadgeCount ( 'easyFixes' )
3036
3137 // Show loading state in badges
3238 const getBadgeContent = ( type : 'assigned' | 'mentions' | 'stale' | 'goodFirstIssues' | 'easyFixes' ) => {
3339 if ( loading [ type ] ) return '...'
3440 return getBadgeCount ( type )
3541 }
3642
37- // Debug logs
38- console . log ( 'Sidebar Debug:' , { currentTab, pathname, isDashboardPage } )
39-
40- // Fixed logic - works for all tabs
43+ // Active states for highlighting (separate from accordion state)
4144 const isQuickWinsTab = currentTab === 'good-first-issues' || currentTab === 'easy-fixes'
4245 const isActionRequiredTab = [ 'assigned' , 'mentions' , 'stale' ] . includes ( currentTab )
4346
44- console . log ( 'Tab States:' , { isQuickWinsTab, isActionRequiredTab } )
45-
4647 const handleLogout = ( ) => {
4748 logout ( )
4849 }
@@ -58,11 +59,12 @@ export function Sidebar() {
5859 ) }
5960
6061 < aside className = { `
61- fixed top-0 left-0 h-screen bg-sidebar border-r border-sidebar-border z-50 transform transition-transform duration-300 ease-in-out
62+ fixed top-0 left-0 bg-sidebar border-r border-sidebar-border z-50 transform transition-transform duration-300 ease-in-out
6263 ${ isOpen ? 'translate-x-0' : '-translate-x-full' }
63- lg:translate-x-0 lg:static lg:z-auto lg:h-screen
64+ lg:translate-x-0
6465 flex flex-col
6566 w-80 min-w-[20rem] max-w-[20rem]
67+ h-screen
6668 ` } >
6769
6870 { /* Header */ }
@@ -79,117 +81,109 @@ export function Sidebar() {
7981 </ button >
8082 </ div >
8183
82- { /* Scrollable Content */ }
8384 < div className = "flex-1 overflow-y-auto" >
84- { /* Navigation Menu with Collapsible */ }
85- < div className = "flex-1 overflow-y-auto p-4" >
85+ { /* Navigation Menu */ }
86+ < div className = "p-4" >
8687 < nav className = "space-y-2" >
87- { /* Action Required - Active with Collapsible */ }
88- < Collapsible open = { true } onOpenChange = { ( ) => { } } >
89- < CollapsibleTrigger asChild >
90- < Link href = "/dashboard" className = { `
91- flex items-center justify-between w-full px-3 py-2 rounded-lg transition-colors
92- ${ isActionRequiredTab
93- ? 'bg-sidebar-accent text-sidebar-accent-foreground'
94- : 'hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground'
95- }
88+ { /* Action Required Accordion */ }
89+ < Collapsible open = { actionRequiredOpen } onOpenChange = { setActionRequiredOpen } >
90+ < CollapsibleTrigger className = { `
91+ flex items-center justify-between w-full px-3 py-2 rounded-lg transition-colors cursor-pointer
92+ ${ isActionRequiredTab
93+ ? 'bg-sidebar-accent text-sidebar-accent-foreground'
94+ : 'hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground'
95+ }
9696 ` } >
97- < div className = "flex items-center gap-3" >
98- < Zap className = "w-5 h-5" />
99- < span > Action Required</ span >
100- { getTotalActionCount ( ) > 0 && (
101- < Badge variant = "destructive" className = "ml-1 text-xs min-w-[1.25rem] h-5" >
102- { getTotalActionCount ( ) }
103- </ Badge >
104- ) }
105- </ div >
106- < ChevronRight className = { `w-4 h-4 transition-transform ${ isActionRequiredTab ? 'rotate-90' : '' } ` } />
107- </ Link >
97+ < div className = "flex items-center gap-3" >
98+ < Zap className = "w-5 h-5" />
99+ < span > Action Required</ span >
100+ { getActionRequiredTotal ( ) > 0 && (
101+ < Badge variant = "destructive" className = "ml-1 text-xs min-w-[1.25rem] h-5" >
102+ { getActionRequiredTotal ( ) }
103+ </ Badge >
104+ ) }
105+ </ div >
106+ < ChevronRight className = { `w-4 h-4 transition-transform ${ actionRequiredOpen ? 'rotate-90' : '' } ` } />
108107 </ CollapsibleTrigger >
109108
110- { /* Action Required sub-items - Always show space */ }
109+ { /* Action Required sub-items */ }
111110 < CollapsibleContent className = "pl-8 space-y-1 mt-1" >
112- < div className = { `transition-opacity duration-200 ${ ! isDashboardPage ? 'opacity-50 pointer-events-none' : 'opacity-100' } ` } >
113- < Link
114- href = "/dashboard?tab=assigned"
115- className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
116- ${ currentTab === 'assigned'
117- ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
118- : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
119- } `}
111+ < Link
112+ href = "/dashboard?tab=assigned"
113+ className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
114+ ${ currentTab === 'assigned'
115+ ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
116+ : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
117+ } `}
118+ >
119+ < Target className = "w-4 h-4" />
120+ Assigned
121+ < Badge
122+ variant = { getBadgeCount ( 'assigned' ) > 0 ? "default" : "secondary" }
123+ className = "ml-auto text-xs"
120124 >
121-
122- < Target className = "w-4 h-4" />
123- Assigned
124- < Badge
125- variant = { getBadgeCount ( 'assigned' ) > 0 ? "default" : "secondary" }
126- className = "ml-auto text-xs"
127- >
128- { getBadgeContent ( 'assigned' ) }
129- </ Badge >
130- </ Link >
131- < Link
132- href = "/dashboard?tab=mentions"
133- className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
134- ${ currentTab === 'mentions'
135- ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
136- : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
137- } `}
125+ { getBadgeContent ( 'assigned' ) }
126+ </ Badge >
127+ </ Link >
128+ < Link
129+ href = "/dashboard?tab=mentions"
130+ className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
131+ ${ currentTab === 'mentions'
132+ ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
133+ : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
134+ } `}
135+ >
136+ < MessageSquare className = "w-4 h-4" />
137+ Mentions
138+ < Badge
139+ variant = { getBadgeCount ( 'mentions' ) > 0 ? "default" : "secondary" }
140+ className = "ml-auto text-xs"
138141 >
139- < MessageSquare className = "w-4 h-4" />
140- Mentions
141- < Badge
142- variant = { getBadgeCount ( 'mentions' ) > 0 ? "default" : "secondary" }
143- className = "ml-auto text-xs "
144- >
145- { getBadgeContent ( 'mentions' ) }
146- </ Badge >
147- </ Link >
148- < Link
149- href = "/dashboard?tab=stale"
150- className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
151- ${ currentTab === 'stale'
152- ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
153- : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
154- } ` }
142+ { getBadgeContent ( 'mentions' ) }
143+ </ Badge >
144+ </ Link >
145+ < Link
146+ href = "/dashboard?tab=stale "
147+ className = { `flex items-center gap-2 px-3 py-1.5 text-sm rounded transition-colors
148+ ${ currentTab === 'stale'
149+ ? 'bg-blue-50 text-blue-600 dark:bg-blue-900/20 dark:text-blue-400'
150+ : 'text-gray-600 hover:text-blue-600 hover:bg-gray-50 dark:hover:bg-gray-800'
151+ } ` }
152+ >
153+ < Clock className = "w-4 h-4" />
154+ Stale PRs
155+ < Badge
156+ variant = { getBadgeCount ( 'stale' ) > 0 ? "destructive" : "secondary" }
157+ className = "ml-auto text-xs"
155158 >
156- < Clock className = "w-4 h-4" />
157- Stale PRs
158- < Badge
159- variant = { getBadgeCount ( 'stale' ) > 0 ? "destructive" : "secondary" }
160- className = "ml-auto text-xs"
161- >
162- { getBadgeContent ( 'stale' ) }
163- </ Badge >
164- </ Link >
165- </ div >
159+ { getBadgeContent ( 'stale' ) }
160+ </ Badge >
161+ </ Link >
166162 </ CollapsibleContent >
167163 </ Collapsible >
168164
169- { /* Quick Wins - Always available */ }
170- < Collapsible open = { true } onOpenChange = { ( ) => { } } >
171- < CollapsibleTrigger asChild >
172- < Link href = "/dashboard?tab=good-first-issues" className = { `
173- flex items-center justify-between w-full px-3 py-2 rounded-lg transition-colors
174- ${ isQuickWinsTab
175- ? 'bg-sidebar-accent text-sidebar-accent-foreground'
176- : 'hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground'
177- }
165+ { /* Quick Wins Accordion */ }
166+ < Collapsible open = { quickWinsOpen } onOpenChange = { setQuickWinsOpen } >
167+ < CollapsibleTrigger className = { `
168+ flex items-center justify-between w-full px-3 py-2 rounded-lg transition-colors cursor-pointer
169+ ${ isQuickWinsTab
170+ ? 'bg-sidebar-accent text-sidebar-accent-foreground'
171+ : 'hover:bg-sidebar-accent/50 hover:text-sidebar-accent-foreground'
172+ }
178173 ` } >
179- < div className = "flex items-center gap-3" >
180- < Target className = "w-5 h-5" />
181- < span > Quick Wins</ span >
182- { ( getBadgeCount ( 'goodFirstIssues' ) + getBadgeCount ( 'easyFixes' ) ) > 0 && (
183- < Badge variant = "default" className = "ml-1 text-xs min-w-[1.25rem] h-5" >
184- { getBadgeCount ( 'goodFirstIssues' ) + getBadgeCount ( 'easyFixes' ) }
185- </ Badge >
186- ) }
187- </ div >
188- < ChevronRight className = { `w-4 h-4 transition-transform ${ isQuickWinsTab ? 'rotate-90' : '' } ` } />
189- </ Link >
174+ < div className = "flex items-center gap-3" >
175+ < Target className = "w-5 h-5" />
176+ < span > Quick Wins</ span >
177+ { getQuickWinsTotal ( ) > 0 && (
178+ < Badge variant = "default" className = "ml-1 text-xs min-w-[1.25rem] h-5" >
179+ { getQuickWinsTotal ( ) }
180+ </ Badge >
181+ ) }
182+ </ div >
183+ < ChevronRight className = { `w-4 h-4 transition-transform ${ quickWinsOpen ? 'rotate-90' : '' } ` } />
190184 </ CollapsibleTrigger >
191185
192- { /* Quick Wins sub-items - Always show space */ }
186+ { /* Quick Wins sub-items */ }
193187 < CollapsibleContent className = "pl-8 space-y-1 mt-1" >
194188 < Link
195189 href = "/dashboard?tab=good-first-issues"
@@ -264,9 +258,9 @@ export function Sidebar() {
264258 </ div >
265259 </ div >
266260
267- { /* Logout - Fixed at bottom */ }
261+ { /* Logout - Fixed at bottom with fixed height */ }
268262 { hasHydrated && isConnected && (
269- < div className = "p-4 border-t border-sidebar-border" >
263+ < div className = "p-4 border-t border-sidebar-border flex-shrink-0 " >
270264 < Button
271265 variant = "ghost"
272266 size = "sm"
@@ -289,9 +283,9 @@ export function SidebarToggle({ onClick }: { onClick: () => void }) {
289283 onClick = { onClick }
290284 className = "lg:hidden fixed top-4 left-4 z-50 bg-background p-2 rounded-lg shadow-lg border border-border hover:bg-accent transition-colors"
291285 >
292- < svg className = "w-6 h-6 text-foreground" fill = "none" stroke = "currentColor" viewBox = "0 24 24" >
286+ < svg className = "w-6 h-6 text-foreground" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
293287 < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M4 6h16M4 12h16M4 18h16" />
294288 </ svg >
295289 </ button >
296290 )
297- }
291+ }
0 commit comments