import { formatPrice, initShadePicker } from "/js/buy.js?v=pdpFx1"; import { renderProductContent } from "/js/product-content.js?v=content5"; import { ensureEurRate, sellCompareFromItem, sellPriceFromItem, } from "/js/fx.js?v=fx1"; function moneyItem(product, variant) { const v = variant || {}; return { price: v.price ?? product?.price, compareAtPrice: v.compareAtPrice ?? product?.compareAtPrice, priceEur: v.priceEur ?? product?.priceEur, sourcePrice: v.sourcePrice ?? product?.sourcePrice, sourceCurrency: v.sourceCurrency ?? product?.sourceCurrency, }; } function escapeHtml(s) { return String(s ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """); } function displayTitle(p) { const variants = p.colorVariants; let title = p.name; if (variants && variants.length >= 2) { const shade = variants.find((v) => v.slug === p.slug)?.shade; if (shade) { const trimmed = p.name.trim(); if (trimmed.endsWith(shade)) title = trimmed.slice(0, -shade.length).trim(); } } return title; } function uniqueImages(list) { const out = []; const seen = new Set(); for (const src of list || []) { if (typeof src !== "string" || !src || seen.has(src)) continue; seen.add(src); out.push(src); } return out; } function variantGalleryImages(v) { if (!v) return []; if (Array.isArray(v.images) && v.images.length) { return uniqueImages(v.images); } return v.heroImage ? [v.heroImage] : []; } /** Prefer shade gallery; fill from family images so PDP always looks like local multi-photo layout. */ function productGalleryImages(product, variant) { const variantImgs = variantGalleryImages(variant); const familyImgs = uniqueImages([ ...(product?.heroImage ? [product.heroImage] : []), ...((product?.images || []).filter((x) => typeof x === "string" && x)), ]); if (variantImgs.length >= 2) return variantImgs; return uniqueImages([...variantImgs, ...familyImgs]); } function inStock(p) { const variants = p.colorVariants; if (variants && variants.length > 1) { return variants.some((v) => Number(v.stock) > 0); } return Number(p.stock) > 0; } function activeVariant(p) { const variants = p.colorVariants || []; const wanted = new URLSearchParams(location.search).get('shade'); return variants.find(v=>wanted && v.shade===wanted) || variants.find((v) => v.slug === productSlugFromPath()) || variants.find(v=>v.id===p.defaultVariantId) || variants.find((v) => v.slug === p.slug) || variants[0] || null; } function shadePickerHtml(p) { const variants = p.colorVariants || []; if (variants.length < 2) return ""; const active = activeVariant(p); return `
رنگ: ${escapeHtml(active?.shade || "")}
انحصاری
${escapeHtml(p.tagline)}
` : ""}
${escapeHtml(stockMsg)}
${heroBlock} ${shadePickerHtml(p)}بارگذاری محصول ناموفق بود.
`; return; } const p = products.find((x) => x.slug === slug || x.colorVariants?.some(v=>v.slug===slug)); if (!p) { root.innerHTML = `محصول یافت نشد.
`; return; } const title = displayTitle(p); document.title = `${title} | کیکومیکو`; const metaDesc = document.querySelector('meta[name="description"]'); if (metaDesc) { metaDesc.setAttribute( "content", p.seoDescription || p.tagline || p.description || document.title ); } if (gallery) { gallery.innerHTML = galleryHtml(p); if (heroWrap) heroWrap.hidden = !gallery.innerHTML; } const shadesSlot = document.querySelector("[data-pdp-shades]"); if (shadesSlot) { shadesSlot.innerHTML = ""; shadesSlot.hidden = true; } root.innerHTML = buyPanelHtml(p); initShadePicker(); renderProductContent(desc, p, activeVariant(p) || {}); root.addEventListener("click", (event) => { const button = event.target.closest("[data-shade-select]"); if (!button) return; const variant = p.colorVariants?.find((v) => v.id === button.dataset.id); if (variant) queueMicrotask(() => renderProductContent(desc, p, variant)); }); }