import { hydrateCart, subscribe, getSnapshot, formatPrice, } from "/js/cart.js"; function qs(sel, root = document) { return root.querySelector(sel); } function qsa(sel, root = document) { return [...root.querySelectorAll(sel)]; } function escapeHtml(s) { return String(s) .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """); } export function initHeader() { hydrateCart(); const header = qs(".site-header"); const mega = qs(".mega-panel"); const backdrop = qs(".mega-backdrop"); const drawer = qs(".mobile-drawer"); const badge = qs("[data-cart-count]"); const cartMenu = qs("[data-cart-menu]"); const cartTrigger = qs("[data-cart-trigger]"); const cartPreview = qs("[data-cart-preview]"); const cartList = qs("[data-cart-preview-list]"); const cartEmpty = qs("[data-cart-preview-empty]"); const cartFoot = qs("[data-cart-preview-foot]"); const cartTotal = qs("[data-cart-preview-total]"); const fineHover = typeof window.matchMedia === "function" && window.matchMedia("(hover: hover) and (pointer: fine)").matches; function syncBadge(snap) { if (!badge) return; badge.textContent = String(snap.itemCount); badge.classList.toggle("is-visible", snap.hydrated && snap.itemCount > 0); } function renderCartPreview(snap) { if (!cartList || !cartEmpty || !cartFoot || !cartTotal) return; const empty = !snap.items.length; cartEmpty.hidden = !empty; cartFoot.hidden = empty; cartList.hidden = empty; cartTotal.textContent = formatPrice(snap.subtotal); if (empty) { cartList.innerHTML = ""; return; } cartList.innerHTML = snap.items .slice(0, 8) .map((item) => { const href = `/products/${escapeHtml(item.slug)}/`; const img = item.image ? `` : ``; return ` ${img}

${escapeHtml(item.name)}

× ${item.quantity.toLocaleString("fa-IR")}

${formatPrice(item.price * item.quantity)}

`; }) .join(""); } function setCartPreviewOpen(open) { if (!cartMenu || !cartPreview || !cartTrigger) return; cartMenu.classList.toggle("is-open", open); cartPreview.classList.toggle("is-open", open); if (open) cartPreview.removeAttribute("hidden"); else cartPreview.setAttribute("hidden", ""); cartTrigger.setAttribute("aria-expanded", open ? "true" : "false"); } function closeCartPreview() { setCartPreviewOpen(false); } function openCartPreview() { setCartPreviewOpen(true); } const sideNav = qs(".side-nav"); const sideNavToggle = qs("[data-side-nav-toggle]"); const SIDE_NAV_KEY = "kikomiko-side-nav-collapsed"; function setSideNavCollapsed(collapsed) { if (!sideNav || !sideNavToggle) return; sideNav.classList.toggle("is-collapsed", collapsed); sideNavToggle.setAttribute("aria-expanded", collapsed ? "false" : "true"); const label = collapsed ? "نمایش منو" : "پنهان کردن منو"; sideNavToggle.setAttribute("aria-label", label); sideNavToggle.setAttribute("title", label); try { localStorage.setItem(SIDE_NAV_KEY, collapsed ? "1" : "0"); } catch { /* ignore */ } if (collapsed) closeMega(); } function hideDesktopMenu() { closeMega(); setSideNavCollapsed(true); } subscribe((snap) => { syncBadge(snap); renderCartPreview(snap); }); const initial = getSnapshot(); syncBadge(initial); renderCartPreview(initial); if (cartMenu && cartTrigger && cartPreview) { cartTrigger.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); const open = cartMenu.classList.contains("is-open"); if (open) closeCartPreview(); else { closeMega(); openCartPreview(); } }); if (fineHover) { let leaveTimer = 0; cartMenu.addEventListener("mouseenter", () => { window.clearTimeout(leaveTimer); openCartPreview(); }); cartMenu.addEventListener("mouseleave", () => { leaveTimer = window.setTimeout(closeCartPreview, 180); }); } document.addEventListener("click", (e) => { if (!(e.target instanceof Element)) return; if (!cartMenu.contains(e.target)) closeCartPreview(); }); document.addEventListener("keydown", (e) => { if (e.key === "Escape") closeCartPreview(); }); } function closeMega() { mega?.classList.remove("is-open"); mega?.removeAttribute("data-active"); backdrop?.classList.remove("is-open"); backdrop?.setAttribute("hidden", ""); header?.classList.remove("is-open"); qsa("[data-mega-key]").forEach((b) => b.classList.remove("is-active")); qsa("[data-mega-pane]").forEach((pane) => { pane.hidden = true; }); // Restore home highlight when on home const home = qs('.side-nav-link[href="/"]'); if (home && (location.pathname === "/" || location.pathname === "/fa")) { home.classList.add("is-active"); } } function openMega(key) { if (!mega) return; closeCartPreview(); // Keep the side panel open while browsing mega categories if (sideNav?.classList.contains("is-collapsed")) { setSideNavCollapsed(false); } mega.setAttribute("data-active", key); mega.classList.add("is-open"); header?.classList.add("is-open"); backdrop?.classList.add("is-open"); backdrop?.removeAttribute("hidden"); qsa("[data-mega-pane]").forEach((pane) => { pane.hidden = pane.getAttribute("data-mega-pane") !== key; }); qsa(".side-nav-link").forEach((b) => b.classList.remove("is-active")); qsa("[data-mega-key]").forEach((b) => b.classList.toggle("is-active", b.getAttribute("data-mega-key") === key) ); } qsa("[data-mega-key]").forEach((btn) => { btn.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); const key = btn.getAttribute("data-mega-key"); if (!key) return; const open = mega?.getAttribute("data-active") === key; if (open) { closeMega(); return; } openMega(key); }); }); // Close mega immediately when any link inside it is chosen // (categories, view-all, featured products, collection title). mega?.addEventListener( "click", (e) => { const link = e.target instanceof Element ? e.target.closest("a[href]") : null; if (!link || !mega.contains(link)) return; hideDesktopMenu(); }, true ); // Home / offers links in side nav should close mega + collapse panel qsa(".side-nav-link[href]").forEach((link) => { link.addEventListener("click", () => hideDesktopMenu()); }); // Highlight active offers item if (location.pathname.startsWith("/offers")) { qsa(".side-nav-link").forEach((el) => el.classList.remove("is-active")); qs( '.side-nav-link[href="/offers/"], .side-nav-link[href="/offers"]' )?.classList.add("is-active"); } // Do not use mouseleave — it fights with clicks on mega links. backdrop?.addEventListener("click", closeMega); qs("[data-mega-close]")?.addEventListener("click", closeMega); function closeDrawer(e) { e?.preventDefault?.(); e?.stopPropagation?.(); drawer?.classList.remove("is-open"); drawer?.setAttribute("aria-hidden", "true"); document.body.style.overflow = ""; qsa("[data-mobile-sub]").forEach((p) => p.classList.remove("is-open")); qsa(".mobile-cat").forEach((c) => c.classList.remove("is-expanded")); } function openDrawer(e) { e?.preventDefault?.(); drawer?.classList.add("is-open"); drawer?.setAttribute("aria-hidden", "false"); document.body.style.overflow = "hidden"; closeMega(); closeCartPreview(); } qs("[data-menu-open]")?.addEventListener("click", openDrawer); qsa("[data-menu-close]").forEach((el) => { el.addEventListener("click", closeDrawer); }); qsa("[data-mobile-expand]").forEach((btn) => { btn.addEventListener("click", () => { const id = btn.getAttribute("data-mobile-expand"); const panel = qs(`[data-mobile-sub="${id}"]`); const cat = btn.closest(".mobile-cat"); const open = panel?.classList.contains("is-open"); qsa("[data-mobile-sub]").forEach((p) => p.classList.remove("is-open")); qsa(".mobile-cat").forEach((c) => c.classList.remove("is-expanded")); if (!open) { panel?.classList.add("is-open"); cat?.classList.add("is-expanded"); } }); }); // Highlight current route in the mobile drawer const path = window.location.pathname.replace(/\/+$/, "") || "/"; qsa(".mobile-nav a[href]").forEach((a) => { const href = (a.getAttribute("href") || "").replace(/\/+$/, "") || "/"; if (href === path || (href !== "/" && path.startsWith(href))) { a.setAttribute("aria-current", "page"); a.classList.add("is-active"); } }); try { if (localStorage.getItem(SIDE_NAV_KEY) === "1") { setSideNavCollapsed(true); } } catch { /* ignore */ } sideNavToggle?.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); setSideNavCollapsed(!sideNav?.classList.contains("is-collapsed")); }); document.addEventListener("keydown", (e) => { if (e.key === "Escape") { closeMega(); closeDrawer(); closeCartPreview(); } }); }