import { GetLoyaltyPage, GetLoyaltyPageRefs, } from "@/lib/graphql/Query/LoyaltyPage.graphql" import { request } from "@/lib/graphql/request" import { _ } from "@/lib/translation" import { badRequestError, internalServerError } from "@/server/errors/trpc" import { publicProcedure, router } from "@/server/trpc" import { generateRefsResponseTag, generateTag, generateTags, } from "@/utils/generateTag" import { removeEmptyObjects } from "../../utils" import { getLoyaltyPageInput } from "./input" import { type LoyaltyPage, type LoyaltyPageDataRaw, type LoyaltyPageRefsDataRaw, validateLoyaltyPageRefsSchema, validateLoyaltyPageSchema, } from "./output" import { getConnections } from "./utils" import { LoyaltyBlocksTypenameEnum, SidebarTypenameEnum, } from "@/types/components/loyalty/enums" import { Embeds } from "@/types/requests/embeds" import { Edges } from "@/types/requests/utils/edges" import { RTEDocument } from "@/types/rte/node" export const loyaltyPageQueryRouter = router({ get: publicProcedure.input(getLoyaltyPageInput).query(async ({ input }) => { try { const { locale } = input const refsResponse = await request( GetLoyaltyPageRefs, { locale, url: input.href, }, { next: { tags: [generateRefsResponseTag(locale, "loyalty_page")], }, } ) if (!refsResponse.data) { console.error("Bad response for `GetLoyaltyPageRefs`") console.error({ refsResponse }) throw internalServerError() } // 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 badRequestError() } const connections = getConnections(validatedLoyaltyPageRefs.data) const tags = generateTags(locale, connections) tags.push( generateTag( locale, validatedLoyaltyPageRefs.data.all_loyalty_page.items[0].system.uid ) ) const loyaltyPageRes = await request( GetLoyaltyPage, { locale, url: input.href, }, { next: { tags } } ) if (!loyaltyPageRes.data) { throw badRequestError() } const validatedLoyaltyPage = validateLoyaltyPageSchema.safeParse( loyaltyPageRes.data ) if (!validatedLoyaltyPage.success) { console.error("Bad validation for `validatedLoyaltyPage`") console.error(validatedLoyaltyPage.error) throw badRequestError() } const sidebar = validatedLoyaltyPage.data.all_loyalty_page.items[0] .sidebar ? validatedLoyaltyPage.data.all_loyalty_page.items[0].sidebar.map( (block) => { if ( block.__typename == SidebarTypenameEnum.LoyaltyPageSidebarContent ) { return { ...block, content: { content: { json: block.content.content.json as RTEDocument, embedded_itemsConnection: block.content.content .embedded_itemsConnection as Edges, }, }, } } else { return block } } ) : null const blocks = validatedLoyaltyPage.data.all_loyalty_page.items[0].blocks ? validatedLoyaltyPage.data.all_loyalty_page.items[0].blocks.map( (block) => { switch (block.__typename) { case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardGrid: return { ...block, card_grid: { ...block.card_grid, cards: block.card_grid.cards.map((card) => { return { ...card, link: card.referenceConnection.totalCount ? { href: `/${card.referenceConnection.edges[0].node.system.locale}${card.referenceConnection.edges[0].node.url}`, title: card.cta_text || _("Read more"), } : undefined, } }), }, } case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent: return { ...block, dynamic_content: { ...block.dynamic_content, link: block.dynamic_content.link.pageConnection.totalCount ? { 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.LoyaltyPageBlocksContent: return { ...block, content: { content: { json: block.content.content.json as RTEDocument, embedded_itemsConnection: block.content.content .embedded_itemsConnection as Edges, }, }, } case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: return { ...block, shortcuts: { ...block.shortcuts, shortcuts: block.shortcuts.shortcuts.map((shortcut) => ({ 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}`, })), }, } default: return block } } ) : null const loyaltyPage = { ...validatedLoyaltyPage.data.all_loyalty_page.items[0], blocks, sidebar, } as LoyaltyPage return loyaltyPage } catch (error) { console.info(`Get Loyalty Page Error`) console.error(error) throw badRequestError() } }), })