"use client"; import { AnimatePresence, motion, useReducedMotion } from "framer-motion"; import { LayoutDashboard, Menu, X } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useLocale, useTranslations } from "next-intl"; import { useEffect, useState } from "react"; import { Container } from "@/components/layout/container"; import { LocaleToggle } from "@/components/layout/locale-toggle"; import { SiteLogo } from "@/components/layout/site-logo"; import { SoundToggle } from "@/components/sound-toggle"; import { ThemeToggle } from "@/components/theme-toggle"; import { Button } from "@/components/ui/button"; import { getLocalizedPath, stripLocalePrefix } from "@/lib/locale"; import { cn } from "@/lib/utils"; const navItems = [ { key: "home", path: "" }, { key: "portfolio", path: "/portfolio" }, { key: "products", path: "/products" }, { key: "about", path: "/about" }, { key: "contact", path: "/contact" }, ]; const brandTitleCharacters = [ ...Array.from("MOH").map((character) => ({ character, tone: "base" as const })), { character: " ", tone: "space" as const }, ...Array.from("FARAWATI").map((character) => ({ character, tone: "accent" as const })), ]; const brandShellVariants = { hidden: {}, visible: { transition: { staggerChildren: 0.035, delayChildren: 0.18, }, }, } as const; const brandCharacterVariants = { hidden: { opacity: 0, y: 18, rotateX: -80, filter: "blur(8px)", }, visible: { opacity: 1, y: 0, rotateX: 0, filter: "blur(0px)", transition: { type: "spring" as const, stiffness: 280, damping: 20, mass: 0.8, }, }, } as const; type SiteHeaderProps = { isAdmin?: boolean; lightLogoUrl?: string | null; darkLogoUrl?: string | null; }; function isNavItemActive(currentPath: string, itemPath: string) { if (itemPath === "/") { return currentPath === "/"; } return currentPath === itemPath || currentPath.startsWith(`${itemPath}/`); } function NavLinks({ onNavigate, mobile = false, }: { onNavigate?: () => void; mobile?: boolean; }) { const locale = useLocale(); const pathname = usePathname(); const t = useTranslations("navigation"); const currentPath = stripLocalePrefix(pathname); return ( <> {navItems.map((item) => ( (() => { const itemPath = item.path || "/"; const isActive = isNavItemActive(currentPath, itemPath); return ( {isActive ? ( ) : null} {t(item.key)} ); })() ))} > ); } export function SiteHeader({ isAdmin = false, lightLogoUrl, darkLogoUrl, }: SiteHeaderProps) { const [isOpen, setIsOpen] = useState(false); const [isScrolled, setIsScrolled] = useState(false); const pathname = usePathname(); const locale = useLocale(); const t = useTranslations("navigation"); const reducedMotion = useReducedMotion(); const isArabic = locale === "ar"; const brandSubtitle = isArabic ? "مــــــطـــــــــــــور ويــــــــــب | فــــــــــــريــــــلانــــــســــــر" : "Webdesigner Bremen | Freelancer"; const desktopControlRailClassName = "inline-flex items-center gap-1 rounded-pill border border-border/70 bg-background/80 p-1 shadow-panel backdrop-blur-chrome"; const desktopControlButtonClassName = "h-9 w-9 rounded-pill border border-transparent p-0 text-foreground/80 hover:bg-accent hover:text-foreground"; const mobileControlButtonClassName = "h-10 w-10 rounded-pill border border-border/70 bg-background text-foreground/80 shadow-xs hover:bg-accent hover:text-foreground"; useEffect(() => { const handleScroll = () => { setIsScrolled(window.scrollY > 24); }; handleScroll(); window.addEventListener("scroll", handleScroll, { passive: true }); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); return ( {isArabic ? ( مــــحـــمــد {" "} فــــرواتـــي ) : ( {brandTitleCharacters.map(({ character, tone }, index) => ( {character === " " ? "\u00A0" : character} ))} )} {brandSubtitle} {isAdmin ? ( ) : null} setIsOpen((open) => !open)} variant="ghost" size="icon" className="col-start-3 ml-auto h-11 w-11 justify-self-end rounded-pill border border-border/70 bg-background/80 text-foreground shadow-panel backdrop-blur-chrome hover:bg-accent lg:hidden" aria-label={isOpen ? t("closeMenu") : t("openMenu")} > {isOpen ? : } {isOpen ? ( {navItems.map((item) => { const itemPath = item.path || "/"; const isActive = isNavItemActive(stripLocalePrefix(pathname), itemPath); return ( setIsOpen(false)} > {t(item.key)} 0{navItems.findIndex((navItem) => navItem.key === item.key) + 1} ); })} {isAdmin ? ( setIsOpen(false)}> ) : null} ) : null} ); }