11import { Link } from 'react-router-dom'
22import { useAuth } from '../../contexts/AuthContext'
3- import { useState } from 'react'
4- import {
5- Menu ,
6- Search ,
7- Github ,
8- Sun ,
9- Moon ,
10- LogOut ,
11- Settings ,
12- BookOpen ,
13- ExternalLink
14- } from 'lucide-react'
3+ import { Menu , Search , Github , Sun , Moon , LogOut , Settings , BookOpen , ExternalLink } from 'lucide-react'
154import { useTheme } from 'next-themes'
165import { Button } from '@/components/ui/button'
6+ import {
7+ DropdownMenu ,
8+ DropdownMenuContent ,
9+ DropdownMenuItem ,
10+ DropdownMenuLabel ,
11+ DropdownMenuSeparator ,
12+ DropdownMenuTrigger ,
13+ } from '@/components/ui/dropdown-menu'
1714
1815interface TopNavProps {
1916 onToggleSidebar : ( ) => void
@@ -24,7 +21,6 @@ interface TopNavProps {
2421export function TopNav ( { onToggleSidebar, sidebarCollapsed, onOpenCommandPalette } : TopNavProps ) {
2522 const { session, signOut } = useAuth ( )
2623 const { theme, setTheme } = useTheme ( )
27- const [ showUserMenu , setShowUserMenu ] = useState ( false )
2824
2925 const userEmail = session ?. user ?. email || 'User'
3026 const userInitial = userEmail . charAt ( 0 ) . toUpperCase ( )
@@ -55,7 +51,7 @@ export function TopNav({ onToggleSidebar, sidebarCollapsed, onOpenCommandPalette
5551 </ div >
5652
5753 { /* Center - Command Palette Trigger */ }
58- < button
54+ < button
5955 className = "hidden sm:flex items-center gap-2 px-3 py-1.5 bg-muted border border-border rounded-lg text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-all max-w-xs"
6056 onClick = { onOpenCommandPalette }
6157 >
@@ -84,72 +80,49 @@ export function TopNav({ onToggleSidebar, sidebarCollapsed, onOpenCommandPalette
8480 className = "text-muted-foreground hover:text-foreground"
8581 aria-label = { theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode' }
8682 >
87- { theme === 'dark' ? (
88- < Sun className = "w-5 h-5" />
89- ) : (
90- < Moon className = "w-5 h-5" />
91- ) }
83+ { theme === 'dark' ? < Sun className = "w-5 h-5" /> : < Moon className = "w-5 h-5" /> }
9284 </ Button >
9385
94- { /* User Menu */ }
95- < div className = "relative" >
96- < button
97- onClick = { ( ) => setShowUserMenu ( ! showUserMenu ) }
98- className = "flex items-center gap-2 p-1 rounded-lg hover:bg-muted transition-colors"
99- >
100- < div className = "w-8 h-8 rounded-full bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center" >
101- < span className = "text-primary-foreground text-sm font-medium" > { userInitial } </ span >
102- </ div >
103- </ button >
104-
105- { showUserMenu && (
106- < >
107- < div
108- className = "fixed inset-0 z-40"
109- onClick = { ( ) => setShowUserMenu ( false ) }
110- />
111- < div className = "absolute right-0 top-full mt-2 w-56 bg-card border border-border rounded-xl shadow-lg z-50 py-2" >
112- < div className = "px-4 py-2 border-b border-border" >
113- < p className = "text-sm text-foreground font-medium truncate" > { userEmail } </ p >
114- < p className = "text-xs text-muted-foreground" > Free Plan</ p >
115- </ div >
116- < div className = "py-1" >
117- < Link
118- to = "/dashboard/settings"
119- className = "flex items-center gap-2 px-4 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
120- onClick = { ( ) => setShowUserMenu ( false ) }
121- >
122- < Settings className = "w-4 h-4" />
123- Settings
124- </ Link >
125- < a
126- href = "/docs"
127- target = "_blank"
128- rel = "noopener noreferrer"
129- className = "flex items-center gap-2 px-4 py-2 text-sm text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
130- onClick = { ( ) => setShowUserMenu ( false ) }
131- >
132- < BookOpen className = "w-4 h-4" />
133- Documentation
134- < ExternalLink className = "w-3 h-3 ml-auto opacity-50" />
135- </ a >
136- </ div >
137- < div className = "border-t border-border py-1" >
138- < button
139- onClick = { ( ) => {
140- signOut ( )
141- setShowUserMenu ( false )
142- } }
143- className = "flex items-center gap-2 w-full text-left px-4 py-2 text-sm text-destructive hover:bg-muted transition-colors"
144- >
145- < LogOut className = "w-4 h-4" />
146- Sign out
147- </ button >
148- </ div >
86+ { /* User Menu - using shadcn DropdownMenu for proper click-outside handling */ }
87+ < DropdownMenu >
88+ < DropdownMenuTrigger asChild >
89+ < button className = "flex items-center gap-2 p-1 rounded-lg hover:bg-muted transition-colors focus:outline-none" >
90+ < div className = "w-8 h-8 rounded-full bg-gradient-to-br from-primary to-purple-600 flex items-center justify-center" >
91+ < span className = "text-primary-foreground text-sm font-medium" > { userInitial } </ span >
92+ </ div >
93+ </ button >
94+ </ DropdownMenuTrigger >
95+ < DropdownMenuContent align = "end" className = "w-56" >
96+ < DropdownMenuLabel className = "font-normal" >
97+ < div className = "flex flex-col space-y-1" >
98+ < p className = "text-sm font-medium truncate" > { userEmail } </ p >
99+ < p className = "text-xs text-muted-foreground" > Free Plan</ p >
149100 </ div >
150- </ >
151- ) }
152- </ div >
101+ </ DropdownMenuLabel >
102+ < DropdownMenuSeparator />
103+ < DropdownMenuItem asChild >
104+ < Link to = "/dashboard/settings" className = "cursor-pointer" >
105+ < Settings className = "mr-2 h-4 w-4" />
106+ Settings
107+ </ Link >
108+ </ DropdownMenuItem >
109+ < DropdownMenuItem asChild >
110+ < a href = "/docs" target = "_blank" rel = "noopener noreferrer" className = "cursor-pointer" >
111+ < BookOpen className = "mr-2 h-4 w-4" />
112+ Documentation
113+ < ExternalLink className = "ml-auto h-3 w-3 opacity-50" />
114+ </ a >
115+ </ DropdownMenuItem >
116+ < DropdownMenuSeparator />
117+ < DropdownMenuItem
118+ onClick = { ( ) => signOut ( ) }
119+ className = "text-destructive focus:text-destructive cursor-pointer"
120+ >
121+ < LogOut className = "mr-2 h-4 w-4" />
122+ Sign out
123+ </ DropdownMenuItem >
124+ </ DropdownMenuContent >
125+ </ DropdownMenu >
153126 </ div >
154127 </ div >
155128 </ nav >
0 commit comments