128 lines
3.7 KiB
TypeScript
128 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useEffect, useState } from "react";
|
|
import { CATEGORIES, slugifyCategory } from "./categories";
|
|
import { useSession } from "next-auth/react";
|
|
|
|
const MERCH_ICONS = [
|
|
"/icons/merchicon1.png",
|
|
"/icons/merchicon2.png",
|
|
"/icons/merchicon3.png",
|
|
"/icons/merchicon4.png",
|
|
];
|
|
|
|
type HeaderProps = {
|
|
forceScrolled?: boolean;
|
|
};
|
|
|
|
export default function Header({ forceScrolled = false }: HeaderProps) {
|
|
const [interior, exterior, lighting, audio, tools, suspension, performance, drivetrain] = CATEGORIES;
|
|
const left = [interior, tools, exterior, drivetrain];
|
|
const right = [lighting, suspension, audio, performance];
|
|
const [merchIndex, setMerchIndex] = useState(0);
|
|
const [isScrolled, setIsScrolled] = useState(forceScrolled);
|
|
const { data: session, status } = useSession();
|
|
const authLabel =
|
|
status === "authenticated"
|
|
? session!.user.name || session!.user.email || "Account"
|
|
: "Sign In / Sign Up";
|
|
|
|
useEffect(() => {
|
|
const t = setInterval(
|
|
() => setMerchIndex((i) => (i + 1) % MERCH_ICONS.length),
|
|
3000
|
|
);
|
|
return () => clearInterval(t);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (forceScrolled) {
|
|
setIsScrolled(true);
|
|
return;
|
|
}
|
|
|
|
const onScroll = () => setIsScrolled(window.scrollY > 120);
|
|
onScroll();
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
return () => window.removeEventListener("scroll", onScroll);
|
|
}, [forceScrolled]);
|
|
|
|
useEffect(() => {
|
|
document.body.classList.toggle("so-header-scrolled", isScrolled);
|
|
return () => document.body.classList.remove("so-header-scrolled");
|
|
}, [isScrolled]);
|
|
|
|
return (
|
|
<header className={`so-header${isScrolled ? " so-header--scrolled" : ""}`}>
|
|
<div className="container">
|
|
<div className="so-header__top">
|
|
<div className="so-header__left">
|
|
<Link href="/" className="so-home" aria-label="Home">
|
|
<span className="so-home__icon" />
|
|
</Link>
|
|
|
|
<Link href="/merch" className="so-merch" aria-label="Merch">
|
|
{MERCH_ICONS.map((src, i) => (
|
|
<img
|
|
key={src}
|
|
src={src}
|
|
className={
|
|
"so-merch__icon" +
|
|
(i === merchIndex ? " so-merch__icon--active" : "")
|
|
}
|
|
alt=""
|
|
/>
|
|
))}
|
|
</Link>
|
|
</div>
|
|
|
|
<Link href="/" className="so-header__logo-wrap">
|
|
<img
|
|
src="/icons/logo.png"
|
|
className="so-header__logo"
|
|
alt="Shifted Offroad"
|
|
/>
|
|
</Link>
|
|
|
|
<div className="so-header__right">
|
|
<Link href="/rewards" className="so-rewards">
|
|
<span className="so-rewards__icon" />
|
|
</Link>
|
|
<Link href="/cart" className="so-cart">
|
|
<span className="so-cart__icon" />
|
|
</Link>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="so-header__categories">
|
|
<nav className="so-header__nav so-header__nav--left">
|
|
{left.map((c) => (
|
|
<Link
|
|
key={c}
|
|
href={`/category/${slugifyCategory(c)}`}
|
|
className="so-navitem"
|
|
>
|
|
{c}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
|
|
<nav className="so-header__nav so-header__nav--right">
|
|
{right.map((c) => (
|
|
<Link
|
|
key={c}
|
|
href={`/category/${slugifyCategory(c)}`}
|
|
className="so-navitem"
|
|
>
|
|
{c}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|