297 lines
8.2 KiB
TypeScript
297 lines
8.2 KiB
TypeScript
import type { Category } from "@/data/home";
|
|
import {
|
|
ABOUT,
|
|
BLACK_ITEMS,
|
|
CATEGORIES,
|
|
MEGA_MENU_TABS,
|
|
} from "@/data/home";
|
|
import type { HeroSlideData } from "@/components/home/HeroSlider";
|
|
import { categoryPath } from "@/lib/category-path";
|
|
import type { PublicWebsiteSlotItem } from "@/lib/website-slots";
|
|
import { firstForSlot, itemsForSlot } from "@/lib/website-slots";
|
|
|
|
export type HomeSlotContent = {
|
|
heroSlides: HeroSlideData[];
|
|
categories: Category[];
|
|
leather: {
|
|
image: string;
|
|
nameFa: string;
|
|
nameEn: string;
|
|
subtext: string;
|
|
linkText: string;
|
|
link: string;
|
|
};
|
|
promoSale: {
|
|
image?: string;
|
|
nameFa?: string;
|
|
nameEn?: string;
|
|
subtext?: string;
|
|
link?: string;
|
|
} | null;
|
|
promoDiscount: {
|
|
image?: string;
|
|
nameFa?: string;
|
|
nameEn?: string;
|
|
subtext?: string;
|
|
link?: string;
|
|
} | null;
|
|
promoAutumn: {
|
|
image?: string;
|
|
nameFa?: string;
|
|
nameEn?: string;
|
|
subtext?: string;
|
|
link?: string;
|
|
} | null;
|
|
blackItems: Array<{
|
|
id: string;
|
|
image: string;
|
|
alt: string;
|
|
nameFa: string;
|
|
nameEn: string;
|
|
href: string;
|
|
}>;
|
|
about: {
|
|
titleFa: string;
|
|
titleEn: string;
|
|
lead: string;
|
|
body: string;
|
|
image: string;
|
|
imageSecondary: string;
|
|
};
|
|
paymentBadges: string;
|
|
megaTabs: Array<{
|
|
id: string;
|
|
nameFa: string;
|
|
nameEn: string;
|
|
href: string;
|
|
image: string;
|
|
links: readonly { label: string; href: string }[];
|
|
columns?: readonly {
|
|
title: string;
|
|
href: string;
|
|
links: readonly { label: string; href: string }[];
|
|
}[];
|
|
}>;
|
|
};
|
|
|
|
function slotItems(
|
|
items: PublicWebsiteSlotItem[],
|
|
slug: string,
|
|
...legacy: string[]
|
|
) {
|
|
const modern = itemsForSlot(items, slug);
|
|
if (modern.length) return modern;
|
|
for (const key of legacy) {
|
|
const found = itemsForSlot(items, key);
|
|
if (found.length) return found;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
function firstSlot(
|
|
items: PublicWebsiteSlotItem[],
|
|
slug: string,
|
|
...legacy: string[]
|
|
) {
|
|
return slotItems(items, slug, ...legacy)[0] ?? null;
|
|
}
|
|
|
|
export function mapHomeSlots(
|
|
items: PublicWebsiteSlotItem[],
|
|
): HomeSlotContent {
|
|
const heroItems = slotItems(items, "hero-slider", "home.hero");
|
|
const heroSlides: HeroSlideData[] =
|
|
heroItems.length > 0
|
|
? heroItems.map((item) => ({
|
|
id: item.id,
|
|
image: item.imageUrl || "/images/home/banners/hero.jpg",
|
|
imagePosition: "object-[center_top]",
|
|
title: item.nameFa || item.nameEn || "مانا کالکشن",
|
|
subtitle: item.nameEn || item.subtext || "",
|
|
cta: {
|
|
label: item.linkText || "مشاهده",
|
|
href: item.link || "/products",
|
|
},
|
|
}))
|
|
: [];
|
|
|
|
const categoryItems = slotItems(items, "category-strip");
|
|
const categories: Category[] =
|
|
categoryItems.length > 0
|
|
? categoryItems.map((item, index) => {
|
|
const fallback = CATEGORIES[index % CATEGORIES.length];
|
|
return {
|
|
id: item.id || `cat-${index}`,
|
|
nameFa: item.nameFa || `دسته ${index + 1}`,
|
|
nameEn: item.nameEn || "",
|
|
image: item.imageUrl || fallback.image,
|
|
href:
|
|
item.link ||
|
|
(fallback
|
|
? categoryPath(fallback)
|
|
: categoryPath({ id: "coat", nameEn: "Coat", nameFa: "کت" })),
|
|
};
|
|
})
|
|
: CATEGORIES.map((cat) => {
|
|
const legacy = firstForSlot(items, `home.category.${cat.id}`);
|
|
if (!legacy) return cat;
|
|
return {
|
|
...cat,
|
|
nameFa: legacy.nameFa || cat.nameFa,
|
|
nameEn: legacy.nameEn || cat.nameEn,
|
|
image: legacy.imageUrl || cat.image,
|
|
href: legacy.link || cat.href || categoryPath(cat),
|
|
};
|
|
});
|
|
|
|
const leatherSlot = firstSlot(
|
|
items,
|
|
"leather-banner",
|
|
"home.banner.leather",
|
|
);
|
|
const leather = {
|
|
image: leatherSlot?.imageUrl || "/images/home/banners/leather.png",
|
|
nameFa: leatherSlot?.nameFa || "هنر پوشیدن",
|
|
nameEn: leatherSlot?.nameEn || "THE ART OF DRESSING",
|
|
subtext: leatherSlot?.subtext || "",
|
|
linkText: leatherSlot?.linkText || "کالکشن چرم",
|
|
link: leatherSlot?.link || "/products?collection=leather",
|
|
};
|
|
|
|
const saleSlot = firstSlot(
|
|
items,
|
|
"promo-1",
|
|
"promo-sale",
|
|
"home.promo.sale",
|
|
);
|
|
const promoSale = saleSlot
|
|
? {
|
|
image: saleSlot.imageUrl || undefined,
|
|
nameEn: saleSlot.nameEn || "",
|
|
nameFa: saleSlot.nameFa || "",
|
|
subtext: saleSlot.subtext || "",
|
|
link: saleSlot.link || "/products?sale=1",
|
|
}
|
|
: null;
|
|
|
|
const discountSlot = firstSlot(items, "promo-2", "promo-discount");
|
|
const promoDiscount = discountSlot
|
|
? {
|
|
image: discountSlot.imageUrl || undefined,
|
|
nameFa: discountSlot.nameFa || discountSlot.linkText || "",
|
|
nameEn: discountSlot.nameEn || "",
|
|
subtext: discountSlot.subtext || "",
|
|
link: discountSlot.link || "/products?sale=1",
|
|
}
|
|
: null;
|
|
|
|
const autumnSlot = firstSlot(
|
|
items,
|
|
"promo-3",
|
|
"promo-autumn",
|
|
"home.promo.autumn",
|
|
);
|
|
const promoAutumn = autumnSlot
|
|
? {
|
|
image: autumnSlot.imageUrl || undefined,
|
|
nameEn: autumnSlot.nameEn || "",
|
|
nameFa: autumnSlot.nameFa || autumnSlot.linkText || "",
|
|
subtext: autumnSlot.subtext || "",
|
|
link: autumnSlot.link || "/products?collection=autumn",
|
|
}
|
|
: null;
|
|
|
|
const portraitItems = slotItems(items, "four-portrait-banner");
|
|
const blackItems =
|
|
portraitItems.length > 0
|
|
? Array.from({ length: 4 }).map((_, index) => {
|
|
const slot =
|
|
portraitItems.find((row) => row.sortOrder === index) ??
|
|
portraitItems[index];
|
|
const fallback = BLACK_ITEMS[index] ?? BLACK_ITEMS[0];
|
|
return {
|
|
id: slot?.id || fallback.id,
|
|
image: slot?.imageUrl || fallback.image,
|
|
alt: slot?.nameFa || fallback.alt,
|
|
nameFa: slot?.nameFa || fallback.nameFa,
|
|
nameEn: slot?.nameEn || fallback.nameEn,
|
|
href:
|
|
slot?.link ||
|
|
`/products?color=black&item=${fallback.id}`,
|
|
};
|
|
})
|
|
: BLACK_ITEMS.map((item) => {
|
|
const slot = firstForSlot(items, `home.black.${item.id}`);
|
|
return {
|
|
id: item.id,
|
|
image: slot?.imageUrl || item.image,
|
|
alt: slot?.nameFa || item.alt,
|
|
nameFa: slot?.nameFa || item.nameFa,
|
|
nameEn: slot?.nameEn || item.nameEn,
|
|
href: slot?.link || `/products?color=black&item=${item.id}`,
|
|
};
|
|
});
|
|
|
|
const aboutItems = slotItems(items, "about");
|
|
const aboutPrimary =
|
|
aboutItems.find((row) => row.sortOrder === 0) ??
|
|
aboutItems[0] ??
|
|
firstSlot(items, "about-primary", "home.about.primary");
|
|
const aboutSecondary =
|
|
aboutItems.find((row) => row.sortOrder === 1) ??
|
|
aboutItems[1] ??
|
|
firstSlot(items, "about-secondary", "home.about.secondary");
|
|
const about = {
|
|
titleFa: aboutPrimary?.nameFa || ABOUT.titleFa,
|
|
titleEn: aboutPrimary?.nameEn || ABOUT.titleEn,
|
|
lead: aboutPrimary?.subtext || ABOUT.lead,
|
|
body: ABOUT.body,
|
|
image: aboutPrimary?.imageUrl || ABOUT.image,
|
|
imageSecondary: aboutSecondary?.imageUrl || ABOUT.imageSecondary,
|
|
};
|
|
|
|
const paymentSlot = firstSlot(
|
|
items,
|
|
"payment-badges",
|
|
"home.footer.payment_badges",
|
|
);
|
|
const paymentBadges =
|
|
paymentSlot?.imageUrl || "/images/home/banners/payment-badges.png";
|
|
|
|
const megaItems = slotItems(items, "mega-menu");
|
|
const megaTabs = MEGA_MENU_TABS.map((tab, index) => {
|
|
const slot =
|
|
megaItems.find((row) => row.sortOrder === index) ??
|
|
megaItems[index] ??
|
|
firstForSlot(items, `nav.mega.${tab.id}`);
|
|
return {
|
|
id: tab.id,
|
|
nameFa: slot?.nameFa || tab.nameFa,
|
|
nameEn: slot?.nameEn || tab.nameEn,
|
|
href: slot?.link || tab.href,
|
|
image: slot?.imageUrl || tab.image,
|
|
links: tab.links,
|
|
columns: [
|
|
{
|
|
title: slot?.nameFa || tab.nameFa,
|
|
href: slot?.link || tab.href,
|
|
links: tab.links,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
return {
|
|
heroSlides,
|
|
categories,
|
|
leather,
|
|
promoSale,
|
|
promoDiscount,
|
|
promoAutumn,
|
|
blackItems,
|
|
about,
|
|
paymentBadges,
|
|
megaTabs,
|
|
};
|
|
}
|