@@ -24,6 +24,7 @@ const baseLinks = [
24
24
const Header : React . FC < HeaderProps > = ( { fontLoaded, smallLogo } ) => {
25
25
const location = useLocation ( ) ;
26
26
const [ openMenuId , setOpenMenuId ] = React . useState < string | null > ( null ) ;
27
+ const [ isMobileMenuOpen , setIsMobileMenuOpen ] = React . useState ( false ) ;
27
28
28
29
React . useEffect ( ( ) => {
29
30
const handleClickOutside = ( event : MouseEvent ) => {
@@ -42,6 +43,11 @@ const Header: React.FC<HeaderProps> = ({ fontLoaded, smallLogo }) => {
42
43
setOpenMenuId ( openMenuId === menuId ? null : menuId ) ;
43
44
} ;
44
45
46
+ const toggleMobileMenu = ( ) => {
47
+ setIsMobileMenuOpen ( ! isMobileMenuOpen ) ;
48
+ setOpenMenuId ( null ) ;
49
+ }
50
+
45
51
const getFilteredChildren = ( children : Array < { name : string ; path : string } > ) => {
46
52
return children . filter ( child => child . path !== location . pathname ) ;
47
53
}
@@ -76,6 +82,38 @@ const Header: React.FC<HeaderProps> = ({ fontLoaded, smallLogo }) => {
76
82
py versify
77
83
</ span >
78
84
</ div >
85
+
86
+ { /* Hamburger Menu Button */ }
87
+ < button
88
+ className = "md:hidden p-2 rounded-lg hover:bg-[#3a719b] transition-colors"
89
+ onClick = { toggleMobileMenu }
90
+ aria-label = "Toggle menu"
91
+ >
92
+ < svg
93
+ className = "w-6 h-6"
94
+ fill = "none"
95
+ stroke = "currentColor"
96
+ viewBox = "0 0 24 24"
97
+ >
98
+ { isMobileMenuOpen ? (
99
+ < path
100
+ strokeLinecap = "round"
101
+ strokeLinejoin = "round"
102
+ strokeWidth = { 2 }
103
+ d = "M6 18L18 6M6 6l12 12"
104
+ />
105
+ ) : (
106
+ < path
107
+ strokeLinecap = "round"
108
+ strokeLinejoin = "round"
109
+ strokeWidth = { 2 }
110
+ d = "M4 6h16M4 12h16M4 18h16"
111
+ />
112
+ ) }
113
+ </ svg >
114
+ </ button >
115
+
116
+ { /* Regular Menu */ }
79
117
< div className = "hidden md:flex space-x-8" >
80
118
{ headerLinks . map ( ( link , index ) => (
81
119
link . children ? (
@@ -144,6 +182,76 @@ const Header: React.FC<HeaderProps> = ({ fontLoaded, smallLogo }) => {
144
182
)
145
183
) ) }
146
184
</ div >
185
+
186
+ { /* Mobile Menu */ }
187
+ < div
188
+ className = { `${
189
+ isMobileMenuOpen ? 'block' : 'hidden'
190
+ } absolute top-full left-0 right-0 bg-[#4584b6] md:hidden shadow-lg`}
191
+ >
192
+ < div className = "px-4 py-2" >
193
+ { location . pathname !== '/' && (
194
+ < Link
195
+ to = "/"
196
+ className = "block py-2 px-4 text-white hover:text-[#ffde57] transition-colors"
197
+ onClick = { ( ) => setIsMobileMenuOpen ( false ) }
198
+ >
199
+ Home
200
+ </ Link >
201
+ ) }
202
+ { baseLinks . map ( ( link , index ) => (
203
+ < div key = { index } >
204
+ { link . children ? (
205
+ < div className = "relative" >
206
+ < button
207
+ onClick = { ( e ) => handleMenuClick ( link . name , e ) }
208
+ className = "w-full flex items-center justify-between py-2 px-4 text-white hover:text-[#ffde57] transition-colors"
209
+ >
210
+ { link . name }
211
+ < svg
212
+ className = { `w-4 h-4 transform transition-transform ${
213
+ openMenuId === link . name ? 'rotate-180' : ''
214
+ } `}
215
+ fill = "none"
216
+ stroke = "currentColor"
217
+ viewBox = "0 0 24 24"
218
+ >
219
+ < path
220
+ strokeLinecap = "round"
221
+ strokeLinejoin = "round"
222
+ strokeWidth = { 2 }
223
+ d = "M19 9l-7 7-7-7"
224
+ />
225
+ </ svg >
226
+ </ button >
227
+ { openMenuId === link . name && (
228
+ < div className = "bg-[#3a719b] py-1" >
229
+ { link . children . map ( ( child , childIndex ) => (
230
+ < Link
231
+ key = { childIndex }
232
+ to = { child . path }
233
+ className = "block py-2 px-8 text-white hover:text-[#ffde57] transition-colors"
234
+ onClick = { ( ) => setIsMobileMenuOpen ( false ) }
235
+ >
236
+ { child . name }
237
+ </ Link >
238
+ ) ) }
239
+ </ div >
240
+ ) }
241
+ </ div >
242
+ ) : (
243
+ < a
244
+ href = { link . path }
245
+ className = "block py-2 px-4 text-white hover:text-[#ffde57] transition-colors"
246
+ onClick = { ( ) => setIsMobileMenuOpen ( false ) }
247
+ >
248
+ { link . name }
249
+ </ a >
250
+ ) }
251
+ </ div >
252
+ ) ) }
253
+ </ div >
254
+ </ div >
147
255
</ nav >
148
256
</ div >
149
257
</ header >
0 commit comments