diff --git a/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx b/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx index 2348065ea..34bca6746 100644 --- a/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx +++ b/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx @@ -8,6 +8,8 @@ import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { getPromoCampaignPage } from "@/lib/trpc/memoizedRequests" +import Blocks from "@/components/Blocks" + import ExpiredPromoCampaign from "./ExpiredPromoCampaign" import PromoCampaignHero from "./Hero" import PromoCampaignPageSkeleton from "./PromoCampaignPageSkeleton" @@ -26,7 +28,7 @@ export default async function PromoCampaignPage() { } const { promo_campaign_page, tracking } = pageData - const { heading, subheading, enddate, promo_hero, eligibleLevels } = + const { heading, subheading, enddate, promo_hero, blocks, eligibleLevels } = promo_campaign_page const isCampaignExpired = enddate @@ -44,6 +46,7 @@ export default async function PromoCampaignPage() { subheading={subheading} promoHero={promo_hero} eligibleLevels={eligibleLevels} + blocks={blocks} /> )} @@ -57,11 +60,13 @@ function ActiveCampaignLayout({ subheading, promoHero, eligibleLevels, + blocks, }: { heading: PromoCampaignPageData["heading"] subheading: PromoCampaignPageData["subheading"] promoHero: PromoHero eligibleLevels: PromoCampaignPageData["eligibleLevels"] + blocks: PromoCampaignPageData["blocks"] }) { return (
@@ -81,6 +86,7 @@ function ActiveCampaignLayout({ ) : null}
+ {blocks ? : null} ) } diff --git a/apps/scandic-web/types/components/blocks/index.ts b/apps/scandic-web/types/components/blocks/index.ts index 976348abb..2c8925765 100644 --- a/apps/scandic-web/types/components/blocks/index.ts +++ b/apps/scandic-web/types/components/blocks/index.ts @@ -8,6 +8,7 @@ import type { Block as DestinationCityPageBlock } from "@scandic-hotels/trpc/typ import type { Block as DestinationCountryPageBlock } from "@scandic-hotels/trpc/types/destinationCountryPage" import type { Block as DestinationOverviewPageBlock } from "@scandic-hotels/trpc/types/destinationOverviewPage" import type { Block as LoyaltyPageBlock } from "@scandic-hotels/trpc/types/loyaltyPage" +import type { Block as PromoCampaignPageBlock } from "@scandic-hotels/trpc/types/promoCampaignPage" type Blocks = | AccountPageBlock @@ -20,6 +21,7 @@ type Blocks = | DestinationOverviewPageBlock | LoyaltyPageBlock | StartPageBlock + | PromoCampaignPageBlock export interface BlocksProps { blocks: Blocks[] diff --git a/packages/trpc/lib/graphql/Fragments/Blocks/Accordion.graphql b/packages/trpc/lib/graphql/Fragments/Blocks/Accordion.graphql index 0a2a6a34e..552c6b931 100644 --- a/packages/trpc/lib/graphql/Fragments/Blocks/Accordion.graphql +++ b/packages/trpc/lib/graphql/Fragments/Blocks/Accordion.graphql @@ -714,3 +714,107 @@ fragment SpecificAccordion_DestinationFilterBlocksRefs on DestinationFilterBlock } } } + +fragment Accordion_PromoCampaignPage on PromoCampaignPageBlocksAccordion { + __typename + accordion { + accordions { + __typename + ...GlobalAccordion_PromoCampaignPage + ...SpecificAccordion_PromoCampaignPage + } + } +} + +fragment GlobalAccordion_PromoCampaignPage on PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion { + __typename + global_accordion { + global_accordionConnection { + edges { + node { + ...AccordionBlock + } + } + } + } +} + +fragment SpecificAccordion_PromoCampaignPage on PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion { + __typename + specific_accordion { + questions { + question + answer { + json + embedded_itemsConnection { + edges { + node { + __typename + ...SysAsset + ...AccountPageLink + ...CampaignOverviewPageLink + ...CampaignPageLink + ...CollectionPageLink + ...ContentPageLink + ...DestinationCityPageLink + ...DestinationCountryPageLink + ...DestinationOverviewPageLink + ...HotelPageLink + ...LoyaltyPageLink + ...StartPageLink + } + } + } + } + } + } +} + +fragment Accordion_PromoCampaignPageRefs on PromoCampaignPageBlocksAccordion { + accordion { + accordions { + __typename + ...GlobalAccordion_PromoCampaignPageRefs + ...SpecificAccordion_PromoCampaignPageRefs + } + } +} + +fragment GlobalAccordion_PromoCampaignPageRefs on PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion { + global_accordion { + global_accordionConnection { + edges { + node { + ...AccordionBlockRefs + } + } + } + } +} + +fragment SpecificAccordion_PromoCampaignPageRefs on PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion { + specific_accordion { + questions { + answer { + embedded_itemsConnection { + edges { + node { + __typename + ...AccountPageRef + ...CampaignOverviewPageRef + ...CampaignPageRef + ...CollectionPageRef + ...ContentPageRef + ...DestinationCityPageRef + ...DestinationCountryPageRef + ...DestinationOverviewPageRef + ...HotelPageRef + ...LoyaltyPageRef + ...StartPageRef + } + } + } + } + } + } +} diff --git a/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql b/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql index 1276590d2..87545732f 100644 --- a/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql +++ b/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql @@ -284,3 +284,48 @@ fragment Content_DestinationFilterBlocksRefs on DestinationFilterBlocksContent { } } } + +fragment Content_PromoCampaign on PromoCampaignPageBlocksContent { + content { + content { + embedded_itemsConnection { + edges { + node { + __typename + ...AccountPageLink + ...CampaignOverviewPageLink + ...CampaignPageLink + ...CollectionPageLink + ...ContentPageLink + ...HotelPageLink + ...LoyaltyPageLink + ...StartPageLink + } + } + } + json + } + } +} + +fragment Content_PromoCampaignRefs on PromoCampaignPageBlocksContent { + content { + content { + embedded_itemsConnection { + edges { + node { + __typename + ...AccountPageRef + ...CampaignOverviewPageRef + ...CampaignPageRef + ...CollectionPageRef + ...ContentPageRef + ...HotelPageRef + ...LoyaltyPageRef + ...StartPageRef + } + } + } + } + } +} diff --git a/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql b/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql index debe92057..7f20a0a86 100644 --- a/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql +++ b/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql @@ -1,12 +1,7 @@ #import "../../Fragments/System.graphql" -#import "../../Fragments/CampaignPage/IncludedHotels.graphql" -#import "../../Fragments/CampaignPage/Hero.graphql" - #import "../../Fragments/Blocks/Accordion.graphql" -#import "../../Fragments/Blocks/Essentials.graphql" -#import "../../Fragments/Blocks/CarouselCards.graphql" -#import "../../Fragments/Blocks/HotelListing.graphql" +#import "../../Fragments/Blocks/Content.graphql" query GetPromoCampaignPage($locale: String!, $uid: String!) { promo_campaign_page(uid: $uid, locale: $locale) { @@ -26,6 +21,10 @@ query GetPromoCampaignPage($locale: String!, $uid: String!) { startdate enddate level_selection + blocks { + __typename + ...Accordion_PromoCampaignPage + } system { ...System created_at @@ -39,6 +38,10 @@ query GetPromoCampaignPage($locale: String!, $uid: String!) { query GetPromoCampaignPageRefs($locale: String!, $uid: String!) { promo_campaign_page(locale: $locale, uid: $uid) { + blocks { + __typename + ...Accordion_PromoCampaignPageRefs + } system { ...System } diff --git a/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts b/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts index 4654851cd..08dfcd6bb 100644 --- a/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts @@ -4,8 +4,35 @@ import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/i import { isMembershipLevel } from "@scandic-hotels/common/utils/membershipLevels" import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator" +import { PromoCampaignPageEnum } from "../../../types/promoCampaignPage" +import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" +import { + accordionRefsSchema, + accordionSchema, +} from "../schemas/blocks/accordion" +import { + //contentRefsSchema as blockContentRefsSchema, + contentSchema as blockContentSchema, +} from "../schemas/blocks/content" import { systemSchema } from "../schemas/system" +export const promoCampaignPageContent = z + .object({ + __typename: z.literal(PromoCampaignPageEnum.ContentStack.blocks.Content), + }) + .merge(blockContentSchema) + +export const promoCampaignPageAccordion = z + .object({ + __typename: z.literal(PromoCampaignPageEnum.ContentStack.blocks.Accordion), + }) + .merge(accordionSchema) + +export const blocksSchema = z.discriminatedUnion("__typename", [ + promoCampaignPageAccordion, + //promoCampaignPageContent, +]) + export const CAMPAIGN_TYPES = { TIER: "TIER", POINT: "POINT", @@ -43,6 +70,7 @@ export const promoCampaignPageSchema = z if (!data) return [] return data.filter(isMembershipLevel) }), + blocks: discriminatedUnionArray(blocksSchema.options).nullish(), system: systemSchema.merge( z.object({ created_at: z.string(), @@ -70,8 +98,28 @@ export const promoCampaignPageSchema = z }) /** REFS */ +/*const promoCampaignPageBlockContentRefs = z + .object({ + __typename: z.literal(PromoCampaignPageEnum.ContentStack.blocks.Content), + }) + .merge(blockContentRefsSchema)*/ + +const promoCampaignPageAccordionRefs = z + .object({ + __typename: z.literal(PromoCampaignPageEnum.ContentStack.blocks.Accordion), + }) + .merge(accordionRefsSchema) + +const promoCampaignPageBlockRefsItem = z.discriminatedUnion("__typename", [ + promoCampaignPageAccordionRefs, + //promoCampaignPageBlockContentRefs, +]) + export const promoCampaignPageRefsSchema = z.object({ promo_campaign_page: z.object({ + blocks: discriminatedUnionArray( + promoCampaignPageBlockRefsItem.options + ).nullable(), system: systemSchema, }), }) diff --git a/packages/trpc/lib/routers/contentstack/promoCampaignPage/utils.ts b/packages/trpc/lib/routers/contentstack/promoCampaignPage/utils.ts index 9384b523c..39d2e7081 100644 --- a/packages/trpc/lib/routers/contentstack/promoCampaignPage/utils.ts +++ b/packages/trpc/lib/routers/contentstack/promoCampaignPage/utils.ts @@ -1,8 +1,11 @@ +import { + PromoCampaignPageEnum, + type PromoCampaignPageRefs, +} from "../../../types/promoCampaignPage" import { generateTag, generateTagsFromSystem } from "../../../utils/generateTag" import type { Lang } from "@scandic-hotels/common/constants/language" -import type { PromoCampaignPageRefs } from "../../../types/promoCampaignPage" import type { System } from "../schemas/system" export function generatePageTags( @@ -19,5 +22,24 @@ export function generatePageTags( export function getConnections({ promo_campaign_page }: PromoCampaignPageRefs) { const connections: System["system"][] = [promo_campaign_page.system] + if (promo_campaign_page.blocks) { + promo_campaign_page.blocks.forEach((block) => { + switch (block.__typename) { + case PromoCampaignPageEnum.ContentStack.blocks.Accordion: { + if (block.accordion.length) { + connections.push(...block.accordion) + } + break + } + /*case PromoCampaignPageEnum.ContentStack.blocks.Content: + { + if (block.content.length) { + connections.push(...block.content) + } + } + break*/ + } + }) + } return connections } diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/accordion.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/accordion.ts index 6a8e650d9..a09691195 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/accordion.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/accordion.ts @@ -47,6 +47,8 @@ enum AccordionEnum { DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion", DestinationFilterBlocksAccordionBlockAccordionsSpecificAccordion = "DestinationFilterBlocksAccordionBlockAccordionsSpecificAccordion", DestinationFilterBlocksAccordionBlockAccordionsGlobalAccordion = "DestinationFilterBlocksAccordionBlockAccordionsGlobalAccordion", + PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion = "PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion", + PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion = "PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion", } export const accordionSchema = z.object({ @@ -92,6 +94,7 @@ export const accordionSchema = z.object({ case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion: case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion: case AccordionEnum.DestinationFilterBlocksAccordionBlockAccordionsGlobalAccordion: + case AccordionEnum.PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion: return ( acc.global_accordion?.global_accordionConnection.edges.flatMap( ({ node: accordionConnection }) => { @@ -105,6 +108,7 @@ export const accordionSchema = z.object({ case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion: case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion: case AccordionEnum.DestinationFilterBlocksAccordionBlockAccordionsSpecificAccordion: + case AccordionEnum.PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion: return acc.specific_accordion?.questions || [] default: return null @@ -175,6 +179,7 @@ export const accordionRefsSchema = z.object({ case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsGlobalAccordion: case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsGlobalAccordion: case AccordionEnum.DestinationFilterBlocksAccordionBlockAccordionsGlobalAccordion: + case AccordionEnum.PromoCampaignPageBlocksAccordionBlockAccordionsGlobalAccordion: return ( accordion.global_accordion?.global_accordionConnection.edges.flatMap( ({ node: accordionConnection }) => { @@ -190,6 +195,7 @@ export const accordionRefsSchema = z.object({ case AccordionEnum.DestinationCityPageBlocksAccordionBlockAccordionsSpecificAccordion: case AccordionEnum.DestinationCountryPageBlocksAccordionBlockAccordionsSpecificAccordion: case AccordionEnum.DestinationFilterBlocksAccordionBlockAccordionsSpecificAccordion: + case AccordionEnum.PromoCampaignPageBlocksAccordionBlockAccordionsSpecificAccordion: return ( accordion.specific_accordion?.questions.flatMap((question) => question.answer.embedded_itemsConnection.edges.flatMap( diff --git a/packages/trpc/lib/types/promoCampaignPage.ts b/packages/trpc/lib/types/promoCampaignPage.ts index c7157f217..c73f26f16 100644 --- a/packages/trpc/lib/types/promoCampaignPage.ts +++ b/packages/trpc/lib/types/promoCampaignPage.ts @@ -1,6 +1,7 @@ import type { z } from "zod" import type { + blocksSchema, promoCampaignPageRefsSchema, promoCampaignPageSchema, } from "../routers/contentstack/promoCampaignPage/output" @@ -9,10 +10,13 @@ export namespace PromoCampaignPageEnum { export namespace ContentStack { export const enum blocks { Accordion = "PromoCampaignPageBlocksAccordion", + Content = "PromoCampaignPageBlocksContent", } } } +export type Block = z.output + export interface GetPromoCampaignPageData extends z.input {}