Files

54 lines
1.6 KiB
JavaScript

/** Shared client-side catalog search (catalog.dedupe2.json). */
let catalogPromise = null;
export function loadSearchCatalog() {
if (!catalogPromise) {
catalogPromise = fetch("/data/catalog.dedupe2.json")
.then((r) => {
if (!r.ok) throw new Error("catalog fetch failed");
return r.json();
})
.then((data) => data.products || []);
}
return catalogPromise;
}
export function displayName(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();
}
}
const fa = p.categoryFa || null;
if (fa && !title.includes(fa)) return `\u2067${fa} · \u2066${title}\u2069\u2069`;
return title;
}
export function searchCatalogProducts(products, query, limit) {
const needle = String(query || "").trim().toLowerCase();
if (!needle) return [];
const hits = products.filter((p) => {
const hay = `${p.name} ${p.category || ""} ${p.categoryFa || ""}`.toLowerCase();
return hay.includes(needle);
});
return limit != null ? hits.slice(0, limit) : hits;
}
export function formatSearchPrice(price) {
const amount = Number.isFinite(price) ? Math.round(price) : 0;
return `${new Intl.NumberFormat("fa-IR", { maximumFractionDigits: 0 }).format(amount)} تومان`;
}
export function escapeSearchHtml(s) {
return String(s)
.replaceAll("&", "&")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;");
}