173 lines
5.8 KiB
JavaScript
173 lines
5.8 KiB
JavaScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { useRouter } from "next/navigation";
|
|
import { useEffect, useState } from "react";
|
|
import { useAuth } from "@/context/AuthContext";
|
|
import { useCart } from "@/context/CartContext";
|
|
|
|
export default function DisplayNav() {
|
|
const { user, token, logout, loading } = useAuth();
|
|
const { itemCount, selectedStoreId, setStoreId } = useCart();
|
|
const router = useRouter();
|
|
const [stores, setStores] = useState([]);
|
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!token) return;
|
|
fetch("/api/v1/stores?size=100", {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
})
|
|
.then((r) => (r.ok ? r.json() : null))
|
|
.then((data) => { if (data) setStores(data.content ?? []); })
|
|
.catch(() => {});
|
|
}, [token]);
|
|
|
|
function handleLogout() {
|
|
logout();
|
|
router.push("/");
|
|
setMenuOpen(false);
|
|
}
|
|
|
|
function closeMenu() {
|
|
setMenuOpen(false);
|
|
}
|
|
|
|
return (
|
|
<nav className="navbar">
|
|
<Link href="/" onClick={closeMenu}>
|
|
<Image
|
|
className="mx-3"
|
|
src="/logo_simple.png"
|
|
alt="store_logo"
|
|
width={50}
|
|
height={50}
|
|
id="logo"
|
|
/>
|
|
</Link>
|
|
|
|
{/* Desktop: inline links + auth */}
|
|
<div className="nav-links">
|
|
<Link href="/" className="nav-link">Home</Link>
|
|
<Link href="/adopt" className="nav-link">Adopt</Link>
|
|
<Link href="/products" className="nav-link">Store</Link>
|
|
<Link href="/appointments" className="nav-link">Appointments</Link>
|
|
<Link href="/ai-chat" className="nav-link">Help</Link>
|
|
<Link href="/contact" className="nav-link">Contact</Link>
|
|
<Link href="/about" className="nav-link">About</Link>
|
|
</div>
|
|
|
|
<div className="nav-auth">
|
|
{stores.length > 0 && (
|
|
<select
|
|
className="nav-store-select"
|
|
value={selectedStoreId ?? ""}
|
|
onChange={(e) => setStoreId(e.target.value || null)}
|
|
>
|
|
<option value="">All Stores</option>
|
|
{stores.map((s) => (
|
|
<option key={s.storeId} value={s.storeId}>
|
|
{s.storeName}
|
|
</option>
|
|
))}
|
|
</select>
|
|
)}
|
|
|
|
{user && (
|
|
<Link href="/cart" className="nav-cart-btn" aria-label="Cart">
|
|
🛒
|
|
{itemCount > 0 && (
|
|
<span className="nav-cart-badge">{itemCount > 99 ? "99+" : itemCount}</span>
|
|
)}
|
|
</Link>
|
|
)}
|
|
|
|
{loading ? null : user ? (
|
|
<>
|
|
<Link href="/profile" className="nav-link nav-greeting">
|
|
Hello, {(user.fullName || user.username).split(" ")[0]}
|
|
</Link>
|
|
<button type="button" className="nav-logout-btn" onClick={handleLogout}>
|
|
Log Out
|
|
</button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Link href="/login" className="nav-link">Log In</Link>
|
|
<Link href="/register" className="nav-link nav-register-btn">Register</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
|
|
{/* Mobile: cart icon + hamburger always in topbar */}
|
|
<div className="nav-mobile-bar">
|
|
{user && (
|
|
<Link href="/cart" className="nav-cart-btn" aria-label="Cart" onClick={closeMenu}>
|
|
🛒
|
|
{itemCount > 0 && (
|
|
<span className="nav-cart-badge">{itemCount > 99 ? "99+" : itemCount}</span>
|
|
)}
|
|
</Link>
|
|
)}
|
|
<button
|
|
className={`nav-hamburger${menuOpen ? " nav-hamburger--open" : ""}`}
|
|
aria-label="Toggle navigation menu"
|
|
aria-expanded={menuOpen}
|
|
onClick={() => setMenuOpen((o) => !o)}
|
|
>
|
|
<span />
|
|
<span />
|
|
<span />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Mobile dropdown drawer */}
|
|
{menuOpen && (
|
|
<div className="nav-drawer">
|
|
<Link href="/" className="nav-drawer-link" onClick={closeMenu}>Home</Link>
|
|
<Link href="/adopt" className="nav-drawer-link" onClick={closeMenu}>Adopt</Link>
|
|
<Link href="/products" className="nav-drawer-link" onClick={closeMenu}>Store</Link>
|
|
<Link href="/appointments" className="nav-drawer-link" onClick={closeMenu}>Appointments</Link>
|
|
<Link href="/ai-chat" className="nav-drawer-link" onClick={closeMenu}>Help</Link>
|
|
<Link href="/contact" className="nav-drawer-link" onClick={closeMenu}>Contact</Link>
|
|
<Link href="/about" className="nav-drawer-link" onClick={closeMenu}>About</Link>
|
|
|
|
<div className="nav-drawer-divider" />
|
|
|
|
{stores.length > 0 && (
|
|
<select
|
|
className="nav-store-select nav-store-select--drawer"
|
|
value={selectedStoreId ?? ""}
|
|
onChange={(e) => { setStoreId(e.target.value || null); closeMenu(); }}
|
|
>
|
|
<option value="">All Stores</option>
|
|
{stores.map((s) => (
|
|
<option key={s.storeId} value={s.storeId}>
|
|
{s.storeName}
|
|
</option>
|
|
))}
|
|
</select>
|
|
)}
|
|
|
|
{loading ? null : user ? (
|
|
<>
|
|
<Link href="/profile" className="nav-drawer-link" onClick={closeMenu}>
|
|
My Profile ({user.fullName || user.username})
|
|
</Link>
|
|
<button type="button" className="nav-logout-btn nav-logout-btn--drawer" onClick={handleLogout}>
|
|
Log Out
|
|
</button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Link href="/login" className="nav-drawer-link" onClick={closeMenu}>Log In</Link>
|
|
<Link href="/register" className="nav-drawer-link nav-drawer-link--register" onClick={closeMenu}>Register</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
)}
|
|
</nav>
|
|
);
|
|
}
|