feat(cms): add Interactive 360 Turntable and Macro Zoom Showcase block

This commit is contained in:
Your Name committed 2026-10-17 09:25:16 +07:00
1 parent 8d9f2fc587
commit 64f7ecf729
12 files changed
+1185 -3

No files matched your search

+32 -1
View File
@@ -1337,6 +1337,35 @@ export const CinematicStoryScrollSectionPayloadSchema = z.object({
}).passthrough();
export type CinematicStoryScrollSectionPayload = z.infer<typeof CinematicStoryScrollSectionPayloadSchema>;
export const Interactive360ShowcaseSectionPayloadSchema = z.object({
spriteSheetUrl: z.string().optional().default('/images/3d/sprocket-views.png'),
detailImageUrl: z.string().optional().default('/images/3d/sprocket-detail.png'),
columns: z.number().optional().default(4),
rows: z.number().optional().default(4),
eyebrow: z.string().optional(),
title: z.string().optional(),
subtitle: z.string().optional(),
detailKicker: z.string().optional(),
detailTitle: z.string().optional(),
detailCaption: z.string().optional(),
productName: z.string().optional(),
productBadge: z.string().optional(),
specs: z.array(z.object({
number: z.string().optional(),
title: z.string(),
subtitle: z.string().optional(),
})).optional(),
endCtaTitle: z.string().optional(),
endCtaButtonText: z.string().optional(),
endCtaLink: z.string().optional(),
theme: z.enum(['dark', 'light']).optional().default('dark'),
accentColor: z.string().optional().default('#d5ff63'),
productId: z.union([z.number(), z.string(), z.null()]).optional(),
paddingTop: z.string().optional(),
paddingBottom: z.string().optional(),
}).passthrough();
export type Interactive360ShowcaseSectionPayload = z.infer<typeof Interactive360ShowcaseSectionPayloadSchema>;
export const AppleShowcaseSectionPayloadSchema = z.object({
productId: z.union([z.number(), z.string(), z.null()]).optional(),
heroImage: z.string().optional(),
@@ -1360,7 +1389,7 @@ export const PAGE_SECTION_TYPES = [
'USP_BAR', 'PRODUCT_MAIN', 'PRODUCT_DETAILS', 'PRODUCT_SPECS',
'PRODUCT_REVIEWS', 'RELATED_PRODUCTS', 'CUSTOM',
'HERO_MINIMAL', 'HERO_SPLIT_MINIMAL', 'HERO_VIDEO_MINIMAL', 'BANNER_MINIMAL', 'ANNOUNCEMENT_BAR_MINIMAL', 'USP_MINIMAL',
'CINEMATIC_STORY_SCROLL', 'APPLE_SHOWCASE'
'CINEMATIC_STORY_SCROLL', 'APPLE_SHOWCASE', 'INTERACTIVE_360_SHOWCASE'
] as const;
export type SectionType = typeof PAGE_SECTION_TYPES[number];
@@ -1411,6 +1440,7 @@ export const PAGE_SECTION_LOCALIZED_PATHS: Record<SectionType, readonly string[]
USP_MINIMAL: ['items[]'],
CINEMATIC_STORY_SCROLL: ['endCtaTitle', 'endCtaButtonText'],
APPLE_SHOWCASE: ['endCtaTitle', 'endCtaButtonText'],
INTERACTIVE_360_SHOWCASE: ['eyebrow', 'title', 'subtitle', 'detailKicker', 'detailTitle', 'detailCaption', 'productName', 'endCtaTitle', 'endCtaButtonText'],
};
export const PAGE_SECTION_PAYLOAD_SCHEMAS: Record<SectionType, z.ZodType> = {
@@ -1460,6 +1490,7 @@ export const PAGE_SECTION_PAYLOAD_SCHEMAS: Record<SectionType, z.ZodType> = {
USP_MINIMAL: UspMinimalSectionPayloadSchema,
CINEMATIC_STORY_SCROLL: CinematicStoryScrollSectionPayloadSchema,
APPLE_SHOWCASE: AppleShowcaseSectionPayloadSchema,
INTERACTIVE_360_SHOWCASE: Interactive360ShowcaseSectionPayloadSchema,
};
export const PRODUCT_DETAIL_SECTION_TYPES = [