"use client"; import Link from "next/link"; import { usePathname, useSearchParams } from "next/navigation"; import { ChevronDown, Heart, LayoutGrid, Menu, ShoppingCart, UserRound } from "lucide-react"; import { Suspense, useEffect, useMemo, useRef, useState } from "react"; import { AccountDialog } from "@/components/account/account-dialog"; import { PredictiveSearch } from "@/components/search/predictive-search"; import { Button } from "@/components/ui/button"; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from "@/components/ui/sheet"; import type { Category, Product } from "@/lib/headless/types"; import { useCartStore } from "@/store/cart-store"; import { useCustomerStore } from "@/store/customer-store"; import { useWishlistStore } from "@/store/wishlist-store"; type CategoryNode = Category & { children: Category[] }; function buildCategoryTree(categories: Category[]): CategoryNode[] { return categories .filter((category) => !category.parentId) .map((root) => ({ ...root, children: categories.filter((category) => category.parentId === root.id), })); } export function Navbar({ products, categories }: { products: Product[]; categories: Category[] }) { const [menuOpen, setMenuOpen] = useState(false); const [accountOpen, setAccountOpen] = useState(false); const items = useCartStore((state) => state.items); const cartHydrated = useCartStore((state) => state.hasHydrated); const openCart = useCartStore((state) => state.openCart); const wishlistProducts = useWishlistStore((state) => state.products); const wishlistHydrated = useWishlistStore((state) => state.hasHydrated); const openWishlist = useWishlistStore((state) => state.openWishlist); const count = cartHydrated ? items.reduce((sum, item) => sum + item.quantity, 0) : 0; const wishlistCount = wishlistHydrated ? wishlistProducts.length : 0; const customer = useCustomerStore((state) => state.customer); const customerHydrated = useCustomerStore((state) => state.hasHydrated); const isLoggedIn = customerHydrated && customer !== null; const tree = useMemo(() => buildCategoryTree(categories), [categories]); // Derivado de los productos reales (no de un endpoint de colecciones): // solo aparecen colecciones que de verdad tienen productos hoy. const collections = useMemo( () => [...new Set(products.map((product) => product.collection).filter(Boolean))], [products], ); return (
Paga tus compras a cuotas · Envíos nacionales · Compra segura con ARI
{/* Isotipo circular con icono + wordmark integrados (como en la version previa a ADR 0008), pedido explicito del usuario en vez del lockup rectangular. logo-ari.svg (rectangular) se mantiene para el footer. */} {/* eslint-disable-next-line @next/next/no-img-element -- vector propio, next/image no optimiza SVG sin habilitar dangerouslyAllowSVG */} ARI shopping
{/* Antes escondido en mobile (solo alcanzable desde el menu hamburguesa) -- pedido explicito del usuario: visible siempre en el header, con un punto verde cuando hay sesion iniciada (mismo patron que el badge de cantidad del carrito/favoritos, pero de presencia, no de conteo). */}
setMenuOpen(true)} />}> setMenuOpen(true)} /> Explora ARI Categorías y colecciones del catálogo.

Categorías

setMenuOpen(false)} />}> setMenuOpen(false)} />
{collections.length > 0 && ( <>

Colecciones

{collections.map((collection) => setMenuOpen(false)} className="rounded-full bg-slate-100 px-4 py-2 text-sm font-bold hover:bg-ari-coral/10 hover:text-ari-coral">{collection})}
)}
); } function useCategoryNavigationState() { const pathname = usePathname(); const searchParams = useSearchParams(); const currentCategory = searchParams.get("category") ?? ""; const isCatalog = pathname === "/catalog"; return { isAllActive: isCatalog && !currentCategory, isActive: (name: string) => isCatalog && currentCategory === name, }; } function pillClass(active: boolean): string { return `shrink-0 rounded-full px-4 py-2 text-sm font-extrabold transition ${ active ? "bg-white text-ari-marino shadow-lg shadow-black/10" : "text-white/90 hover:bg-white/10 hover:text-white" }`; } function mobileLinkClass(active: boolean): string { return `rounded-2xl border px-4 py-3 font-extrabold transition ${ active ? "border-ari-coral bg-ari-coral/5 text-ari-coral" : "border-slate-200 hover:border-ari-coral/50 hover:bg-ari-coral/5" }`; } function DesktopCategoryNavigation({ tree, onOpenMenu }: { tree: CategoryNode[]; onOpenMenu: () => void }) { const { isActive, isAllActive } = useCategoryNavigationState(); return ; } function DesktopCategoryNavigationFallback({ tree, onOpenMenu }: { tree: CategoryNode[]; onOpenMenu: () => void }) { return false} isAllActive={false} />; } function CategoryNavBar({ tree, onOpenMenu, isActive, isAllActive, }: { tree: CategoryNode[]; onOpenMenu: () => void; isActive: (name: string) => boolean; isAllActive: boolean; }) { return ( ); } function DepartmentsMegaMenu({ tree, isActive }: { tree: CategoryNode[]; isActive: (name: string) => boolean }) { const [open, setOpen] = useState(false); const containerRef = useRef(null); useEffect(() => { if (!open) return; function handlePointerDown(event: PointerEvent) { if (containerRef.current && !containerRef.current.contains(event.target as Node)) setOpen(false); } function handleKeyDown(event: KeyboardEvent) { if (event.key === "Escape") setOpen(false); } document.addEventListener("pointerdown", handlePointerDown); document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("pointerdown", handlePointerDown); document.removeEventListener("keydown", handleKeyDown); }; }, [open]); return (
setOpen(true)} onMouseLeave={() => setOpen(false)}> {open && (
{tree.map((root) => (
setOpen(false)} className={`block text-sm font-black uppercase tracking-wide transition ${ isActive(root.name) ? "text-ari-coral-claro" : "text-white hover:text-ari-coral-claro" }`} > {root.name} {root.children.length > 0 && (
    {root.children.map((child) => (
  • setOpen(false)} className={`block text-sm transition ${isActive(child.name) ? "font-bold text-ari-coral-claro" : "text-white/70 hover:text-white"}`} > {child.name}
  • ))}
)}
))}
)}
); } function MobileCategoryLinks({ tree, onNavigate }: { tree: CategoryNode[]; onNavigate: () => void }) { const { isActive, isAllActive } = useCategoryNavigationState(); return ( <> Todo el catálogo {tree.map((root) => (
{root.name} {root.children.map((child) => ( {child.name} ))}
))} ); } function MobileCategoryLinksFallback({ tree, onNavigate }: { tree: CategoryNode[]; onNavigate: () => void }) { return ( <> Todo el catálogo {tree.map((root) => (
{root.name} {root.children.map((child) => ( {child.name} ))}
))} ); }