Fix category-slot matching: identity by linkUrl slug, not array position
The homepage category carousel and installments highlights matched slot.images[i] to categoryList[i] by array index, assuming the business's CMS upload order lines up with this site's own category sort order. It doesn't - live data showed a laptop photo landing on "موبایل" and "لوازم برقی" appearing on the site despite no photo ever being uploaded for it, purely from index luck. titleFa isn't reliable either: the same laptop image was titled "تبلت" in the CMS, contradicting its own linkUrl. Fix: resolve each image's category from the `category` query param on its own linkUrl (categorySlugFromLinkUrl() in slug.ts, matched against ApiCategory.slug via the new findNodeBySlug()). The homepage carousel is now fully slot-driven - it iterates slot.images (in the CMS's own sortOrder) and simply omits any category with no matching image, per explicit product direction, rather than falling back to a placeholder. Installments keeps its curated HIGHLIGHT_IDS list with a placeholder for uncovered categories, since that page always shows the same fixed set, but now uses the same identity-based lookup instead of position. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
db7d00e473
commit
2249a07dee
@@ -35,6 +35,15 @@ export function findNode(nodes: CategoryNode[], id: string): CategoryNode | unde
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function findNodeBySlug(nodes: CategoryNode[], slug: string): CategoryNode | undefined {
|
||||
for (const node of nodes) {
|
||||
if (node.slug === slug) return node;
|
||||
const hit = findNodeBySlug(node.children, slug);
|
||||
if (hit) return hit;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Products are filed against leaf categories, so a parent like "لوازم جانبی"
|
||||
// matches almost nothing on its own — a carousel for it has to ask for the
|
||||
// whole subtree. Capped for the homepage's small carousels; a full category
|
||||
|
||||
@@ -22,3 +22,18 @@ export function categoryHref(id: string, nameFa?: string | null, name?: string |
|
||||
export function blogHref(id: string, title?: string | null): string {
|
||||
return `/blog/${id}/${faSlug(title)}`;
|
||||
}
|
||||
|
||||
// Static-image-slot items carry a business-picked linkUrl like
|
||||
// "https://moalem.shop/products?category=mobile" — the `category` query
|
||||
// param is the DB slug (ApiCategory.slug), the one reliable way to identify
|
||||
// which category an uploaded photo is actually for. Position in the list
|
||||
// and the item's own titleFa are NOT reliable — see AGENTS.md "Static-image
|
||||
// slots" for the real mismatch this was built to fix.
|
||||
export function categorySlugFromLinkUrl(linkUrl: string | null | undefined): string | null {
|
||||
if (!linkUrl) return null;
|
||||
try {
|
||||
return new URL(linkUrl).searchParams.get("category");
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user