|
1 | | -import { Link } from "react-router-dom"; |
| 1 | +import { Link, useLocation } from "react-router-dom"; |
2 | 2 | import { useState, useContext } from "react"; |
3 | 3 | import { ThemeContext } from "../context/ThemeContext"; |
4 | | -import { Moon, Sun } from 'lucide-react'; |
5 | | - |
| 4 | +import { Moon, Sun } from "lucide-react"; |
6 | 5 |
|
7 | 6 | const Navbar: React.FC = () => { |
8 | | - |
9 | 7 | const [isOpen, setIsOpen] = useState<boolean>(false); |
10 | 8 | const themeContext = useContext(ThemeContext); |
| 9 | + const location = useLocation(); |
11 | 10 |
|
12 | | - if (!themeContext) |
13 | | - return null; |
| 11 | + if (!themeContext) return null; |
14 | 12 |
|
15 | 13 | const { toggleTheme, mode } = themeContext; |
16 | 14 |
|
| 15 | + const navLinks = [ |
| 16 | + { to: "/", label: "Home" }, |
| 17 | + { to: "/track", label: "Tracker" }, |
| 18 | + { to: "/contributors", label: "Contributors" }, |
| 19 | + { to: "/login", label: "Login" }, |
| 20 | + ]; |
| 21 | + |
17 | 22 | return ( |
18 | | - <nav className="sticky top-0 z-50 bg-white dark:bg-gray-900 text-black dark:text-white border-b border-gray-100 dark:border-gray-800 transition-colors duration-300"> |
| 23 | + <nav className="sticky top-0 z-50 bg-white/70 dark:bg-gray-900/70 backdrop-blur-lg text-black dark:text-white border-b border-gray-200 dark:border-gray-800 shadow-md transition-colors duration-300"> |
19 | 24 | <div className="container mx-auto px-6 py-4 flex justify-between items-center"> |
20 | 25 | {/* Logo Section */} |
21 | 26 | <Link |
22 | 27 | to="/" |
23 | | - className="text-2xl font-bold hover:text-gray-300 cursor-pointer flex items-center" |
| 28 | + className="text-2xl font-extrabold tracking-wide flex items-center group" |
24 | 29 | > |
25 | | - <img src="/crl-icon.png" alt="CRL Icon" className="h-8 mr-2" /> |
26 | | - GitHub Tracker |
| 30 | + <img src="/crl-icon.png" alt="CRL Icon" className="h-9 mr-2" /> |
| 31 | + <span className="relative"> |
| 32 | + GitHub Tracker |
| 33 | + <span className="absolute -bottom-1 left-0 w-0 h-[3px] bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 transition-all duration-500 group-hover:w-full rounded"></span> |
| 34 | + </span> |
27 | 35 | </Link> |
28 | 36 |
|
29 | 37 | {/* Desktop Links */} |
30 | 38 | <div className="hidden md:flex space-x-6"> |
31 | | - <Link |
32 | | - to="/" |
33 | | - className="text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
34 | | - > |
35 | | - Home |
36 | | - </Link> |
37 | | - <Link |
38 | | - to="/track" |
39 | | - className="text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
40 | | - > |
41 | | - Tracker |
42 | | - </Link> |
43 | | - <Link |
44 | | - to="/contributors" |
45 | | - className="text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
46 | | - > |
47 | | - Contributors |
48 | | - </Link> |
49 | | - <Link |
50 | | - to="/login" |
51 | | - className="text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
52 | | - > |
53 | | - Login |
54 | | - </Link> |
| 39 | + {navLinks.map((link) => ( |
| 40 | + <Link |
| 41 | + key={link.to} |
| 42 | + to={link.to} |
| 43 | + className={`relative text-lg font-medium px-3 py-2 rounded-lg transition-all duration-300 group |
| 44 | + ${ |
| 45 | + location.pathname === link.to |
| 46 | + ? "text-indigo-500 dark:text-indigo-400 font-semibold bg-indigo-50 dark:bg-indigo-900" |
| 47 | + : "hover:text-indigo-400 dark:hover:text-indigo-300 hover:bg-indigo-100 dark:hover:bg-gray-800" |
| 48 | + }`} |
| 49 | + > |
| 50 | + {link.label} |
| 51 | + {/* Gradient underline hover */} |
| 52 | + <span className="absolute bottom-0 left-0 w-0 h-[2px] bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 transition-all duration-500 group-hover:w-full"></span> |
| 53 | + </Link> |
| 54 | + ))} |
| 55 | + |
| 56 | + {/* Theme Toggle */} |
55 | 57 | <button |
56 | 58 | onClick={toggleTheme} |
57 | | - className="text-sm font-semibold px-3 py-1 rounded border border-gray-500 hover:text-gray-300 hover:border-gray-300 transition duration-200" |
| 59 | + className="ml-4 p-2 rounded-full border border-gray-400 dark:border-gray-600 hover:scale-110 hover:border-indigo-400 transition-all duration-500 transform hover:rotate-12" |
58 | 60 | > |
59 | | - {mode === "dark" ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />} |
| 61 | + {mode === "dark" ? ( |
| 62 | + <Sun className="h-5 w-5 text-yellow-400 drop-shadow-glow" /> |
| 63 | + ) : ( |
| 64 | + <Moon className="h-5 w-5 text-indigo-500 drop-shadow-glow" /> |
| 65 | + )} |
60 | 66 | </button> |
61 | 67 | </div> |
62 | 68 |
|
@@ -86,56 +92,38 @@ const Navbar: React.FC = () => { |
86 | 92 | </div> |
87 | 93 |
|
88 | 94 | {/* Mobile Links */} |
89 | | - {isOpen && ( |
90 | | - <div className="md:hidden bg-white dark:bg-gray-800 text-black dark:text-white"> |
91 | | - <div className="space-y-4 px-6 py-4"> |
92 | | - <Link |
93 | | - to="/" |
94 | | - className="block text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
95 | | - onClick={() => setIsOpen(false)} |
96 | | - > |
97 | | - Home |
98 | | - </Link> |
99 | | - <Link |
100 | | - to="/about" |
101 | | - className="block text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
102 | | - onClick={() => setIsOpen(false)} |
103 | | - > |
104 | | - About |
105 | | - </Link> |
106 | | - <Link |
107 | | - to="/contact" |
108 | | - className="block text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
109 | | - onClick={() => setIsOpen(false)} |
110 | | - > |
111 | | - Contact |
112 | | - </Link> |
113 | | - <Link |
114 | | - to="/contributors" |
115 | | - className="block text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
116 | | - onClick={() => setIsOpen(false)} |
117 | | - > |
118 | | - Contributors |
119 | | - </Link> |
| 95 | + <div |
| 96 | + className={`md:hidden overflow-hidden transition-all duration-500 ${ |
| 97 | + isOpen ? "max-h-96 opacity-100" : "max-h-0 opacity-0" |
| 98 | + }`} |
| 99 | + > |
| 100 | + <div className="bg-white/90 dark:bg-gray-800/90 backdrop-blur-md text-black dark:text-white border-t border-gray-200 dark:border-gray-700 px-6 py-4 space-y-4"> |
| 101 | + {navLinks.map((link) => ( |
120 | 102 | <Link |
121 | | - to="/login" |
122 | | - className="block text-lg font-medium hover:text-gray-300 transition-all px-2 py-1 border border-transparent hover:border-gray-400 rounded" |
| 103 | + key={link.to} |
| 104 | + to={link.to} |
123 | 105 | onClick={() => setIsOpen(false)} |
| 106 | + className={`block text-lg font-medium px-3 py-2 rounded-lg transition-all duration-300 |
| 107 | + ${ |
| 108 | + location.pathname === link.to |
| 109 | + ? "text-indigo-500 dark:text-indigo-400 font-semibold bg-indigo-50 dark:bg-indigo-900" |
| 110 | + : "hover:text-indigo-400 dark:hover:text-indigo-300 hover:bg-indigo-100 dark:hover:bg-gray-800" |
| 111 | + }`} |
124 | 112 | > |
125 | | - Login |
| 113 | + {link.label} |
126 | 114 | </Link> |
127 | | - <button |
128 | | - onClick={() => { |
129 | | - toggleTheme(); |
130 | | - setIsOpen(false); |
131 | | - }} |
132 | | - className="text-sm font-semibold px-3 py-1 rounded border border-gray-500 hover:text-gray-300 hover:border-gray-300 transition duration-200 w-full text-left" |
133 | | - > |
134 | | - {mode === "dark" ? "🌞 Light" : "🌙 Dark"} |
135 | | - </button> |
136 | | - </div> |
| 115 | + ))} |
| 116 | + <button |
| 117 | + onClick={() => { |
| 118 | + toggleTheme(); |
| 119 | + setIsOpen(false); |
| 120 | + }} |
| 121 | + className="w-full text-left text-sm font-semibold px-3 py-2 rounded-lg border border-gray-500 hover:border-indigo-400 hover:text-indigo-400 dark:hover:text-indigo-300 transition duration-300" |
| 122 | + > |
| 123 | + {mode === "dark" ? "🌞 Light Mode" : "🌙 Dark Mode"} |
| 124 | + </button> |
137 | 125 | </div> |
138 | | - )} |
| 126 | + </div> |
139 | 127 | </nav> |
140 | 128 | ); |
141 | 129 | }; |
|
0 commit comments