| import React, { useState, useEffect } from 'react'; | |
| import { Link, useLocation } from 'react-router-dom'; | |
| import { FaLeaf, FaBars, FaTimes, FaSearch, FaChartBar, FaDatabase, FaMoon, FaSun } from 'react-icons/fa'; | |
| import { useTheme } from '../context/ThemeContext'; | |
| import api, { endpoints } from '../config/api'; | |
| const Navbar = () => { | |
| const [isOpen, setIsOpen] = useState(false); | |
| const [logos, setLogos] = useState([]); | |
| const location = useLocation(); | |
| const { darkMode, toggleDarkMode } = useTheme(); | |
| useEffect(() => { | |
| const fetchLogos = async () => { | |
| try { | |
| const response = await api.get(endpoints.mediaByType('Logo')); | |
| setLogos(response.data.data || []); | |
| } catch (error) { | |
| console.error('Error fetching logos:', error); | |
| } | |
| }; | |
| fetchLogos(); | |
| }, []); | |
| const isActive = (path) => location.pathname === path; | |
| const navItems = [ | |
| { path: '/', label: 'Dashboard', icon: FaChartBar }, | |
| { path: '/plants', label: 'Plants', icon: FaLeaf }, | |
| { path: '/surveys', label: 'Surveys', icon: FaDatabase }, | |
| { path: '/search', label: 'Search', icon: FaSearch }, | |
| { path: '/statistics', label: 'Statistics', icon: FaChartBar }, | |
| { path: '/about', label: 'About', icon: FaLeaf }, | |
| ]; | |
| return ( | |
| <nav className="sticky top-0 z-50 bg-gradient-to-r from-primary-600 via-primary-500 to-emerald-600 dark:from-slate-900 dark:via-slate-800 dark:to-slate-900 text-white shadow-xl transition-all duration-300 border-b border-transparent dark:border-slate-700"> | |
| <div className="container mx-auto px-4"> | |
| <div className="flex justify-between items-center py-3"> | |
| {/* Left Logo */} | |
| <Link to="/" className="flex items-center space-x-2 hover:scale-105 transition-transform"> | |
| {logos[0] ? ( | |
| <img | |
| src={`/images/logo_${logos[0].media_id}.png`} | |
| alt="Logo" | |
| className="h-10 w-auto object-contain" | |
| onError={(e) => { | |
| if (!e.target.src.includes('.jpg')) { | |
| e.target.src = `/images/logo_${logos[0].media_id}.jpg`; | |
| } else { | |
| e.target.style.display = 'none'; | |
| } | |
| }} | |
| /> | |
| ) : ( | |
| <div className="bg-white/20 p-1 rounded-lg"> | |
| <FaLeaf className="text-white text-2xl" /> | |
| </div> | |
| )} | |
| <span className="text-xl font-bold bg-gradient-to-r from-white to-green-100 dark:from-emerald-400 dark:to-emerald-300 bg-clip-text text-transparent"> | |
| SeerBharat | |
| </span> | |
| </Link> | |
| {/* Center Nav Links */} | |
| <div className="hidden md:flex items-center space-x-1"> | |
| {navItems.map((item) => ( | |
| <Link | |
| key={item.path} | |
| to={item.path} | |
| className={`flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-200 ${ | |
| isActive(item.path) | |
| ? 'bg-white dark:bg-slate-700 text-primary-700 dark:text-emerald-400 shadow-lg scale-105 font-semibold' | |
| : 'hover:bg-white/10 dark:hover:bg-slate-700/70 hover:scale-105 text-white dark:text-slate-200' | |
| }`} | |
| > | |
| <item.icon /> | |
| <span>{item.label}</span> | |
| </Link> | |
| ))} | |
| </div> | |
| {/* Right: Logo2 + Dark Mode */} | |
| <div className="flex items-center space-x-3"> | |
| {logos[1] && ( | |
| <img | |
| src={`/images/logo_${logos[1].media_id}.png`} | |
| alt="Logo 2" | |
| className="h-10 w-auto object-contain" | |
| onError={(e) => { | |
| if (!e.target.src.includes('.jpg')) { | |
| e.target.src = `/images/logo_${logos[1].media_id}.jpg`; | |
| } else { | |
| e.target.style.display = 'none'; | |
| } | |
| }} | |
| /> | |
| )} | |
| {/* Dark Mode Toggle - desktop */} | |
| <button | |
| onClick={toggleDarkMode} | |
| className="hidden md:block p-3 rounded-lg bg-white/20 backdrop-blur-md dark:bg-slate-700 text-white dark:text-yellow-400 hover:scale-110 hover:bg-white/30 dark:hover:bg-slate-600 transition-all duration-200 shadow-lg border border-white/20 dark:border-slate-600" | |
| title={darkMode ? 'Switch to Light Mode' : 'Switch to Dark Mode'} | |
| > | |
| {darkMode ? <FaSun className="text-xl animate-pulse" /> : <FaMoon className="text-xl" />} | |
| </button> | |
| {/* Mobile buttons */} | |
| <div className="flex items-center space-x-2 md:hidden"> | |
| <button | |
| onClick={toggleDarkMode} | |
| className="p-2 rounded-lg bg-white/20 dark:bg-slate-700 text-white dark:text-yellow-400" | |
| > | |
| {darkMode ? <FaSun /> : <FaMoon />} | |
| </button> | |
| <button | |
| onClick={() => setIsOpen(!isOpen)} | |
| className="text-2xl focus:outline-none text-white" | |
| > | |
| {isOpen ? <FaTimes /> : <FaBars />} | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Mobile Menu */} | |
| {isOpen && ( | |
| <div className="md:hidden pb-4 animate-slide-in"> | |
| {navItems.map((item) => ( | |
| <Link | |
| key={item.path} | |
| to={item.path} | |
| onClick={() => setIsOpen(false)} | |
| className={`flex items-center space-x-2 px-4 py-3 rounded-lg mb-2 transition-all duration-200 ${ | |
| isActive(item.path) | |
| ? 'bg-white dark:bg-slate-700 text-green-700 dark:text-emerald-400 font-semibold' | |
| : 'hover:bg-green-500 dark:hover:bg-slate-700/70 text-white dark:text-slate-200' | |
| }`} | |
| > | |
| <item.icon /> | |
| <span>{item.label}</span> | |
| </Link> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| </nav> | |
| ); | |
| }; | |
| export default Navbar; | |