import { z } from "zod" import { Lang } from "@/constants/languages" import { JoinLoyaltyContactTypenameEnum, LoyaltyBlocksTypenameEnum, LoyaltyComponentEnum, SidebarTypenameEnum, } from "@/types/components/loyalty/enums" import { Embeds } from "@/types/requests/embeds" import { PageLinkEnum } from "@/types/requests/pageLinks" 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({ 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 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(cardBlock), }), }) 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(), contact: z.array( z.object({ __typename: z.literal( JoinLoyaltyContactTypenameEnum.LoyaltyPageSidebarJoinLoyaltyContactBlockContactContact ), contact: z.object({ display_text: z.string().nullable(), contact_field: z.string(), }), }) ), }), }) const loyaltyPageSidebarItem = z.discriminatedUnion("__typename", [ loyaltyPageSidebarTextContent, 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 CardsGridRaw = z.infer export type CardsRaw = CardsGridRaw["cards_grid"]["cards"][number] export type CardsGrid = z.infer 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 } } } export type JoinLoyaltyContact = z.infer export type Sidebar = JoinLoyaltyContact | RteSidebarContent 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 cardBlockRefs = z.object({ 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 loyaltyPageCardsRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid), cards_grid: z.object({ cardConnection: z.object({ edges: z.array( z.object({ node: cardBlockRefs, }) ), }), }), }) 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: pageConnectionRefs, }), }), }) 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: pageConnectionRefs, }), }), }) const loyaltyPageSidebarRefsItem = z.discriminatedUnion("__typename", [ loyaltyPageSidebarTextContentRef, ]) 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 >