Files
nini-naderi/src/components/Header.tsx
T
Alireza HassaniandCursor c0a95a826a Connect the storefront to the Meshkee Website API.
Products, blog, search, mega menu, and home carousels now read live tenant data, and login goes to the customer portal.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-18 11:22:31 +03:30

228 lines
8.7 KiB
TypeScript

"use client";
import Link from "next/link";
import { useState } from "react";
import { SearchBox } from "@/components/SearchBox";
import { navLinks } from "@/data/content";
import type { MegaColumn } from "@/lib/catalog";
import { CUSTOMER_URL } from "@/lib/site";
import { IconBag, IconChevronDown, IconClose, IconHeart, IconMenu, IconUser } from "./Icons";
type Props = {
categories?: MegaColumn[];
};
export function Header({ categories = [] }: Props) {
const [open, setOpen] = useState(false);
const [mega, setMega] = useState(false);
const [mobileCats, setMobileCats] = useState(false);
const closeAll = () => {
setOpen(false);
setMega(false);
setMobileCats(false);
};
return (
<header className="sticky top-0 z-40 border-b border-white/50 bg-white/40 backdrop-blur-2xl">
<div className="container-nn">
<div className="flex h-[72px] items-center gap-3">
<button
type="button"
className="text-ink lg:hidden"
onClick={() => setOpen((value) => !value)}
aria-label={open ? "بستن منو" : "باز کردن منو"}
>
{open ? <IconClose /> : <IconMenu />}
</button>
<Link href="/" className="flex items-center gap-2.5">
<span className="grid size-11 place-items-center rounded-2xl bg-linear-to-br from-purple-600 via-cyan-500 to-rose-500 text-white shadow-card">
<span className="font-display text-lg leading-none">NN</span>
</span>
<span className="leading-tight">
<span className="font-display block text-[15px] text-purple-700">Nini Naderi</span>
<span className="block text-sm font-bold text-ink">نینی نادری</span>
</span>
</Link>
<SearchBox
className="mx-auto hidden min-w-0 flex-1 max-w-xl md:block"
inputClassName="h-11 w-full rounded-full border border-line bg-purple-50/60 pr-4 pl-11 text-sm outline-none transition focus:border-purple-500 focus:bg-white"
/>
<div className="ms-auto flex items-center gap-1 sm:gap-2">
<a
href={CUSTOMER_URL}
className="grid size-10 place-items-center rounded-full text-ink hover:bg-purple-50 lg:hidden"
aria-label="ورود"
>
<IconUser />
</a>
<a
href={CUSTOMER_URL}
className="hidden items-center gap-1.5 rounded-full px-3 py-2 text-sm text-ink hover:bg-purple-50 lg:inline-flex"
>
<IconUser />
ورود
</a>
<a
href={CUSTOMER_URL}
className="relative grid size-10 place-items-center rounded-full text-ink hover:bg-purple-50"
aria-label="علاقه‌مندی"
>
<IconHeart />
</a>
<a
href={CUSTOMER_URL}
className="relative grid size-10 place-items-center rounded-full text-ink hover:bg-purple-50"
aria-label="سبد خرید"
>
<IconBag />
</a>
</div>
</div>
<div className="pb-3 md:hidden">
<SearchBox
placeholder="جستجو در نینی نادری"
inputClassName="h-10 w-full rounded-full border border-line bg-purple-50/60 pr-4 pl-10 text-sm outline-none"
onNavigate={closeAll}
/>
</div>
<nav className="relative hidden h-12 items-center gap-6 text-sm font-medium text-ink lg:flex">
<div
className="h-full"
onMouseEnter={() => setMega(true)}
onMouseLeave={() => setMega(false)}
>
<button
type="button"
className="relative flex h-full items-center gap-1 py-3 transition hover:text-purple-700"
aria-expanded={mega}
onClick={() => setMega((value) => !value)}
>
دسته‌بندی‌ها
<IconChevronDown className={`size-4 transition ${mega ? "rotate-180" : ""}`} />
</button>
{mega ? <MegaMenu categories={categories} onPick={closeAll} /> : null}
</div>
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href}
className="relative py-3 transition hover:text-purple-700 after:absolute after:right-0 after:bottom-1 after:h-0.5 after:w-0 after:bg-linear-to-l after:from-purple-600 after:to-cyan-500 after:transition-all hover:after:w-full"
>
{link.label}
</Link>
))}
</nav>
</div>
{open ? (
<div className="border-t border-line bg-white lg:hidden">
<nav className="container-nn flex flex-col py-2 text-sm">
<button
type="button"
className="flex items-center justify-between border-b border-line/70 py-3 text-ink"
onClick={() => setMobileCats((value) => !value)}
>
دسته‌بندی‌ها
<IconChevronDown className={`size-4 transition ${mobileCats ? "rotate-180" : ""}`} />
</button>
{mobileCats ? (
<div className="space-y-3 border-b border-line/70 py-3">
{categories.map((column) => (
<div key={column.id}>
<Link href={column.href} onClick={closeAll} className="block text-sm font-bold text-purple-700">
{column.name}
</Link>
{column.children.length ? (
<div className="mt-2 grid grid-cols-2 gap-2">
{column.children.map((child) => (
<Link
key={child.id}
href={child.href}
onClick={closeAll}
className="rounded-2xl bg-purple-50/70 px-3 py-2 text-xs font-bold"
>
{child.name}
</Link>
))}
</div>
) : null}
</div>
))}
</div>
) : null}
{navLinks.map((link) => (
<Link
key={link.label}
href={link.href}
onClick={closeAll}
className="border-b border-line/70 py-3 text-ink"
>
{link.label}
</Link>
))}
<a href={CUSTOMER_URL} onClick={closeAll} className="py-3 text-ink">
ورود / ثبت نام
</a>
</nav>
</div>
) : null}
</header>
);
}
function MegaMenu({ categories, onPick }: { categories: MegaColumn[]; onPick: () => void }) {
return (
<div className="absolute top-full right-0 z-50 w-[min(52rem,calc(100vw-2rem))] pt-2">
<div className="rounded-3xl border border-white/80 bg-white/95 p-5 shadow-card backdrop-blur-[80px]">
<div className="mb-4 flex items-end justify-between">
<div>
<p className="font-display text-xs text-cyan-600">Categories</p>
<p className="text-base font-bold">خرید بر اساس دسته</p>
</div>
<Link href="/products" onClick={onPick} className="text-xs font-medium text-purple-700">
مشاهده همه
</Link>
</div>
{categories.length ? (
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
{categories.map((column) => (
<div key={column.id}>
<Link
href={column.href}
onClick={onPick}
className="block text-sm font-bold text-purple-700 hover:text-purple-800"
>
{column.name}
</Link>
{column.children.length ? (
<ul className="mt-2 space-y-1.5">
{column.children.map((child) => (
<li key={child.id}>
<Link
href={child.href}
onClick={onPick}
className="block rounded-xl px-2 py-1 text-sm text-muted transition hover:bg-purple-50 hover:text-ink"
>
{child.name}
</Link>
</li>
))}
</ul>
) : null}
</div>
))}
</div>
) : (
<p className="text-sm text-muted">دسته‌بندی‌ها به‌زودی اینجا می‌آیند.</p>
)}
</div>
</div>
);
}