Files
salar-store/components/Header.tsx
T

181 lines
7.2 KiB
TypeScript

"use client";
import Image from "next/image";
import Link from "next/link";
import { useState } from "react";
import { customerLoginUrl } from "@/lib/customer";
import { parentCategories } from "@/lib/data";
import { SITE } from "@/lib/site";
import { useCart } from "@/lib/cart";
import { useSession } from "@/lib/session";
import { AccountMenu } from "./AccountMenu";
import { CartPopup } from "./CartPopup";
import { IconCart, IconChevron, IconClose, IconMenu, IconUser } from "./Icons";
import { SearchBox } from "./SearchBox";
const nav = [
{ name: "فروش ویژه", href: "#special-sale" },
{ name: "درباره ما", href: "/aboutus" },
{ name: "سوالات متداول", href: "/frequently-asked-questions" },
{ name: "تماس با ما", href: "/contactus" },
];
export function Header() {
const [open, setOpen] = useState(false);
const [mega, setMega] = useState(false);
const [cartOpen, setCartOpen] = useState(false);
const { itemCount } = useCart();
const { isAuthenticated, user, logout, isWebsiteAdmin } = useSession();
const displayName = user?.firstName?.trim() || "حساب من";
const loginHref = customerLoginUrl("/");
return (
<header className="sticky top-0 z-50 bg-white border-b border-black/5">
<div className="container-site flex h-[76px] items-center gap-4">
<button
type="button"
className="lg:hidden grid place-items-center w-10 h-10 text-ink"
aria-label="منو"
onClick={() => setOpen(true)}
>
<IconMenu />
</button>
<Link href="/" className="shrink-0">
<Image src="/images/logo/logo.png" alt={SITE.nameFa} width={150} height={40} className="h-10 w-auto" priority />
</Link>
<nav className="hidden lg:flex items-center gap-1 mr-4 text-sm">
<div
className="relative"
onMouseEnter={() => setMega(true)}
onMouseLeave={() => setMega(false)}
>
<Link
href="/products"
className="flex items-center gap-1 px-3 py-2 rounded-lg font-medium hover:text-brand"
>
محصولات
<IconChevron className="w-3.5 h-3.5 -rotate-90" />
</Link>
{mega && (
<div className="absolute top-full right-0 w-[760px] rounded-2xl bg-white border border-black/5 shadow-xl p-5 grid grid-cols-4 gap-5">
{parentCategories.map((cat) => (
<div key={cat.slug}>
<Link href={`/products/${cat.slug}`} className="block mb-3 text-sm font-bold text-brand">
{cat.name}
</Link>
<ul className="space-y-1.5">
{cat.children.slice(0, 8).map((child) => (
<li key={child.slug}>
<Link
href={`/products/${child.slug}`}
className="block text-[13px] text-zinc-600 hover:text-ink"
>
{child.name}
</Link>
</li>
))}
</ul>
</div>
))}
</div>
)}
</div>
{nav.map((item) => (
<Link key={item.href} href={item.href} className="px-3 py-2 rounded-lg hover:text-brand">
{item.name}
</Link>
))}
</nav>
<SearchBox className="hidden md:block ms-4 max-w-sm flex-1 rounded-full bg-zinc-100 px-3" />
<div className="flex items-center gap-2 ms-auto">
{isAuthenticated ? (
<div className="hidden sm:block">
<AccountMenu displayName={displayName} isWebsiteAdmin={isWebsiteAdmin} onLogout={logout} />
</div>
) : (
<a href={loginHref} className="flex items-center gap-2 rounded-full px-3 py-2 text-sm hover:bg-zinc-100">
<IconUser />
<span className="hidden sm:inline">ورود / ثبت نام</span>
</a>
)}
<button
type="button"
onClick={() => setCartOpen(true)}
aria-label={itemCount > 0 ? `سبد خرید، ${itemCount.toLocaleString("fa-IR")} کالا` : "سبد خرید"}
className="relative grid place-items-center w-10 h-10 rounded-full hover:bg-zinc-100"
>
<IconCart className="w-6 h-6 text-brand" />
{itemCount > 0 && (
<span className="absolute top-1 left-1 grid place-items-center min-w-4 h-4 rounded-full bg-brand px-0.5 text-[10px] text-white">
{itemCount.toLocaleString("fa-IR")}
</span>
)}
</button>
</div>
</div>
{open && (
<div className="fixed inset-0 z-50 lg:hidden">
<button className="absolute inset-0 bg-black/40" aria-label="بستن" onClick={() => setOpen(false)} />
<aside className="absolute inset-y-0 right-0 w-[86%] max-w-sm bg-white p-5 overflow-y-auto">
<div className="flex items-center justify-between mb-6">
<Image src="/images/logo/logo.png" alt={SITE.nameFa} width={130} height={36} className="h-9 w-auto" />
<button type="button" aria-label="بستن منو" onClick={() => setOpen(false)}>
<IconClose />
</button>
</div>
<SearchBox className="mb-5 rounded-full bg-zinc-100 px-3" onNavigate={() => setOpen(false)} />
<p className="text-xs text-zinc-400 mb-2">محصولات</p>
<div className="space-y-4 mb-6">
{parentCategories.map((cat) => (
<div key={cat.slug}>
<Link href={`/products/${cat.slug}`} className="font-bold text-brand" onClick={() => setOpen(false)}>
{cat.name}
</Link>
<ul className="mt-2 grid grid-cols-2 gap-1">
{cat.children.slice(0, 6).map((child) => (
<li key={child.slug}>
<Link href={`/products/${child.slug}`} className="text-sm text-zinc-600" onClick={() => setOpen(false)}>
{child.name}
</Link>
</li>
))}
</ul>
</div>
))}
</div>
<div className="flex flex-col gap-2 border-t border-black/5 pt-4">
{nav.map((item) => (
<Link key={item.href} href={item.href} className="py-2" onClick={() => setOpen(false)}>
{item.name}
</Link>
))}
{isAuthenticated ? (
<AccountMenu
displayName={displayName}
isWebsiteAdmin={isWebsiteAdmin}
compact
onLogout={() => {
logout();
setOpen(false);
}}
/>
) : (
<a href={loginHref} className="py-2">
ورود / ثبت نام
</a>
)}
</div>
</aside>
</div>
)}
<CartPopup open={cartOpen} onClose={() => setCartOpen(false)} />
</header>
);
}