import { z } from "zod" import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { scriptedCardThemeEnum } from "../../../../enums/scriptedCard" import { BlocksEnums } from "../../../../types/blocksEnum" import { CardsGridEnum, CardsGridLayoutEnum, } from "../../../../types/cardsGridEnum" import { systemSchema } from "../system" import { infoCardWithImageBlockSchema, transformInfoCardWithImageBlock, } from "./cards/infoCardWithImage" import { loyaltyCardBlockSchema } from "./cards/loyaltyCard" import { teaserCardBlockSchema, transformTeaserCardBlock, } from "./cards/teaserCard" import { buttonSchema } from "./utils/buttonLinkSchema" export const infoCardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.InfoCard), // JSON - ImageVault Image background_image: transformedImageVaultAssetSchema, body_text: z.string().optional().default(""), has_primary_button: z.boolean().default(false), has_secondary_button: z.boolean().default(false), heading: z.string().optional().default(""), primary_button: buttonSchema, scripted_top_title: z.string().optional(), secondary_button: buttonSchema, system: systemSchema, title: z.string().optional(), }) export function transformInfoCardBlock(card: typeof infoCardBlockSchema._type) { return { __typename: card.__typename, backgroundImage: card.background_image ? { src: card.background_image.url, alt: card.background_image.meta.alt ?? undefined, focalPoint: card.background_image.focalPoint, dimensions: card.background_image.dimensions, } : undefined, bodyText: card.body_text, heading: card.heading, primaryButton: card.has_primary_button && card.primary_button ? { href: card.primary_button.href, text: card.primary_button.title, openInNewTab: card.primary_button.openInNewTab, } : undefined, topTitle: card.scripted_top_title, secondaryButton: card.has_secondary_button && card.secondary_button ? { href: card.secondary_button.href, text: card.secondary_button.title, openInNewTab: card.secondary_button.openInNewTab, } : undefined, system: card.system, title: card.title, } } export const cardsGridSchema = z.object({ typename: z .literal(BlocksEnums.block.CardsGrid) .optional() .default(BlocksEnums.block.CardsGrid), cards_grid: z .object({ cardConnection: z.object({ edges: z.array( z.object({ node: z.discriminatedUnion("__typename", [ infoCardBlockSchema, loyaltyCardBlockSchema, teaserCardBlockSchema, infoCardWithImageBlockSchema, ]), }) ), }), link: buttonSchema.nullish(), layout: z.nativeEnum(CardsGridLayoutEnum), preamble: z.string().optional().default(""), theme: z .nativeEnum(scriptedCardThemeEnum) .nullable() .transform(getInfoCardThemeFromDeprecatedCardTheme), title: z.string().optional().default(""), }) .transform((data) => { return { layout: data.layout, preamble: data.preamble, theme: data.theme, title: data.title, link: data.link?.href && data.link.title ? { href: data.link.href, text: data.link.title } : undefined, cards: data.cardConnection.edges.map((card) => { if (card.node.__typename === CardsGridEnum.cards.InfoCard) { return transformInfoCardBlock(card.node) } else if (card.node.__typename === CardsGridEnum.cards.TeaserCard) { return transformTeaserCardBlock(card.node) } else if ( card.node.__typename === CardsGridEnum.cards.InfoCardWithImage ) { return transformInfoCardWithImageBlock(card.node) } else { return { __typename: card.node.__typename, body_text: card.node.body_text, heading: card.node.heading, image: card.node.image, link: card.node.link, system: card.node.system, title: card.node.title, } } }), } }), }) export function getInfoCardThemeFromDeprecatedCardTheme(theme?: string | null) { if (!theme) { return null } switch (theme) { case "one": return "Primary 1" case "primaryDark": return "Primary 3" case "primaryDim": return "Accent" case "primaryInverted": return "White" case "primaryStrong": return "Primary 2" case "image": return "Image" case "two": // Doesn't exist anymore, map to Primary 1 case "three": // Doesn't exist anymore, map to Primary 1 default: return "Primary 1" } }