import { z } from "zod" import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks" import { tempImageVaultAssetSchema } from "../imageVault" import { systemSchema } from "../system" import { buttonSchema } from "./utils/buttonLinkSchema" import { linkConnectionRefsSchema } from "./utils/linkConnection" import { imageSchema } from "./image" import { imageContainerSchema } from "./imageContainer" import { BlocksEnums } from "@/types/enums/blocks" import { CardsGridEnum, CardsGridLayoutEnum } from "@/types/enums/cardsGrid" import { scriptedCardThemeEnum } from "@/types/enums/scriptedCard" export const cardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.Card), // JSON - ImageVault Image background_image: tempImageVaultAssetSchema, 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 transformCardBlock(card: typeof cardBlockSchema._type) { return { __typename: card.__typename, backgroundImage: card.background_image, body_text: card.body_text, heading: card.heading, primaryButton: card.has_primary_button ? card.primary_button : undefined, scripted_top_title: card.scripted_top_title, secondaryButton: card.has_secondary_button ? card.secondary_button : undefined, system: card.system, title: card.title, } } export const teaserCardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.TeaserCard), heading: z.string().default(""), body_text: z.string().default(""), image: tempImageVaultAssetSchema, primary_button: buttonSchema, secondary_button: buttonSchema, has_primary_button: z.boolean().default(false), has_secondary_button: z.boolean().default(false), has_sidepeek_button: z.boolean().default(false), sidepeek_button: z .object({ call_to_action_text: z.string().optional().default(""), }) .optional(), sidepeek_content: z .object({ heading: z.string(), content: z.object({ json: z.any(), embedded_itemsConnection: z.object({ edges: z.array( z.object({ node: z .discriminatedUnion("__typename", [ imageContainerSchema, imageSchema, pageLinks.accountPageSchema, pageLinks.contentPageSchema, pageLinks.hotelPageSchema, pageLinks.loyaltyPageSchema, pageLinks.collectionPageSchema, ]) .transform((data) => { const link = pageLinks.transform(data) if (link) { return link } return data }), }) ), }), }), has_primary_button: z.boolean().default(false), primary_button: buttonSchema, has_secondary_button: z.boolean().default(false), secondary_button: buttonSchema, }) .optional() .transform((data) => { if (!data) { return undefined } return { ...data, primary_button: data.has_primary_button ? data.primary_button : undefined, secondary_button: data.has_secondary_button ? data.secondary_button : undefined, } }), system: systemSchema, }) export function transformTeaserCardBlock( card: typeof teaserCardBlockSchema._type ) { return { __typename: card.__typename, body_text: card.body_text, heading: card.heading, primaryButton: card.has_primary_button ? card.primary_button : undefined, secondaryButton: card.has_secondary_button ? card.secondary_button : undefined, sidePeekButton: card.has_sidepeek_button ? card.sidepeek_button : undefined, sidePeekContent: card.has_sidepeek_button ? card.sidepeek_content : undefined, image: card.image, system: card.system, } } const loyaltyCardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.LoyaltyCard), body_text: z.string().optional(), heading: z.string().optional().default(""), // JSON - ImageVault Image image: tempImageVaultAssetSchema, link: buttonSchema, system: systemSchema, title: z.string().optional(), }) 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", [ cardBlockSchema, loyaltyCardBlockSchema, teaserCardBlockSchema, ]), }) ), }), layout: z.nativeEnum(CardsGridLayoutEnum), preamble: z.string().optional().default(""), theme: z.nativeEnum(scriptedCardThemeEnum).nullable(), title: z.string().optional().default(""), }) .transform((data) => { return { layout: data.layout, preamble: data.preamble, theme: data.theme, title: data.title, cards: data.cardConnection.edges.map((card) => { if (card.node.__typename === CardsGridEnum.cards.Card) { return transformCardBlock(card.node) } else if (card.node.__typename === CardsGridEnum.cards.TeaserCard) { return transformTeaserCardBlock(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 const cardBlockRefsSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.Card), primary_button: linkConnectionRefsSchema, secondary_button: linkConnectionRefsSchema, system: systemSchema, }) export function transformCardBlockRefs( card: | typeof cardBlockRefsSchema._type | typeof teaserCardBlockRefsSchema._type ) { const cards = [card.system] if (card.primary_button) { cards.push(card.primary_button) } if (card.secondary_button) { cards.push(card.secondary_button) } return cards } const loyaltyCardBlockRefsSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.LoyaltyCard), link: linkConnectionRefsSchema, system: systemSchema, }) export const teaserCardBlockRefsSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.TeaserCard), primary_button: linkConnectionRefsSchema, secondary_button: linkConnectionRefsSchema, system: systemSchema, }) export const cardGridRefsSchema = z.object({ cards_grid: z .object({ cardConnection: z.object({ edges: z.array( z.object({ node: z.discriminatedUnion("__typename", [ cardBlockRefsSchema, loyaltyCardBlockRefsSchema, teaserCardBlockRefsSchema, ]), }) ), }), }) .transform((data) => { return data.cardConnection.edges .map(({ node }) => { if ( node.__typename === CardsGridEnum.cards.Card || node.__typename === CardsGridEnum.cards.TeaserCard ) { return transformCardBlockRefs(node) } else { const loyaltyCards = [node.system] if (node.link) { loyaltyCards.push(node.link) } return loyaltyCards } }) .flat() }), })