127 lines
3.3 KiB
TypeScript
127 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import { ChevronDown, ChevronLeft } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { useEffect, useMemo, useState } from "react";
|
|
import {
|
|
categoryPath,
|
|
fetchProductCategories,
|
|
getLevelTwoProductCategories,
|
|
type ProductCategory,
|
|
} from "../lib/meshkee";
|
|
|
|
type ActivePage = "home" | "products" | "about" | "contact";
|
|
|
|
const navigationItems: {
|
|
label: string;
|
|
href: string;
|
|
key?: ActivePage;
|
|
}[] = [
|
|
{ label: "صفحه اصلی", href: "/", key: "home" },
|
|
{ label: "خدمات", href: "/#services" },
|
|
{ label: "اخبار", href: "/#news" },
|
|
{ label: "درباره ما", href: "/about-us", key: "about" },
|
|
{ label: "تماس با ما", href: "/contact-us", key: "contact" },
|
|
];
|
|
|
|
export default function HeaderNavigation({
|
|
active,
|
|
mobileOpen,
|
|
onNavigate,
|
|
}: {
|
|
active?: ActivePage;
|
|
mobileOpen: boolean;
|
|
onNavigate?: () => void;
|
|
}) {
|
|
const [categories, setCategories] = useState<ProductCategory[]>([]);
|
|
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
|
|
fetchProductCategories(controller.signal)
|
|
.then(setCategories)
|
|
.catch(() => {
|
|
// Keep the all-products link when categories cannot be loaded.
|
|
});
|
|
|
|
return () => controller.abort();
|
|
}, []);
|
|
|
|
const levelTwoCategories = useMemo(
|
|
() => getLevelTwoProductCategories(categories),
|
|
[categories],
|
|
);
|
|
|
|
const renderCategoryLinks = () => (
|
|
<>
|
|
<Link href="/products" onClick={onNavigate}>
|
|
همه ماشینآلات
|
|
<small>ALL PRODUCTS</small>
|
|
</Link>
|
|
{levelTwoCategories.map((category) => (
|
|
<Link
|
|
href={categoryPath(category)}
|
|
key={category.id}
|
|
onClick={onNavigate}
|
|
>
|
|
{category.nameFa || category.name}
|
|
<small dir="ltr">{category.name}</small>
|
|
</Link>
|
|
))}
|
|
</>
|
|
);
|
|
|
|
return (
|
|
<>
|
|
<nav className="desktop-nav" aria-label="ناوبری اصلی">
|
|
<Link className={active === "home" ? "active" : ""} href="/">
|
|
صفحه اصلی
|
|
</Link>
|
|
<div className="product-menu">
|
|
<Link
|
|
className={active === "products" ? "active" : ""}
|
|
href="/products"
|
|
>
|
|
محصولات
|
|
<ChevronDown size={14} />
|
|
</Link>
|
|
<div className="product-menu__dropdown">
|
|
<div>{renderCategoryLinks()}</div>
|
|
</div>
|
|
</div>
|
|
{navigationItems.slice(1).map((item) => (
|
|
<Link
|
|
className={item.key === active ? "active" : ""}
|
|
href={item.href}
|
|
key={item.label}
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
|
|
{mobileOpen && (
|
|
<nav className="mobile-nav" aria-label="ناوبری موبایل">
|
|
<Link href="/" onClick={onNavigate}>
|
|
صفحه اصلی
|
|
<ChevronLeft size={17} />
|
|
</Link>
|
|
<details className="mobile-product-menu">
|
|
<summary>
|
|
محصولات
|
|
<ChevronDown size={17} />
|
|
</summary>
|
|
<div>{renderCategoryLinks()}</div>
|
|
</details>
|
|
{navigationItems.slice(1).map((item) => (
|
|
<Link href={item.href} key={item.label} onClick={onNavigate}>
|
|
{item.label}
|
|
<ChevronLeft size={17} />
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
)}
|
|
</>
|
|
);
|
|
}
|