1
+ import React , { useState , useEffect } from 'react' ;
2
+ import Link from 'next/link' ;
3
+ import { useRouter } from 'next/router' ;
4
+ import WalletDropdown from './WalletDropdown' ;
5
+
6
+ const Navbar = ( ) => {
7
+ const router = useRouter ( ) ;
8
+ const [ isMenuOpen , setIsMenuOpen ] = useState ( false ) ;
9
+ const [ mounted , setMounted ] = useState ( false ) ;
10
+
11
+ // Prevent hydration mismatch
12
+ useEffect ( ( ) => {
13
+ setMounted ( true ) ;
14
+ } , [ ] ) ;
15
+
16
+ const isActive = ( path : string ) => router . pathname === path ;
17
+
18
+ const navItems = [
19
+ { name : 'Home' , path : '/' } ,
20
+ { name : 'Create' , path : '/create' } ,
21
+ { name : 'Mint' , path : '/mint' } ,
22
+ { name : 'Marketplace' , path : '/marketplace' } ,
23
+ { name : 'DAO' , path : '/dao' } ,
24
+ ] ;
25
+
26
+ const toggleMenu = ( ) => {
27
+ setIsMenuOpen ( ! isMenuOpen ) ;
28
+ // Prevent body scroll when menu is open
29
+ document . body . style . overflow = ! isMenuOpen ? 'hidden' : '' ;
30
+ } ;
31
+
32
+ return (
33
+ < nav className = "bg-gradient-to-r from-purple-600 to-indigo-700 shadow-md relative z-50" >
34
+ < div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8" >
35
+ < div className = "flex justify-between h-16" >
36
+ { /* Logo and desktop navigation */ }
37
+ < div className = "flex items-center justify-between w-full" >
38
+ < div className = "flex-shrink-0 flex items-center" >
39
+ < Link href = "/" className = "text-3xl font-extrabold text-white" >
40
+ < span className = "bg-clip-text text-transparent bg-gradient-to-r from-yellow-300 to-pink-300" > TL2V</ span >
41
+ </ Link >
42
+ </ div >
43
+
44
+ { /* Desktop navigation */ }
45
+ < div className = "hidden md:flex md:items-center md:space-x-8" >
46
+ { navItems . map ( ( item ) => (
47
+ < Link
48
+ key = { item . path }
49
+ href = { item . path }
50
+ className = { `inline-flex items-center px-3 py-2 rounded-md text-sm font-bold transition-colors duration-200 ease-in-out ${
51
+ isActive ( item . path )
52
+ ? 'bg-white/20 text-white'
53
+ : 'text-white/80 hover:bg-white/10 hover:text-white'
54
+ } `}
55
+ >
56
+ { item . name }
57
+ </ Link >
58
+ ) ) }
59
+ </ div >
60
+
61
+ { /* Wallet dropdown - desktop */ }
62
+ < div className = "hidden md:flex md:items-center" >
63
+ < WalletDropdown />
64
+ </ div >
65
+
66
+ { /* Mobile menu button */ }
67
+ < div className = "flex items-center md:hidden" >
68
+ < button
69
+ onClick = { toggleMenu }
70
+ className = "inline-flex items-center justify-center p-2 rounded-md text-white hover:bg-purple-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
71
+ aria-expanded = { isMenuOpen }
72
+ >
73
+ < span className = "sr-only" > Open main menu</ span >
74
+ { ! isMenuOpen ? (
75
+ < svg className = "block h-6 w-6" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
76
+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M4 6h16M4 12h16M4 18h16" />
77
+ </ svg >
78
+ ) : (
79
+ < svg className = "block h-6 w-6" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
80
+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M6 18L18 6M6 6l12 12" />
81
+ </ svg >
82
+ ) }
83
+ </ button >
84
+ </ div >
85
+ </ div >
86
+ </ div >
87
+ </ div >
88
+
89
+ { mounted && (
90
+ < >
91
+ { /* Mobile menu overlay */ }
92
+ < div
93
+ className = { `md:hidden fixed inset-0 z-40 bg-black bg-opacity-50 transition-opacity duration-300 ease-in-out ${
94
+ isMenuOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'
95
+ } `}
96
+ onClick = { toggleMenu }
97
+ />
98
+
99
+ { /* Mobile menu panel */ }
100
+ < div
101
+ className = { `md:hidden fixed inset-y-0 right-0 z-50 w-64 bg-gradient-to-b from-purple-700 to-indigo-800 shadow-xl transform transition-all duration-300 ease-in-out ${
102
+ isMenuOpen ? 'translate-x-0' : 'translate-x-full'
103
+ } `}
104
+ >
105
+ { /* Close button */ }
106
+ < div className = "absolute top-0 right-0 pt-4 pr-4" >
107
+ < button
108
+ onClick = { toggleMenu }
109
+ className = "inline-flex items-center justify-center p-2 rounded-md text-white hover:bg-purple-600 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
110
+ >
111
+ < span className = "sr-only" > Close menu</ span >
112
+ < svg className = "h-6 w-6" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
113
+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M6 18L18 6M6 6l12 12" />
114
+ </ svg >
115
+ </ button >
116
+ </ div >
117
+
118
+ { /* Mobile menu content */ }
119
+ < div className = "pt-14 pb-3 px-2 space-y-1 overflow-y-auto max-h-screen" >
120
+ { navItems . map ( ( item ) => (
121
+ < Link
122
+ key = { item . path }
123
+ href = { item . path }
124
+ className = { `block px-3 py-3 rounded-md text-base font-medium ${
125
+ isActive ( item . path )
126
+ ? 'bg-white/20 text-white'
127
+ : 'text-white/80 hover:bg-white/10 hover:text-white'
128
+ } `}
129
+ onClick = { toggleMenu }
130
+ >
131
+ { item . name }
132
+ </ Link >
133
+ ) ) }
134
+ < div className = "mt-4 px-3 py-2" >
135
+ < WalletDropdown minimal = { true } />
136
+ </ div >
137
+ </ div >
138
+ </ div >
139
+ </ >
140
+ ) }
141
+ </ nav >
142
+ ) ;
143
+ } ;
144
+
145
+ export default Navbar ;
0 commit comments