Files
membership-fe/src/components/Navbar.js
2025-12-13 13:39:54 +07:00

370 lines
14 KiB
JavaScript

import React, { useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { Button } from './ui/button';
import { ChevronDown, Menu, X } from 'lucide-react';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from './ui/dropdown-menu';
const Navbar = () => {
const { user, logout } = useAuth();
const navigate = useNavigate();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
// LOAF logo (local)
const loafLogo = `${process.env.PUBLIC_URL}/loaf-logo.png`;
const handleLogout = () => {
logout();
navigate('/login');
};
return (
<>
{/* Top Header - Member Actions (Desktop Only) */}
<header className="hidden lg:flex bg-gradient-to-r from-[#644c9f] to-[#48286e] px-4 sm:px-8 md:px-16 py-4 justify-end items-center gap-4 sm:gap-6">
{user && (
<span className="text-white text-base font-medium" style={{ fontFamily: "'Poppins', sans-serif" }}>
Welcome, {user.first_name}
</span>
)}
{user?.role === 'admin' && (
<Link to="/admin">
<button
className="text-white text-base font-medium hover:opacity-80 transition-opacity bg-transparent border-none cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="admin-nav-button"
>
Admin Panel
</button>
</Link>
)}
<button
onClick={handleLogout}
className="text-white text-base font-medium hover:opacity-80 transition-opacity bg-transparent border-none cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="logout-button"
>
Logout
</button>
<Link to="/donate">
<Button
className="bg-[#ff9e77] hover:bg-[#ff8c64] text-[#48286e] rounded-[25px] px-[54px] py-[10px] text-[16.5px] font-semibold h-[41px]"
style={{ fontFamily: "'Montserrat', sans-serif" }}
>
Donate
</Button>
</Link>
</header>
{/* Main Header - Member Navigation */}
<header className="bg-[#664fa3] px-4 sm:px-8 md:px-16 py-2 flex justify-between items-center">
<Link to="/dashboard">
<img src={loafLogo} alt="LOAF Logo" className="h-16 w-16 sm:h-20 sm:w-20 md:h-28 md:w-28 object-contain" />
</Link>
{/* Desktop Navigation */}
<nav className="hidden lg:flex gap-6 sm:gap-8 md:gap-10 items-center">
<Link
to="/"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Home
</Link>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity flex items-center gap-1 bg-transparent border-none cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}>
About Us
<ChevronDown className="h-4 w-4" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="bg-white min-w-[220px]">
<DropdownMenuItem asChild>
<Link to="/about/history" className="w-full px-3 py-2 text-[#48286e] hover:bg-[#f1eef9] cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}>
History
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link to="/about/mission-values" className="w-full px-3 py-2 text-[#48286e] hover:bg-[#f1eef9] cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}>
Mission and Values
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link to="/about/board" className="w-full px-3 py-2 text-[#48286e] hover:bg-[#f1eef9] cursor-pointer"
style={{ fontFamily: "'Poppins', sans-serif" }}>
Board of Directors
</Link>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Link
to="/dashboard"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Dashboard
</Link>
<Link
to="/events"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="events-nav-button"
>
Events
</Link>
<Link
to="/members/calendar"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Calendar
</Link>
<Link
to="/members/directory"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Directory
</Link>
<Link
to="/members/gallery"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Gallery
</Link>
<Link
to="/members/newsletters"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Documents
</Link>
<Link
to="/profile"
className="text-white text-[17.5px] font-medium hover:opacity-80 transition-opacity"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="profile-nav-button"
>
Profile
</Link>
</nav>
{/* Mobile Hamburger Button */}
<button
onClick={() => setIsMobileMenuOpen(true)}
className="lg:hidden p-2 text-white hover:bg-white/10 rounded-lg transition-colors"
aria-label="Open menu"
>
<Menu className="h-6 w-6" />
</button>
</header>
{/* Mobile Menu Drawer */}
{isMobileMenuOpen && (
<div className="fixed inset-0 z-50 lg:hidden">
{/* Backdrop */}
<div
className="fixed inset-0 bg-black/50 backdrop-blur-sm"
onClick={() => setIsMobileMenuOpen(false)}
/>
{/* Drawer */}
<div className="fixed right-0 top-0 h-full w-[280px] bg-gradient-to-b from-[#664fa3] to-[#48286e] shadow-2xl flex flex-col">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-white/20">
<div className="flex items-center gap-3">
<img src={loafLogo} alt="LOAF" className="h-10 w-10 object-contain" />
<span className="text-white font-semibold text-lg" style={{ fontFamily: "'Poppins', sans-serif" }}>
LOAF
</span>
</div>
<button
onClick={() => setIsMobileMenuOpen(false)}
className="p-2 text-white hover:bg-white/10 rounded-lg transition-colors"
aria-label="Close menu"
>
<X className="h-6 w-6" />
</button>
</div>
{/* User Info */}
{user && (
<div className="px-6 py-4 border-b border-white/20">
<p className="text-white text-sm opacity-90" style={{ fontFamily: "'Poppins', sans-serif" }}>
Welcome,
</p>
<p className="text-white font-semibold text-base" style={{ fontFamily: "'Poppins', sans-serif" }}>
{user.first_name} {user.last_name}
</p>
</div>
)}
{/* Navigation Links */}
<nav className="flex-1 overflow-y-auto py-6 px-4">
<div className="space-y-2">
<Link
to="/"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Home
</Link>
{/* About Us Section */}
<div className="space-y-1">
<p className="px-4 py-2 text-white/70 text-sm font-semibold uppercase tracking-wider" style={{ fontFamily: "'Poppins', sans-serif" }}>
About Us
</p>
<Link
to="/about/history"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-6 py-2 text-white text-base hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
History
</Link>
<Link
to="/about/mission-values"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-6 py-2 text-white text-base hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Mission and Values
</Link>
<Link
to="/about/board"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-6 py-2 text-white text-base hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Board of Directors
</Link>
</div>
<Link
to="/dashboard"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Dashboard
</Link>
<Link
to="/events"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="mobile-events-nav-button"
>
Events
</Link>
<Link
to="/members/calendar"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Calendar
</Link>
<Link
to="/members/directory"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Directory
</Link>
<Link
to="/members/gallery"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Gallery
</Link>
<Link
to="/members/newsletters"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Documents
</Link>
<Link
to="/profile"
onClick={() => setIsMobileMenuOpen(false)}
className="block px-4 py-3 text-white text-base font-medium hover:bg-white/10 rounded-lg transition-colors"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="mobile-profile-nav-button"
>
Profile
</Link>
</div>
</nav>
{/* Footer Actions */}
<div className="p-4 border-t border-white/20 space-y-3">
{user?.role === 'admin' && (
<Link
to="/admin"
onClick={() => setIsMobileMenuOpen(false)}
>
<Button
className="w-full bg-white/20 hover:bg-white/30 text-white rounded-lg"
style={{ fontFamily: "'Poppins', sans-serif" }}
>
Admin Panel
</Button>
</Link>
)}
<Link
to="/donate"
onClick={() => setIsMobileMenuOpen(false)}
>
<Button
className="w-full bg-[#ff9e77] hover:bg-[#ff8c64] text-[#48286e] rounded-lg font-semibold"
style={{ fontFamily: "'Montserrat', sans-serif" }}
>
Donate
</Button>
</Link>
<Button
onClick={() => {
setIsMobileMenuOpen(false);
handleLogout();
}}
variant="outline"
className="w-full border-2 border-white/30 text-white hover:bg-white/10 rounded-lg"
style={{ fontFamily: "'Poppins', sans-serif" }}
data-testid="mobile-logout-button"
>
Logout
</Button>
</div>
</div>
</div>
)}
</>
);
};
export default Navbar;