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 pageLink = z.object({ edges: z.array( z.object({ node: z.object({ system: z.object({ uid: z.string(), locale: z.nativeEnum(Lang), }), web: z .object({ original_url: z.string().nullable(), }) .nullable() .optional(), url: z.string(), title: z.string(), __typename: z.string().optional(), }), }) ), }) 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().nullable(), pageConnection: pageLink, }), }), }) 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({ linkConnection: pageLink, text: z.string().nullable(), open_in_new_tab: z.boolean(), }) ), }), }) const cardBlock = z.object({ heading: z.string().nullable(), body_text: z.string().nullable(), background_image: z.any(), scripted_top_title: z.string().nullable(), primary_button: z .object({ is_contentstack_link: z.boolean(), cta_text: z.string().nullable(), open_in_new_tab: z.boolean(), external_link: z.object({ title: z.string().nullable(), href: z.string().nullable(), }), linkConnection: pageLink, }) .nullable(), secondary_button: z .object({ is_contentstack_link: z.boolean(), cta_text: z.string().nullable(), open_in_new_tab: z.boolean().nullable(), external_link: z.object({ title: z.string().nullable(), href: z.string().nullable(), }), linkConnection: pageLink, }) .nullable(), 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(), cardConnection: z.object({ edges: z.array( z.object({ node: 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({ loyalty_page: z.object({ title: z.string(), heading: z.string().nullable(), blocks: z.array(loyaltyPageBlockItem).nullable(), sidebar: z.array(loyaltyPageSidebarItem).nullable(), system: z.object({ uid: z.string() }), }), }) // Block types type DynamicContentRaw = z.infer export type DynamicContent = Omit & { dynamic_content: Omit & { link: | { href: string title: string text?: string } | undefined } } 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"]["cardConnection"]["edges"][number]["node"] export type CardsGrid = Omit & { cards_grid: Omit & { cards: (Omit & { primaryButton: | { openInNewTab: boolean title: string href: string isExternal: boolean } | undefined secondaryButton: | { openInNewTab: boolean title: string href: string isExternal: boolean } | undefined })[] } } type ShortcutsRaw = z.infer export type Shortcuts = Omit & { shortcuts: Omit & { shortcuts: { text?: string openInNewTab: boolean url: string title: string }[] } } 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 export type LoyaltyPageDataRaw = z.infer type LoyaltyPageRaw = LoyaltyPageDataRaw["loyalty_page"] 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 >