diff --git a/components/Blocks/CarouselCards/index.tsx b/components/Blocks/CarouselCards/index.tsx index 034381673..459169958 100644 --- a/components/Blocks/CarouselCards/index.tsx +++ b/components/Blocks/CarouselCards/index.tsx @@ -17,9 +17,9 @@ export default function CarouselCards({ carousel_cards }: CarouselCardsProps) { const { heading, enableFilters, + defaultFilter, filterCategories, cards, - defaultFilter, link, } = carousel_cards diff --git a/components/ContentType/DestinationOverviewPage/HotelsSection/hotelsSection.module.css b/components/ContentType/DestinationOverviewPage/HotelsSection/hotelsSection.module.css index 90e7767c1..e12c4ff92 100644 --- a/components/ContentType/DestinationOverviewPage/HotelsSection/hotelsSection.module.css +++ b/components/ContentType/DestinationOverviewPage/HotelsSection/hotelsSection.module.css @@ -1,12 +1,11 @@ .container { display: grid; gap: var(--Spacing-x4); - padding: var(--Spacing-x5) var(--Spacing-x2) var(--Spacing-x7); + padding: var(--Spacing-x5) 0 var(--Spacing-x7); } @media screen and (min-width: 768px) { .container { gap: var(--Spacing-x7); - padding: var(--Spacing-x5) 9.625rem var(--Spacing-x9) 9.625rem; } } diff --git a/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css b/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css index 7d9f620b6..7dd5c6da3 100644 --- a/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css +++ b/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css @@ -1,12 +1,28 @@ -.pageContainer { +.mapContainer { position: relative; display: grid; width: 100%; max-width: var(--max-width); + margin: 0 auto; } -@media screen and (min-width: 768px) { - .pageContainer { - margin: 0 auto; - } +.main { + display: grid; + gap: var(--Spacing-x9); + padding: var(--Spacing-x7) 0 var(--Spacing-x9); + background-color: var(--Base-Surface-Primary-light-Normal); +} + +.blocks { + display: grid; + gap: var(--Spacing-x9); + width: 100%; + max-width: var(--max-width-content); + margin: 0 auto; +} + +.hotelsAccordions { + width: 100%; + max-width: var(--max-width-content); + margin: 0 auto; } diff --git a/components/ContentType/DestinationOverviewPage/index.tsx b/components/ContentType/DestinationOverviewPage/index.tsx index 9ba454b1c..851c4a800 100644 --- a/components/ContentType/DestinationOverviewPage/index.tsx +++ b/components/ContentType/DestinationOverviewPage/index.tsx @@ -6,6 +6,7 @@ import { getDestinationsList, } from "@/lib/trpc/memoizedRequests" +import Blocks from "@/components/Blocks" import TrackingSDK from "@/components/TrackingSDK" import HotelsSection from "./HotelsSection" @@ -30,12 +31,21 @@ export default async function DestinationOverviewPage() { return ( <> -
- {googleMapsApiKey ? ( + {googleMapsApiKey ? ( +
- ) : null} - {destinationsData && } -
+
+ ) : null} +
+
+ +
+
+ {destinationsData && ( + + )} diff --git a/lib/graphql/Fragments/Blocks/CarouselCards.graphql b/lib/graphql/Fragments/Blocks/CarouselCards.graphql index 24fd31a6e..f2ee33806 100644 --- a/lib/graphql/Fragments/Blocks/CarouselCards.graphql +++ b/lib/graphql/Fragments/Blocks/CarouselCards.graphql @@ -24,10 +24,8 @@ fragment CarouselCards_StartPage on StartPageBlocksCarouselCards { heading enable_filters card_groups { - filter_category { - filter_identifier - filter_label - } + filter_label + filter_identifier cardConnection { edges { node { @@ -93,3 +91,76 @@ fragment CarouselCards_StartPageRefs on StartPageBlocksCarouselCards { } } } + +fragment CarouselCards_DestinationOverviewPage on DestinationOverviewPageBlocksCarouselCards { + carousel_cards { + heading + enable_filters + card_groups { + filter_identifier + filter_label + cardConnection { + edges { + node { + ...ContentCardBlock + } + } + } + } + link { + cta_text + is_contentstack_link + open_in_new_tab + external_link { + href + title + } + linkConnection { + edges { + node { + __typename + ...AccountPageLink + ...CollectionPageLink + ...ContentPageLink + ...DestinationCityPageLink + ...DestinationCountryPageLink + ...DestinationOverviewPageLink + ...HotelPageLink + ...LoyaltyPageLink + } + } + } + } + } +} + +fragment CarouselCards_DestinationOverviewPageRefs on DestinationOverviewPageBlocksCarouselCards { + carousel_cards { + card_groups { + cardConnection { + edges { + node { + ...ContentCardBlockRef + } + } + } + } + link { + linkConnection { + edges { + node { + __typename + ...AccountPageRef + ...CollectionPageRef + ...ContentPageRef + ...DestinationCityPageRef + ...DestinationCountryPageRef + ...DestinationOverviewPageRef + ...HotelPageRef + ...LoyaltyPageRef + } + } + } + } + } +} diff --git a/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql b/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql index c1e66703c..f81b58f1d 100644 --- a/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql +++ b/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql @@ -1,9 +1,15 @@ #import "../../Fragments/System.graphql" +#import "../../Fragments/Blocks/CarouselCards.graphql" + query GetDestinationOverviewPage($locale: String!, $uid: String!) { destination_overview_page(uid: $uid, locale: $locale) { title url + blocks { + __typename + ...CarouselCards_DestinationOverviewPage + } system { ...System created_at @@ -17,6 +23,10 @@ query GetDestinationOverviewPage($locale: String!, $uid: String!) { query GetDestinationOverviewPageRefs($locale: String!, $uid: String!) { destination_overview_page(locale: $locale, uid: $uid) { + blocks { + __typename + ...CarouselCards_DestinationOverviewPageRefs + } system { ...System } diff --git a/server/routers/contentstack/destinationOverviewPage/output.ts b/server/routers/contentstack/destinationOverviewPage/output.ts index 9bd481bdb..8d4c6e9a4 100644 --- a/server/routers/contentstack/destinationOverviewPage/output.ts +++ b/server/routers/contentstack/destinationOverviewPage/output.ts @@ -1,12 +1,33 @@ import { z } from "zod" +import { discriminatedUnionArray } from "@/lib/discriminatedUnion" + import { removeMultipleSlashes } from "@/utils/url" +import { + carouselCardsRefsSchema, + carouselCardsSchema, +} from "../schemas/blocks/carouselCards" import { systemSchema } from "../schemas/system" +import { DestinationOverviewPageEnum } from "@/types/enums/destinationOverviewPage" + +const destinationOverviewPageCarouselCards = z + .object({ + __typename: z.literal( + DestinationOverviewPageEnum.ContentStack.blocks.CarouselCards + ), + }) + .merge(carouselCardsSchema) + +export const blocksSchema = z.discriminatedUnion("__typename", [ + destinationOverviewPageCarouselCards, +]) + export const destinationOverviewPageSchema = z.object({ destination_overview_page: z.object({ title: z.string(), + blocks: discriminatedUnionArray(blocksSchema.options), system: systemSchema.merge( z.object({ created_at: z.string(), @@ -41,8 +62,21 @@ export const countryPageUrlSchema = z ) /** REFS */ +const destinationOverviewPageCarouselCardsRef = z + .object({ + __typename: z.literal( + DestinationOverviewPageEnum.ContentStack.blocks.CarouselCards + ), + }) + .merge(carouselCardsRefsSchema) + +const blocksRefsSchema = z.discriminatedUnion("__typename", [ + destinationOverviewPageCarouselCardsRef, +]) + export const destinationOverviewPageRefsSchema = z.object({ destination_overview_page: z.object({ + blocks: discriminatedUnionArray(blocksRefsSchema.options).nullable(), system: systemSchema, }), }) diff --git a/server/routers/contentstack/schemas/blocks/carouselCards.ts b/server/routers/contentstack/schemas/blocks/carouselCards.ts index 56c7f6a40..35d6a2365 100644 --- a/server/routers/contentstack/schemas/blocks/carouselCards.ts +++ b/server/routers/contentstack/schemas/blocks/carouselCards.ts @@ -24,10 +24,8 @@ const carouselCardsWithFilters = z.object({ enable_filters: z.literal(true), card_groups: z.array( z.object({ - filter_category: z.object({ - filter_identifier: z.nativeEnum(CarouselCardFilterEnum), - filter_label: z.string(), - }), + filter_identifier: z.nativeEnum(CarouselCardFilterEnum), + filter_label: z.string(), cardConnection: z.object({ edges: z.array(z.object({ node: contentCardSchema })), }), @@ -40,10 +38,8 @@ const carouselCardsWithoutFilters = z.object({ enable_filters: z.literal(false), card_groups: z.array( z.object({ - filter_category: z.object({ - filter_identifier: z.null(), - filter_label: z.string(), - }), + filter_identifier: z.null(), + filter_label: z.string(), cardConnection: z.object({ edges: z.array(z.object({ node: contentCardSchema })), }), @@ -74,7 +70,6 @@ export const carouselCardsSchema = z.object({ ) ) .filter((card): card is NonNullable => card !== null), - defaultFilter: null, link: data.link ? { href: data.link.href, text: data.link.title } : undefined, @@ -87,11 +82,11 @@ export const carouselCardsSchema = z.object({ label: string }> >((acc, group) => { - const identifier = group.filter_category.filter_identifier + const identifier = group.filter_identifier if (!acc.some((category) => category.identifier === identifier)) { acc.push({ identifier, - label: group.filter_category.filter_label, + label: group.filter_label, }) } return acc @@ -107,11 +102,11 @@ export const carouselCardsSchema = z.object({ .filter((card): card is NonNullable => card !== null) .map((card) => ({ ...card, - filterId: group.filter_category.filter_identifier, + filterId: group.filter_identifier, })) ), defaultFilter: - data.card_groups[0]?.filter_category.filter_identifier ?? + data.card_groups[0]?.filter_identifier ?? filterCategories[0]?.identifier, link: data.link ? { href: data.link.href, text: data.link.title } diff --git a/types/components/blocks/index.ts b/types/components/blocks/index.ts index aaab9569c..1c1e4ad17 100644 --- a/types/components/blocks/index.ts +++ b/types/components/blocks/index.ts @@ -3,6 +3,7 @@ import type { Block as CollectionPageBlock } from "@/types/trpc/routers/contents import type { Block as ContentPageBlock } from "@/types/trpc/routers/contentstack/contentPage" import type { Block as DestinationCityPageBlock } from "@/types/trpc/routers/contentstack/destinationCityPage" import type { Block as DestinationCountryPageBlock } from "@/types/trpc/routers/contentstack/destinationCountryPage" +import type { Block as DestinationOverviewPageBlock } from "@/types/trpc/routers/contentstack/destinationOverviewPage" import type { Block as LoyaltyPageBlock } from "@/types/trpc/routers/contentstack/loyaltyPage" import type { Block as StartPageBlock } from "@/types/trpc/routers/contentstack/startPage" @@ -12,6 +13,7 @@ export type Blocks = | ContentPageBlock | DestinationCityPageBlock | DestinationCountryPageBlock + | DestinationOverviewPageBlock | LoyaltyPageBlock | StartPageBlock diff --git a/types/enums/destinationOverviewPage.ts b/types/enums/destinationOverviewPage.ts new file mode 100644 index 000000000..304028a88 --- /dev/null +++ b/types/enums/destinationOverviewPage.ts @@ -0,0 +1,7 @@ +export namespace DestinationOverviewPageEnum { + export namespace ContentStack { + export const enum blocks { + CarouselCards = "DestinationOverviewPageBlocksCarouselCards", + } + } +} diff --git a/types/trpc/routers/contentstack/destinationOverviewPage.ts b/types/trpc/routers/contentstack/destinationOverviewPage.ts index 41d9818cd..6efe0b581 100644 --- a/types/trpc/routers/contentstack/destinationOverviewPage.ts +++ b/types/trpc/routers/contentstack/destinationOverviewPage.ts @@ -1,6 +1,7 @@ import type { z } from "zod" import type { + blocksSchema, countryPageUrlSchema, destinationOverviewPageRefsSchema, destinationOverviewPageSchema, @@ -19,3 +20,5 @@ export interface DestinationOverviewPageRefs export interface GetCountryPageUrlData extends z.input {} + +export type Block = z.output