22
33import { useState } from 'react' ;
44import { motion , AnimatePresence } from 'framer-motion' ;
5- import { Menu , X , BookOpen , Award , Code , ChevronDown , MousePointer , Eye , Workflow } from 'lucide-react' ;
5+ import { Menu , X , BookOpen , Award , Code , ChevronDown } from 'lucide-react' ;
66import { useLanguage } from '@/contexts/LanguageContext' ;
77import { useRouter } from 'next/navigation' ;
88import LanguageSwitcher from './LanguageSwitcher' ;
@@ -11,6 +11,7 @@ import Logo from './Logo';
1111const Header = ( ) => {
1212 const [ isMobileMenuOpen , setIsMobileMenuOpen ] = useState ( false ) ;
1313 const [ isProductSubmenuOpen , setIsProductSubmenuOpen ] = useState ( false ) ;
14+ const [ isGuidelinesSubmenuOpen , setIsGuidelinesSubmenuOpen ] = useState ( false ) ;
1415 const { t } = useLanguage ( ) ;
1516 const router = useRouter ( ) ;
1617
@@ -24,11 +25,17 @@ const Header = () => {
2425 hasSubmenu : true ,
2526 submenuItems : [
2627 { name : t ( 'product.sections.principles' ) , href : '/product#principles' } ,
27- { name : t ( 'product.sections.guidelines' ) , href : '/product#guidelines' } ,
28+ {
29+ name : t ( 'product.sections.guidelines' ) ,
30+ href : '/product#guidelines' ,
31+ hasSubmenu : true ,
32+ submenuItems : [
33+ { name : 'UX Patterns' , href : '/product/UX-patterns' } ,
34+ { name : 'Visual Patterns' , href : '/product/visual-patterns' } ,
35+ { name : 'Workflow & Rituals' , href : '/product/workflow-rituals' } ,
36+ ]
37+ } ,
2838 { name : t ( 'product.sections.resources' ) , href : '/product#resources' } ,
29- { name : 'UX Patterns' , href : '/product/UX-patterns' , icon : MousePointer } ,
30- { name : 'Visual Patterns' , href : '/product/visual-patterns' , icon : Eye } ,
31- { name : 'Workflow & Rituals' , href : '/product/workflow-rituals' , icon : Workflow } ,
3239 ]
3340 } ,
3441 ] ;
@@ -79,24 +86,78 @@ const Header = () => {
7986 animate = { { opacity : 1 , y : 0 } }
8087 exit = { { opacity : 0 , y : 10 } }
8188 transition = { { duration : 0.2 } }
82- className = "absolute top-full left-0 mt-2 w-64 bg-background/98 backdrop-blur-sm border border-border rounded-lg shadow-xl z-50 "
89+ className = "absolute top-full left-0 mt-2 w-64 bg-background/98 backdrop-blur-sm border border-border rounded-lg shadow-xl z-[60] "
8390 >
8491 < div className = "py-2" >
8592 { item . submenuItems ?. map ( ( subItem , subIndex ) => (
86- < motion . button
87- key = { subItem . name }
88- whileHover = { { x : 4 } }
89- onClick = { ( ) => {
90- router . push ( subItem . href ) ;
91- setIsProductSubmenuOpen ( false ) ;
92- } }
93- className = "w-full flex items-center space-x-3 px-4 py-3 text-left hover:bg-accent transition-colors"
94- >
95- { subItem . icon && < subItem . icon className = "w-4 h-4 text-muted-foreground" /> }
96- < span className = { `font-medium ${ subItem . icon ? 'text-muted-foreground' : 'text-foreground pl-7' } ` } >
97- { subItem . name }
98- </ span >
99- </ motion . button >
93+ < div key = { subItem . name } className = "relative" >
94+ { subItem . hasSubmenu ? (
95+ < div
96+ onMouseEnter = { ( ) => setIsGuidelinesSubmenuOpen ( true ) }
97+ onMouseLeave = { ( ) => setIsGuidelinesSubmenuOpen ( false ) }
98+ className = "relative"
99+ >
100+ < motion . button
101+ whileHover = { { x : 4 } }
102+ onClick = { ( ) => {
103+ router . push ( subItem . href ) ;
104+ setIsProductSubmenuOpen ( false ) ;
105+ } }
106+ className = "w-full flex items-center justify-between px-4 py-3 text-left hover:bg-accent transition-colors"
107+ >
108+ < span className = "font-medium text-foreground" >
109+ { subItem . name }
110+ </ span >
111+ < ChevronDown className = { `w-4 h-4 transition-transform duration-200 ${ isGuidelinesSubmenuOpen ? 'rotate-180' : '' } ` } />
112+ </ motion . button >
113+
114+ { /* Guidelines Submenu */ }
115+ < AnimatePresence >
116+ { isGuidelinesSubmenuOpen && (
117+ < motion . div
118+ initial = { { opacity : 0 , x : 10 } }
119+ animate = { { opacity : 1 , x : 0 } }
120+ exit = { { opacity : 0 , x : 10 } }
121+ transition = { { duration : 0.2 } }
122+ className = "absolute top-0 left-full ml-2 w-56 bg-background/98 backdrop-blur-sm border border-border rounded-lg shadow-xl z-[70]"
123+ >
124+ < div className = "py-2" >
125+ { subItem . submenuItems ?. map ( ( guidelineItem , guidelineIndex ) => (
126+ < motion . button
127+ key = { guidelineItem . name }
128+ whileHover = { { x : 4 } }
129+ onClick = { ( ) => {
130+ router . push ( guidelineItem . href ) ;
131+ setIsProductSubmenuOpen ( false ) ;
132+ setIsGuidelinesSubmenuOpen ( false ) ;
133+ } }
134+ className = "w-full flex items-center px-4 py-3 text-left hover:bg-accent transition-colors"
135+ >
136+ < span className = "font-medium text-muted-foreground pl-4" >
137+ { guidelineItem . name }
138+ </ span >
139+ </ motion . button >
140+ ) ) }
141+ </ div >
142+ </ motion . div >
143+ ) }
144+ </ AnimatePresence >
145+ </ div >
146+ ) : (
147+ < motion . button
148+ whileHover = { { x : 4 } }
149+ onClick = { ( ) => {
150+ router . push ( subItem . href ) ;
151+ setIsProductSubmenuOpen ( false ) ;
152+ } }
153+ className = "w-full flex items-center px-4 py-3 text-left hover:bg-accent transition-colors"
154+ >
155+ < span className = "font-medium text-foreground" >
156+ { subItem . name }
157+ </ span >
158+ </ motion . button >
159+ ) }
160+ </ div >
100161 ) ) }
101162 </ div >
102163 </ motion . div >
@@ -174,20 +235,67 @@ const Header = () => {
174235 >
175236 < div className = "ml-6 space-y-1" >
176237 { item . submenuItems ?. map ( ( subItem , subIndex ) => (
177- < motion . button
178- key = { subItem . name }
179- onClick = { ( ) => {
180- setIsMobileMenuOpen ( false ) ;
181- setIsProductSubmenuOpen ( false ) ;
182- router . push ( subItem . href ) ;
183- } }
184- className = "flex items-center space-x-3 px-4 py-2 rounded-lg hover:bg-accent transition-colors cursor-pointer w-full text-left"
185- >
186- { subItem . icon && < subItem . icon className = "w-4 h-4 text-muted-foreground" /> }
187- < span className = { `font-medium text-sm ${ subItem . icon ? 'text-muted-foreground' : 'text-foreground' } ` } >
188- { subItem . name }
189- </ span >
190- </ motion . button >
238+ < div key = { subItem . name } >
239+ { subItem . hasSubmenu ? (
240+ < div >
241+ < motion . button
242+ onClick = { ( ) => {
243+ setIsGuidelinesSubmenuOpen ( ! isGuidelinesSubmenuOpen ) ;
244+ } }
245+ className = "flex items-center justify-between w-full px-4 py-2 rounded-lg hover:bg-accent transition-colors cursor-pointer text-left"
246+ >
247+ < span className = "font-medium text-sm text-foreground" >
248+ { subItem . name }
249+ </ span >
250+ < ChevronDown className = { `w-4 h-4 transition-transform duration-200 ${ isGuidelinesSubmenuOpen ? 'rotate-180' : '' } ` } />
251+ </ motion . button >
252+
253+ < AnimatePresence >
254+ { isGuidelinesSubmenuOpen && (
255+ < motion . div
256+ initial = { { opacity : 0 , height : 0 } }
257+ animate = { { opacity : 1 , height : 'auto' } }
258+ exit = { { opacity : 0 , height : 0 } }
259+ transition = { { duration : 0.2 } }
260+ className = "overflow-hidden"
261+ >
262+ < div className = "ml-6 space-y-1" >
263+ { subItem . submenuItems ?. map ( ( guidelineItem , guidelineIndex ) => (
264+ < motion . button
265+ key = { guidelineItem . name }
266+ onClick = { ( ) => {
267+ setIsMobileMenuOpen ( false ) ;
268+ setIsProductSubmenuOpen ( false ) ;
269+ setIsGuidelinesSubmenuOpen ( false ) ;
270+ router . push ( guidelineItem . href ) ;
271+ } }
272+ className = "flex items-center px-4 py-2 rounded-lg hover:bg-accent transition-colors cursor-pointer w-full text-left"
273+ >
274+ < span className = "font-medium text-sm text-muted-foreground" >
275+ { guidelineItem . name }
276+ </ span >
277+ </ motion . button >
278+ ) ) }
279+ </ div >
280+ </ motion . div >
281+ ) }
282+ </ AnimatePresence >
283+ </ div >
284+ ) : (
285+ < motion . button
286+ onClick = { ( ) => {
287+ setIsMobileMenuOpen ( false ) ;
288+ setIsProductSubmenuOpen ( false ) ;
289+ router . push ( subItem . href ) ;
290+ } }
291+ className = "flex items-center px-4 py-2 rounded-lg hover:bg-accent transition-colors cursor-pointer w-full text-left"
292+ >
293+ < span className = "font-medium text-sm text-foreground" >
294+ { subItem . name }
295+ </ span >
296+ </ motion . button >
297+ ) }
298+ </ div >
191299 ) ) }
192300 </ div >
193301 </ motion . div >
0 commit comments