import { z } from "zod" import { Lang } from "@/constants/languages" import { ImageVaultAsset } from "@/types/components/imageVaultImage" import { JoinLoyaltyContactTypenameEnum, LoyaltyBlocksTypenameEnum, LoyaltyCardsGridEnum, LoyaltyComponentEnum, LoyaltySidebarDynamicComponentEnum, SidebarTypenameEnum, } from "@/types/components/loyalty/enums" import { Embeds } from "@/types/requests/embeds" import { PageLinkEnum } from "@/types/requests/pageLinks" import { RTEEmbedsEnum } from "@/types/requests/rte" import { EdgesWithTotalCount } from "@/types/requests/utils/edges" import { RTEDocument } from "@/types/rte/node" const loyaltyPageDynamicContent = z.object({ __typename: z.literal( LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent ), dynamic_content: z.object({ title: z.string().nullable(), subtitle: z.string().nullable(), component: z.nativeEnum(LoyaltyComponentEnum), link: z .object({ text: z.string(), href: z.string(), }) .optional(), }), }) const loyaltyPageShortcuts = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts), shortcuts: z.object({ title: z.string().nullable(), preamble: z.string().nullable(), shortcuts: z.array( z.object({ text: z.string().optional(), openInNewTab: z.boolean(), url: z.string(), title: z.string(), }) ), }), }) const cardBlock = z.object({ __typename: z.literal(LoyaltyCardsGridEnum.Card), heading: z.string().nullable(), body_text: z.string().nullable(), background_image: z.any(), scripted_top_title: z.string().nullable(), primaryButton: z .object({ openInNewTab: z.boolean(), title: z.string(), href: z.string(), isExternal: z.boolean(), }) .optional(), secondaryButton: z .object({ openInNewTab: z.boolean(), title: z.string(), href: z.string(), isExternal: z.boolean(), }) .optional(), system: z.object({ locale: z.nativeEnum(Lang), uid: z.string(), }), }) const loyaltyCardBlock = z.object({ __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard), heading: z.string().nullable(), body_text: z.string().nullable(), image: z.any(), link: z .object({ openInNewTab: z.boolean(), title: z.string(), href: z.string(), isExternal: z.boolean(), }) .optional(), system: z.object({ locale: z.nativeEnum(Lang), uid: z.string(), }), }) const loyaltyPageCardsItems = z.discriminatedUnion("__typename", [ loyaltyCardBlock, cardBlock, ]) const loyaltyPageCards = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid), cards_grid: z.object({ title: z.string().nullable(), preamble: z.string().nullable(), layout: z.enum(["twoColumnGrid", "threeColumnGrid", "twoPlusOne"]), theme: z.enum(["one", "two", "three"]).nullable(), cards: z.array(loyaltyPageCardsItems), }), }) const loyaltyPageBlockTextContent = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent), content: z.object({ content: z.object({ embedded_itemsConnection: z.object({ edges: z.array(z.any()), totalCount: z.number(), }), json: z.any(), }), }), }) const loyaltyPageBlockItem = z.discriminatedUnion("__typename", [ loyaltyPageDynamicContent, loyaltyPageBlockTextContent, loyaltyPageShortcuts, loyaltyPageCards, ]) const loyaltyPageSidebarTextContent = z.object({ __typename: z.literal(SidebarTypenameEnum.LoyaltyPageSidebarContent), content: z.object({ content: z.object({ embedded_itemsConnection: z.object({ edges: z.array(z.any()), totalCount: z.number(), }), json: z.any(), }), }), }) const loyaltyPageJoinLoyaltyContact = z.object({ __typename: z.literal( SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact ), join_loyalty_contact: z.object({ title: z.string().nullable(), preamble: z.string().nullable(), button: z .object({ openInNewTab: z.boolean(), title: z.string(), href: z.string(), isExternal: z.boolean(), }) .nullable(), contact: z.array( z.object({ __typename: z.literal( JoinLoyaltyContactTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContactBlockContactContact ), contact: z.object({ display_text: z.string().nullable(), contact_field: z.string(), footnote: z.string().nullable(), }), }) ), }), }) const loyaltyPageSidebarDynamicContent = z.object({ __typename: z.literal(SidebarTypenameEnum.LoyaltyPageSidebarDynamicContent), dynamic_content: z.object({ component: z.nativeEnum(LoyaltySidebarDynamicComponentEnum), }), }) const loyaltyPageSidebarItem = z.discriminatedUnion("__typename", [ loyaltyPageSidebarTextContent, loyaltyPageSidebarDynamicContent, loyaltyPageJoinLoyaltyContact, ]) export const validateLoyaltyPageSchema = z.object({ heading: z.string().nullable(), blocks: z.array(loyaltyPageBlockItem).nullable(), sidebar: z.array(loyaltyPageSidebarItem).nullable(), system: z.object({ uid: z.string() }), }) // Block types export type DynamicContent = z.infer type BlockContentRaw = z.infer export interface RteBlockContent extends BlockContentRaw { content: { content: { json: RTEDocument embedded_itemsConnection: EdgesWithTotalCount } } } type LoyaltyCardRaw = z.infer type LoyaltyCard = Omit & { image?: ImageVaultAsset } type CardRaw = z.infer type Card = Omit & { backgroundImage?: ImageVaultAsset } type CardsGridRaw = z.infer export type CardsGrid = Omit & { cards: (LoyaltyCard | Card)[] } export type CardsRaw = CardsGrid["cards_grid"]["cards"][number] export type Shortcuts = z.infer export type Block = RteBlockContent | DynamicContent | Shortcuts | CardsGrid // Sidebar block types type SidebarContentRaw = z.infer export type RteSidebarContent = Omit & { content: { content: { json: RTEDocument embedded_itemsConnection: EdgesWithTotalCount } } } type SideBarDynamicContent = z.infer export type JoinLoyaltyContact = z.infer export type Sidebar = | JoinLoyaltyContact | RteSidebarContent | SideBarDynamicContent type LoyaltyPageDataRaw = z.infer export type LoyaltyPage = Omit & { blocks: Block[] sidebar: Sidebar[] } // Refs types const pageConnectionRefs = z.object({ edges: z.array( z.object({ node: z.object({ __typename: z.nativeEnum(PageLinkEnum), system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }), }) ), }) const rteConnectionRefs = z.object({ edges: z.array( z.object({ node: z.object({ __typename: z.nativeEnum(RTEEmbedsEnum), system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }), }) ), }) const cardBlockRefs = z.object({ __typename: z.literal(LoyaltyCardsGridEnum.Card), primary_button: z .object({ linkConnection: pageConnectionRefs, }) .nullable(), secondary_button: z .object({ linkConnection: pageConnectionRefs, }) .nullable(), system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }) const loyaltyCardBlockRefs = z.object({ __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard), link: z .object({ linkConnection: pageConnectionRefs, }) .nullable(), system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }) const cardGridCardsRef = z.discriminatedUnion("__typename", [ loyaltyCardBlockRefs, cardBlockRefs, ]) const loyaltyPageCardsRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid), cards_grid: z.object({ cardConnection: z.object({ edges: z.array( z.object({ node: cardGridCardsRef, }) ), }), }), }) const loyaltyPageDynamicContentRefs = z.object({ __typename: z.literal( LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent ), dynamic_content: z.object({ link: z.object({ pageConnection: pageConnectionRefs, }), }), }) const loyaltyPageShortcutsRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts), shortcuts: z.object({ shortcuts: z.array( z.object({ linkConnection: pageConnectionRefs, }) ), }), }) const loyaltyPageBlockTextContentRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksContent), content: z.object({ content: z.object({ embedded_itemsConnection: rteConnectionRefs, }), }), }) const loyaltyPageBlocRefsItem = z.discriminatedUnion("__typename", [ loyaltyPageDynamicContentRefs, loyaltyPageBlockTextContentRefs, loyaltyPageShortcutsRefs, loyaltyPageCardsRefs, ]) const loyaltyPageSidebarTextContentRef = z.object({ __typename: z.literal(SidebarTypenameEnum.LoyaltyPageSidebarContent), content: z.object({ content: z.object({ embedded_itemsConnection: rteConnectionRefs, }), }), }) const loyaltyPageSidebarJoinLoyaltyContactRef = z.object({ __typename: z.literal( SidebarTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContact ), join_loyalty_contact: z.object({ button: z .object({ linkConnection: pageConnectionRefs, }) .nullable(), }), }) const loyaltyPageSidebarRefsItem = z.discriminatedUnion("__typename", [ loyaltyPageSidebarTextContentRef, loyaltyPageSidebarJoinLoyaltyContactRef, ]) export const validateLoyaltyPageRefsSchema = z.object({ loyalty_page: z.object({ blocks: z.array(loyaltyPageBlocRefsItem).nullable(), sidebar: z.array(loyaltyPageSidebarRefsItem).nullable(), system: z.object({ content_type_uid: z.string(), uid: z.string(), }), }), }) export type LoyaltyPageRefsDataRaw = z.infer< typeof validateLoyaltyPageRefsSchema >