Build the RTL Next.js experience with live catalog, journal, customer interactions, and SEO-ready canonical routes. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import { Menu, Phone, X } from "lucide-react";
|
|
import { usePathname } from "next/navigation";
|
|
import { useEffect, useState } from "react";
|
|
import { contact } from "@/data/site";
|
|
import { UserMenu } from "@/components/user-menu";
|
|
|
|
const nav = [
|
|
{ href: "/", label: "صفحه اصلی" },
|
|
{ href: "/products", label: "محصولات" },
|
|
{ href: "/blog", label: "مقالات" },
|
|
{ href: "/features", label: "ویژگیها" },
|
|
{ href: "/about", label: "درباره ما" },
|
|
{ href: "/contact", label: "تماس با ما" },
|
|
];
|
|
|
|
export function Header() {
|
|
const pathname = usePathname();
|
|
const [open, setOpen] = useState(false);
|
|
const [scrolled, setScrolled] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const onScroll = () => setScrolled(window.scrollY > 30);
|
|
onScroll();
|
|
window.addEventListener("scroll", onScroll, { passive: true });
|
|
return () => window.removeEventListener("scroll", onScroll);
|
|
}, []);
|
|
|
|
useEffect(() => setOpen(false), [pathname]);
|
|
|
|
return (
|
|
<header className={`site-header ${scrolled ? "is-scrolled" : ""}`}>
|
|
<div className="container nav-wrap">
|
|
<Link href="/" className="brand" aria-label="گلسموند - صفحه اصلی">
|
|
<Image src="/images/logo.png" alt="گلسموند" width={164} height={68} priority />
|
|
</Link>
|
|
|
|
<nav className="desktop-nav" aria-label="ناوبری اصلی">
|
|
{nav.map((item) => {
|
|
const active =
|
|
item.href === "/"
|
|
? pathname === "/"
|
|
: !item.href.includes("#") && pathname === item.href;
|
|
return (
|
|
<Link key={item.href} href={item.href} className={active ? "active" : ""}>
|
|
{item.label}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
|
|
<a className="nav-phone" href={contact.mobileHref} aria-label="تماس با گلسموند">
|
|
<Phone size={17} />
|
|
<span>{contact.mobile}</span>
|
|
</a>
|
|
|
|
<UserMenu />
|
|
|
|
<button
|
|
className="menu-button"
|
|
type="button"
|
|
onClick={() => setOpen((value) => !value)}
|
|
aria-expanded={open}
|
|
aria-label={open ? "بستن منو" : "باز کردن منو"}
|
|
>
|
|
{open ? <X /> : <Menu />}
|
|
</button>
|
|
</div>
|
|
|
|
<div className={`mobile-panel ${open ? "open" : ""}`}>
|
|
<nav className="container" aria-label="ناوبری موبایل">
|
|
{nav.map((item) => {
|
|
const active =
|
|
item.href === "/"
|
|
? pathname === "/"
|
|
: !item.href.includes("#") && pathname === item.href;
|
|
return (
|
|
<Link key={item.href} href={item.href} className={active ? "active" : ""}>
|
|
{item.label}
|
|
</Link>
|
|
);
|
|
})}
|
|
<a href={contact.mobileHref} className="mobile-call">
|
|
<Phone size={18} />
|
|
تماس با گلسموند
|
|
</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|