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 loyaltyPageBlockCardGrid = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid), card_grid: z.object({ title: z.string().nullable(), subtitle: z.string().nullable(), cards: z.array( z.object({ title: z.string().nullable(), subtitle: z.string().nullable(), referenceConnection: z.object({ edges: z.array( z.object({ node: z.object({ system: z.object({ uid: z.string(), locale: z.nativeEnum(Lang), }), url: z.string(), title: z.string(), __typename: z.string(), }), }) ), totalCount: z.number(), }), open_in_new_tab: z.boolean(), cta_text: z.string().nullable(), }) ), }), }) 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: z.object({ edges: z.array( z.object({ node: z.object({ system: z.object({ uid: z.string(), locale: z.nativeEnum(Lang), }), url: z.string(), title: z.string(), }), }) ), totalCount: z.number(), }), }), }), }) 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: z.object({ edges: z.array( z.object({ node: z.object({ system: z.object({ uid: z.string(), locale: z.nativeEnum(Lang), }), url: z.string(), web: z .object({ original_url: z.string().nullable(), }) .nullable(), title: z.string(), }), }) ), totalCount: z.number(), }), text: z.string().nullable(), open_in_new_tab: z.boolean(), }) ), }), }) 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", [ loyaltyPageBlockCardGrid, loyaltyPageDynamicContent, loyaltyPageBlockTextContent, loyaltyPageShortcuts, ]) 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 CardGridRaw = z.infer export type CardGridCard = Omit< CardGridRaw["card_grid"]["cards"][number], "referenceConnection" > & { link: | { href: string title: string } | undefined } export type CardGrid = Omit & { card_grid: Omit & { cards: CardGridCard[] } } 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 ShortcutsRaw = z.infer export type Shortcuts = Omit & { shortcuts: Omit & { shortcuts: { text?: string openInNewTab: boolean url: string title: string }[] } } export type Block = CardGrid | RteBlockContent | DynamicContent | Shortcuts // 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 loyaltyPageBlockCardGridRefs = z.object({ __typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid), card_grid: z.object({ cards: z.array( z.object({ referenceConnection: pageConnectionRefs, }) ), }), }) 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", [ loyaltyPageBlockCardGridRefs, loyaltyPageDynamicContentRefs, loyaltyPageBlockTextContentRefs, loyaltyPageShortcutsRefs, ]) 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 >