import { Lang } from "@/constants/languages" import { GetContentPage } from "@/lib/graphql/Query/ContentPage.graphql" import { request } from "@/lib/graphql/request" import { notFound } from "@/server/errors/trpc" import { contentstackExtendedProcedureUID, router } from "@/server/trpc" import { makeImageVaultImage } from "@/utils/imageVault" import { removeMultipleSlashes } from "@/utils/url" import { removeEmptyObjects } from "../../utils" import { Block, ContentPage, ContentPageDataRaw, validateContentPageSchema, } from "./output" import { fetchContentPageRefs, generatePageTags, getContentPageCounter, makeButtonObject, validateContentPageRefs, } from "./utils" import { CardsGridEnum, ContentBlocksTypenameEnum, } from "@/types/components/content/enums" import { TrackingChannelEnum, TrackingSDKPageData, } from "@/types/components/tracking" export const contentPageQueryRouter = router({ get: contentstackExtendedProcedureUID.query(async ({ ctx }) => { const { lang, uid } = ctx const cleanedRefsData = await fetchContentPageRefs(lang, uid) const validatedRefsData = validateContentPageRefs( cleanedRefsData, lang, uid ) const tags = generatePageTags(validatedRefsData, lang) getContentPageCounter.add(1, { lang, uid }) console.info( "contentstack.contentPage start", JSON.stringify({ query: { lang, uid }, }) ) const response = await request( GetContentPage, { locale: lang, uid }, { cache: "force-cache", next: { tags, }, } ) const { content_page } = removeEmptyObjects(response.data) if (!content_page) { throw notFound(response) } const processedBlocks = content_page.blocks ? content_page.blocks.map((block: any) => { switch (block.__typename) { case ContentBlocksTypenameEnum.ContentPageBlocksContent: return block case ContentBlocksTypenameEnum.ContentPageBlocksShortcuts: 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 || removeMultipleSlashes( `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}` ), })), }, } case ContentBlocksTypenameEnum.ContentPageBlocksCardsGrid: return { ...block, cards_grid: { ...block.cards_grid, cards: block.cards_grid.cardConnection.edges.map( ({ node: card }: { node: any }) => { switch (card.__typename) { case CardsGridEnum.Card: return { ...card, backgroundImage: makeImageVaultImage( card.background_image ), primaryButton: card.has_primary_button ? makeButtonObject(card.primary_button) : undefined, secondaryButton: card.has_secondary_button ? makeButtonObject(card.secondary_button) : undefined, } case CardsGridEnum.LoyaltyCard: return { ...card, image: makeImageVaultImage(card.image), link: makeButtonObject(card.link), } } } ), }, } default: return block } }) : null const heroImage = makeImageVaultImage(content_page.hero_image) const validatedContentPage = validateContentPageSchema.safeParse({ content_page: { ...content_page, blocks: processedBlocks, hero_image: heroImage, }, }) if (!validatedContentPage.success) { console.error( `Failed to validate Contentpage Data - (lang: ${lang}, uid: ${uid})` ) console.error(validatedContentPage.error?.format()) return null } const { hero_image, blocks, ...restContentPage } = validatedContentPage.data.content_page const contentPage: ContentPage = { ...restContentPage, heroImage, blocks: blocks as Block[], } const tracking: TrackingSDKPageData = { pageId: contentPage.system.uid, lang: contentPage.system.locale as Lang, publishedDate: contentPage.system.updated_at, createdDate: contentPage.system.created_at, channel: TrackingChannelEnum["static-content-page"], pageType: "staticcontentpage", } return { contentPage, tracking, } }), })