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 { validateContentPageSchema } from "./output" import { fetchContentPageRefs, generatePageTags, getContentPageCounter, makeButtonObject, validateContentPageRefs, } from "./utils" import { CardsGridEnum, ContentBlocksTypenameEnum, SidebarTypenameEnum, } from "@/types/components/content/enums" import { TrackingChannelEnum, TrackingSDKPageData, } from "@/types/components/tracking" import { Block, ContentPage, ContentPageDataRaw, Sidebar, } from "@/types/trpc/routers/contentstack/contentPage" 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, isContentCard: !!card.is_content_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, sidePeekButton: card.has_sidepeek_button || !!card.sidepeek_button?.call_to_action_text ? { title: card.sidepeek_button.call_to_action_text, } : undefined, } case CardsGridEnum.LoyaltyCard: return { ...card, image: makeImageVaultImage(card.image), link: makeButtonObject(card.link), } } } ), }, } case ContentBlocksTypenameEnum.ContentPageBlocksDynamicContent: return { ...block, dynamic_content: { ...block.dynamic_content, link: block.dynamic_content.link.pageConnection.edges.length ? { text: block.dynamic_content.link.text, href: removeMultipleSlashes( `/${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, }, } default: return block } }) : null const sidebar = response.data.content_page.sidebar ? response.data.content_page.sidebar.map((item: any) => { switch (item.__typename) { case SidebarTypenameEnum.ContentPageSidebarJoinLoyaltyContact: return { ...item, join_loyalty_contact: { ...item.join_loyalty_contact, button: makeButtonObject(item.join_loyalty_contact.button), }, } default: return item } }) : null const heroImage = makeImageVaultImage(content_page.hero_image) const validatedContentPage = validateContentPageSchema.safeParse({ content_page: { ...content_page, blocks: processedBlocks, sidebar, 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[], sidebar: sidebar as Sidebar[], } 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, } }), })