1- import { Nav , Navbar } from 'react-bootstrap'
2- import styled from 'styled-components'
1+ import styled , { keyframes } from 'styled-components'
32import Themes from '../constants/Themes'
43import AppRoutes from '../AppRoutes'
54import { Link , useLocation } from 'react-router-dom'
@@ -36,132 +35,118 @@ const Navigation = ({ currentTheme, setTheme }: NavigationProps) => {
3635 }
3736
3837 return (
39- < Container ref = { navRef } >
40- < Navbar
41- variant = { currentTheme === Themes . Light ? 'light' : 'dark' }
42- expand = "lg"
43- fixed = "top"
44- expanded = { expanded }
45- onToggle = { setExpanded }
38+ < NavBar ref = { navRef } >
39+ < Brand to = { routes . Home } >
40+ < BrandText > ShotClock Pro</ BrandText >
41+ </ Brand >
42+ < Hamburger
43+ onClick = { ( ) => setExpanded ( ! expanded ) }
44+ aria-label = "Toggle navigation"
45+ aria-expanded = { expanded }
46+ aria-controls = "nav-menu"
4647 >
47- < Navbar . Brand as = { Link } to = { routes . Home } >
48- < BrandText > ShotClock Pro</ BrandText >
49- </ Navbar . Brand >
50- < Navbar . Toggle aria-controls = "basic-navbar-nav" />
51- < Navbar . Collapse id = "basic-navbar-nav" >
52- < Nav className = "ml-auto" >
53- < NavLink
54- to = { routes . Home }
55- $active = { location . pathname === routes . Home }
56- onClick = { handleNavClick }
48+ < HamburgerLine />
49+ < HamburgerLine />
50+ < HamburgerLine />
51+ </ Hamburger >
52+ < NavCollapse id = "nav-menu" $expanded = { expanded } >
53+ < NavItems >
54+ < NavLink
55+ to = { routes . Home }
56+ $active = { location . pathname === routes . Home }
57+ onClick = { handleNavClick }
58+ >
59+ { locals . home }
60+ </ NavLink >
61+ < NavLink
62+ to = { routes . Instructions }
63+ $active = { location . pathname === routes . Instructions }
64+ onClick = { handleNavClick }
65+ >
66+ { locals . instructions }
67+ </ NavLink >
68+ < NavLink
69+ to = { routes . FIBAResources }
70+ $active = { location . pathname === routes . FIBAResources }
71+ onClick = { handleNavClick }
72+ >
73+ { locals . fibaResources }
74+ </ NavLink >
75+ < NavLink
76+ to = { routes . About }
77+ $active = { location . pathname === routes . About }
78+ onClick = { handleNavClick }
79+ >
80+ { locals . about }
81+ </ NavLink >
82+ < NavLink
83+ to = { routes . FAQ }
84+ $active = { location . pathname === routes . FAQ }
85+ onClick = { handleNavClick }
86+ >
87+ { locals . faq }
88+ </ NavLink >
89+ < ThemeToggle >
90+ < ThemeButton
91+ $active = { currentTheme === Themes . Light }
92+ onClick = { ( ) => setTheme ( Themes . Light ) }
5793 >
58- { locals . home }
59- </ NavLink >
60- < NavLink
61- to = { routes . Instructions }
62- $active = { location . pathname === routes . Instructions }
63- onClick = { handleNavClick }
94+ light
95+ </ ThemeButton >
96+ < ThemeDivider > | </ ThemeDivider >
97+ < ThemeButton
98+ $active = { currentTheme === Themes . Dark }
99+ onClick = { ( ) => setTheme ( Themes . Dark ) }
64100 >
65- { locals . instructions }
66- </ NavLink >
67- < NavLink
68- to = { routes . FIBAResources }
69- $active = { location . pathname === routes . FIBAResources }
70- onClick = { handleNavClick }
71- >
72- { locals . fibaResources }
73- </ NavLink >
74- < NavLink
75- to = { routes . About }
76- $active = { location . pathname === routes . About }
77- onClick = { handleNavClick }
78- >
79- { locals . about }
80- </ NavLink >
81- < NavLink
82- to = { routes . FAQ }
83- $active = { location . pathname === routes . FAQ }
84- onClick = { handleNavClick }
85- >
86- { locals . faq }
87- </ NavLink >
88- < ThemeToggle >
89- < ThemeButton
90- $active = { currentTheme === Themes . Light }
91- onClick = { ( ) => setTheme ( Themes . Light ) }
92- >
93- light
94- </ ThemeButton >
95- < ThemeDivider > |</ ThemeDivider >
96- < ThemeButton
97- $active = { currentTheme === Themes . Dark }
98- onClick = { ( ) => setTheme ( Themes . Dark ) }
99- >
100- dark
101- </ ThemeButton >
102- </ ThemeToggle >
103- </ Nav >
104- </ Navbar . Collapse >
105- </ Navbar >
106- </ Container >
101+ dark
102+ </ ThemeButton >
103+ </ ThemeToggle >
104+ </ NavItems >
105+ </ NavCollapse >
106+ </ NavBar >
107107 )
108108}
109109
110- const Container = styled . div `
111- nav {
112- background: rgba(0, 0, 0, 0.8) !important;
113- backdrop-filter: blur(10px);
114- -webkit-backdrop-filter: blur(10px);
115- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
116- padding: 0.5rem 1rem;
117- box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3);
118- font-family: 'Poppins', sans-serif;
119- z-index: 1000;
120- }
121-
122- .navbar-brand {
123- font-size: 1.8rem;
124- line-height: 1.5;
125- color: ${ ( props ) => props . theme . primary } !important;
126- transition: transform 0.2s ease-in-out;
127- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
128-
129- &:hover {
130- transform: scale(1.05);
131- }
110+ const slideDown = keyframes `
111+ from {
112+ opacity: 0;
113+ transform: translateY(-8px);
132114 }
133-
134- .navbar-toggler {
135- border: none;
136- padding: 0.5rem;
137- &:focus {
138- outline: none;
139- box-shadow: none;
140- }
115+ to {
116+ opacity: 1;
117+ transform: translateY(0);
141118 }
119+ `
142120
143- .navbar-toggler-icon {
144- background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 0.9)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
145- }
121+ const NavBar = styled . nav `
122+ position: fixed;
123+ top: 0;
124+ left: 0;
125+ right: 0;
126+ z-index: 1000;
127+ display: flex;
128+ align-items: center;
129+ flex-wrap: wrap;
130+ gap: 1rem;
131+ min-height: 70px;
132+ background: rgba(0, 0, 0, 0.8);
133+ backdrop-filter: blur(10px);
134+ -webkit-backdrop-filter: blur(10px);
135+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
136+ padding: 0.5rem 1rem;
137+ box-shadow: 0 4px 30px rgba(0, 0, 0, 0.3);
138+ font-family: 'Poppins', sans-serif;
139+ `
146140
147- @media (max-width: 768px) {
148- nav {
149- margin: 0;
150- border-radius: 0;
151- }
141+ const Brand = styled ( Link ) `
142+ font-size: 1.8rem;
143+ line-height: 1.5;
144+ text-decoration: none;
145+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
146+ transition: transform 0.2s ease-in-out;
152147
153- .navbar-collapse {
154- background: rgba(0, 0, 0, 0.9);
155- backdrop-filter: blur(10px);
156- -webkit-backdrop-filter: blur(10px);
157- border-radius: 0 0 1rem 1rem;
158- padding: 1rem;
159- position: absolute;
160- top: 100%;
161- left: 0;
162- right: 0;
163- z-index: 1000;
164- }
148+ &:hover {
149+ transform: scale(1.05);
165150 }
166151`
167152
@@ -171,11 +156,70 @@ const BrandText = styled.span`
171156 background: linear-gradient(45deg, #ffd700, #ff6b6b);
172157 -webkit-background-clip: text;
173158 -webkit-text-fill-color: transparent;
174- text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
159+ `
160+
161+ const Hamburger = styled . button `
162+ display: none;
163+ flex-direction: column;
164+ gap: 5px;
165+ background: none;
166+ border: none;
167+ padding: 0.5rem;
168+ cursor: pointer;
169+ margin-left: auto;
170+
171+ &:focus {
172+ outline: none;
173+ box-shadow: none;
174+ }
175+
176+ @media (max-width: 768px) {
177+ display: flex;
178+ }
179+ `
180+
181+ const HamburgerLine = styled . span `
182+ display: block;
183+ width: 22px;
184+ height: 2px;
185+ background: rgba(255, 255, 255, 0.9);
186+ border-radius: 2px;
187+ `
188+
189+ const NavCollapse = styled . div < { $expanded : boolean } > `
190+ display: flex;
191+ align-items: center;
192+
193+ @media (max-width: 768px) {
194+ display: ${ ( props ) => ( props . $expanded ? 'flex' : 'none' ) } ;
195+ flex-direction: column;
196+ width: 100%;
197+ margin-left: 0;
198+ background: rgba(0, 0, 0, 0.9);
199+ backdrop-filter: blur(10px);
200+ -webkit-backdrop-filter: blur(10px);
201+ border-radius: 0 0 1rem 1rem;
202+ padding: 1rem;
203+ position: absolute;
204+ top: 100%;
205+ left: 0;
206+ right: 0;
207+ animation: ${ slideDown } 0.35s ease-out;
208+ }
209+ `
210+
211+ const NavItems = styled . div `
212+ display: flex;
213+ align-items: center;
214+
215+ @media (max-width: 768px) {
216+ flex-direction: column;
217+ width: 100%;
218+ }
175219`
176220
177221const NavLink = styled ( Link ) < { $active : boolean } > `
178- color: #ffffff !important ;
222+ color: #ffffff;
179223 margin: 0 1rem;
180224 text-decoration: none;
181225 font-weight: 500;
@@ -197,7 +241,7 @@ const NavLink = styled(Link)<{ $active: boolean }>`
197241 }
198242
199243 &:hover {
200- color: #ffd700 !important ;
244+ color: #ffd700;
201245 &:after {
202246 width: 100%;
203247 }
@@ -207,8 +251,8 @@ const NavLink = styled(Link)<{ $active: boolean }>`
207251 margin: 0.5rem 0;
208252 padding: 0.5rem 1rem;
209253 border-radius: 8px;
210- background: ${ ( props ) =>
211- props . $active ? 'rgba(255, 255, 255, 0.1)' : 'transparent' } ;
254+ width: 100%;
255+ background: ${ ( props ) => ( props . $active ? 'rgba(255, 255, 255, 0.1)' : 'transparent' ) } ;
212256
213257 &:after {
214258 display: none;
@@ -231,6 +275,7 @@ const ThemeToggle = styled.div`
231275 @media (max-width: 768px) {
232276 margin: 0.5rem 0;
233277 justify-content: center;
278+ width: 100%;
234279 }
235280`
236281
0 commit comments