Wire homepage images to Meshkee slots and publish the catalog.
The dashboard can refresh these keys from the live site. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
1272977923
commit
1c2d1eb31c
@@ -0,0 +1,104 @@
|
||||
export type StaticImage = {
|
||||
id: string;
|
||||
url?: string | null;
|
||||
title?: string | null;
|
||||
linkUrl?: string | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
sortOrder?: number;
|
||||
};
|
||||
|
||||
export type StaticImageWithUrl = StaticImage & { url: string };
|
||||
|
||||
export type StaticImageSlot = {
|
||||
id: string;
|
||||
key: string;
|
||||
kind: "single" | "list";
|
||||
label?: string;
|
||||
aspectRatio?: string;
|
||||
recommendedWidth?: number;
|
||||
sortOrder?: number;
|
||||
images?: StaticImage[];
|
||||
};
|
||||
|
||||
export const STATIC_IMAGE_KEYS = {
|
||||
slider: "slider",
|
||||
bannerInSpecialSale: "banner-in-special-sale",
|
||||
categories: "categories",
|
||||
twoBannerRow: "two-banner-row",
|
||||
} as const;
|
||||
|
||||
export const STATIC_IMAGE_SLOT_CATALOG = [
|
||||
{
|
||||
key: STATIC_IMAGE_KEYS.slider,
|
||||
label: "Homepage slider",
|
||||
kind: "list" as const,
|
||||
pageKey: "home",
|
||||
aspectRatio: "16:9",
|
||||
itemCount: null,
|
||||
recommendedWidth: 1440,
|
||||
},
|
||||
{
|
||||
key: STATIC_IMAGE_KEYS.bannerInSpecialSale,
|
||||
label: "Banner in special sale",
|
||||
kind: "single" as const,
|
||||
pageKey: "home",
|
||||
aspectRatio: "12:19",
|
||||
itemCount: 1,
|
||||
recommendedWidth: 480,
|
||||
},
|
||||
{
|
||||
key: STATIC_IMAGE_KEYS.categories,
|
||||
label: "Featured category images",
|
||||
kind: "list" as const,
|
||||
pageKey: "home",
|
||||
aspectRatio: "1:1",
|
||||
itemCount: null,
|
||||
recommendedWidth: 400,
|
||||
},
|
||||
{
|
||||
key: STATIC_IMAGE_KEYS.twoBannerRow,
|
||||
label: "Two banner row",
|
||||
kind: "list" as const,
|
||||
pageKey: "home",
|
||||
aspectRatio: "16:5",
|
||||
itemCount: 2,
|
||||
recommendedWidth: 1440,
|
||||
},
|
||||
];
|
||||
|
||||
const API_BASE = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
|
||||
const DOMAIN = process.env.NEXT_PUBLIC_DOMAIN ?? "";
|
||||
|
||||
export async function getStaticImageSlots(): Promise<StaticImageSlot[]> {
|
||||
if (!API_BASE || !DOMAIN) return [];
|
||||
|
||||
try {
|
||||
const res = await fetch(
|
||||
`${API_BASE}/tenants/${DOMAIN}/website/static-images`,
|
||||
{ cache: "no-store" },
|
||||
);
|
||||
if (!res.ok) return [];
|
||||
const data: { items?: StaticImageSlot[] } = await res.json();
|
||||
return data.items ?? [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function imagesForSlot(
|
||||
slots: StaticImageSlot[],
|
||||
key: string,
|
||||
): StaticImageWithUrl[] {
|
||||
const images = slots.find((slot) => slot.key === key)?.images ?? [];
|
||||
return [...images]
|
||||
.filter((image): image is StaticImageWithUrl => Boolean(image.url))
|
||||
.sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
|
||||
}
|
||||
|
||||
export function firstImageForSlot(
|
||||
slots: StaticImageSlot[],
|
||||
key: string,
|
||||
): StaticImageWithUrl | undefined {
|
||||
return imagesForSlot(slots, key)[0];
|
||||
}
|
||||
Reference in New Issue
Block a user