import { GetLoyaltyPage, GetLoyaltyPageRefs, } from "@/lib/graphql/Query/LoyaltyPage.graphql" import { request } from "@/lib/graphql/request" import { _ } from "@/lib/translation" import { internalServerError, notFound } from "@/server/errors/trpc" import { contentstackProcedure, router } from "@/server/trpc" import { generateRefsResponseTag, generateTag, generateTags, } from "@/utils/generateTag" import { removeEmptyObjects } from "../../utils" import { LoyaltyPage, type LoyaltyPageRefsDataRaw, validateLoyaltyPageRefsSchema, validateLoyaltyPageSchema, } from "./output" import { getConnections } from "./utils" import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums" function makeButtonObject(button: any) { return { openInNewTab: button.open_in_new_tab, title: button.cta_text || (button.is_contentstack_link && button.linkConnection.edges.length ? button.linkConnection.edges[0].node.title : button.external_link.title), href: button.is_contentstack_link && button.linkConnection.edges.length ? button.linkConnection.edges[0].node.web?.original_url || `/${button.linkConnection.edges[0].node.system.locale}${button.linkConnection.edges[0].node.url}` : button.external_link.href, isExternal: !button.is_contentstack_link, } } export const loyaltyPageQueryRouter = router({ get: contentstackProcedure.query(async ({ ctx }) => { const { lang, uid } = ctx const refsResponse = await request( GetLoyaltyPageRefs, { locale: lang, uid, }, { next: { tags: [generateRefsResponseTag(lang, uid)], }, } ) if (!refsResponse.data) { throw notFound(refsResponse) } // Remove empty objects from a fetched content type. Needed since // Contentstack returns empty objects for all non queried blocks in modular blocks. // This is an ongoing support case in Contentstack, ticker number #00031579 const cleanedData = removeEmptyObjects(refsResponse.data) const validatedLoyaltyPageRefs = validateLoyaltyPageRefsSchema.safeParse(cleanedData) if (!validatedLoyaltyPageRefs.success) { console.error("Bad validation for `GetLoyaltyPageRefs`") console.error(validatedLoyaltyPageRefs.error) throw internalServerError(validatedLoyaltyPageRefs.error) } const connections = getConnections(validatedLoyaltyPageRefs.data) const tags = [ generateTags(lang, connections), generateTag(lang, validatedLoyaltyPageRefs.data.loyalty_page.system.uid), ].flat() const response = await request( GetLoyaltyPage, { locale: lang, uid, }, { next: { tags } } ) if (!response.data) { throw notFound(response) } const blocks = response.data.loyalty_page.blocks ? response.data.loyalty_page.blocks.map((block: any) => { switch (block.__typename) { case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent: return { ...block, dynamic_content: { ...block.dynamic_content, link: block.dynamic_content.link.pageConnection.edges.length ? { text: block.dynamic_content.link.text, href: `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}${block.dynamic_content.link.pageConnection.edges[0].node.url}`, title: block.dynamic_content.link.pageConnection.edges[0] .node.title, } : undefined, }, } case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: return { ...block, shortcuts: { ...block.shortcuts, shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({ text: shortcut.text, openInNewTab: shortcut.open_in_new_tab, ...shortcut.linkConnection.edges[0].node, url: shortcut.linkConnection.edges[0].node.web?.original_url || `/${shortcut.linkConnection.edges[0].node.system.locale}${shortcut.linkConnection.edges[0].node.url}`, })), }, } case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid: return { ...block, cards_grid: { ...block.cards_grid, cards: block.cards_grid.cardConnection.edges.map( ({ node: card }: { node: any }) => { return { ...card, primaryButton: card.has_primary_button ? makeButtonObject(card.primary_button) : undefined, secondaryButton: card.has_secondary_button ? makeButtonObject(card.secondary_button) : undefined, } } ), }, } default: return block } }) : null const loyaltyPage = { heading: response.data.loyalty_page.heading, system: response.data.loyalty_page.system, blocks, sidebar: response.data.loyalty_page.sidebar, } const validatedLoyaltyPage = validateLoyaltyPageSchema.safeParse(loyaltyPage) if (!validatedLoyaltyPage.success) { throw internalServerError(validatedLoyaltyPage.error) } // Assert LoyaltyPage type to get correct typings for RTE fields return validatedLoyaltyPage.data as LoyaltyPage }), })