diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index 476a423a4..974ea7735 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -5,6 +5,7 @@ import { isSignupPage } from "@/constants/routes/signup" import { env } from "@/env/server" import { getHotelPage } from "@/lib/trpc/memoizedRequests" +import DestinationOverviewPage from "@/components/ContentType/DestinationOverviewPage" import HotelPage from "@/components/ContentType/HotelPage" import LoyaltyPage from "@/components/ContentType/LoyaltyPage" import CollectionPage from "@/components/ContentType/StaticPages/CollectionPage" @@ -55,6 +56,8 @@ export default async function ContentTypePage({ } case PageContentTypeEnum.loyaltyPage: return + case PageContentTypeEnum.destinationOverviewPage: + return case PageContentTypeEnum.hotelPage: if (env.HIDE_FOR_NEXT_RELEASE) { return notFound() diff --git a/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css b/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css new file mode 100644 index 000000000..c58807d98 --- /dev/null +++ b/components/ContentType/DestinationOverviewPage/destinationOverviewPage.module.css @@ -0,0 +1,10 @@ +.pageContainer { + display: grid; + max-width: var(--max-width); +} + +@media screen and (min-width: 768px) { + .pageContainer { + margin: 0 auto; + } +} diff --git a/components/ContentType/DestinationOverviewPage/index.tsx b/components/ContentType/DestinationOverviewPage/index.tsx new file mode 100644 index 000000000..db5406452 --- /dev/null +++ b/components/ContentType/DestinationOverviewPage/index.tsx @@ -0,0 +1,28 @@ +import { Suspense } from "react" + +import { getDestinationOverviewPage } from "@/lib/trpc/memoizedRequests" + +import TrackingSDK from "@/components/TrackingSDK" + +import styles from "./destinationOverviewPage.module.css" + +export default async function DestinationOverviewPage() { + const pageData = await getDestinationOverviewPage() + + if (!pageData) { + return null + } + + const { tracking, destinationOverviewPage } = pageData + + return ( + <> +
+

Destination Overview Page

+
+ + + + + ) +} diff --git a/components/TempDesignSystem/Breadcrumbs/variants.ts b/components/TempDesignSystem/Breadcrumbs/variants.ts index 826a1d3b7..28ff76517 100644 --- a/components/TempDesignSystem/Breadcrumbs/variants.ts +++ b/components/TempDesignSystem/Breadcrumbs/variants.ts @@ -10,6 +10,7 @@ export const breadcrumbsVariants = cva(styles.breadcrumbs, { [PageContentTypeEnum.accountPage]: styles.fullWidth, [PageContentTypeEnum.contentPage]: styles.contentWidth, [PageContentTypeEnum.collectionPage]: styles.contentWidth, + [PageContentTypeEnum.destinationOverviewPage]: styles.contentWidth, [PageContentTypeEnum.hotelPage]: styles.hotelHeaderWidth, [PageContentTypeEnum.loyaltyPage]: styles.fullWidth, default: styles.fullWidth, diff --git a/lib/graphql/Query/BookingWidgetToggle.graphql b/lib/graphql/Query/BookingWidgetToggle.graphql index 017f07f9d..412e0a5cc 100644 --- a/lib/graphql/Query/BookingWidgetToggle.graphql +++ b/lib/graphql/Query/BookingWidgetToggle.graphql @@ -29,6 +29,13 @@ query GetContentPageSettings($uid: String!, $locale: String!) { } } } +query GetDestinationOverviewPageSettings($uid: String!, $locale: String!) { + destination_overview_page(uid: $uid, locale: $locale) { + page_settings { + hide_booking_widget + } + } +} query GetHotelPageSettings($uid: String!, $locale: String!) { hotel_page(uid: $uid, locale: $locale) { diff --git a/lib/graphql/Query/Breadcrumbs/DestinationOverviewPage.graphql b/lib/graphql/Query/Breadcrumbs/DestinationOverviewPage.graphql new file mode 100644 index 000000000..f00d1c992 --- /dev/null +++ b/lib/graphql/Query/Breadcrumbs/DestinationOverviewPage.graphql @@ -0,0 +1,31 @@ +#import "../../Fragments/Breadcrumbs/Breadcrumbs.graphql" +#import "../../Fragments/System.graphql" + +query GetDestinationOverviewPageBreadcrumbs($locale: String!, $uid: String!) { + destination_overview_page(locale: $locale, uid: $uid) { + web { + breadcrumbs { + ...Breadcrumbs + } + } + system { + ...System + } + } +} + +query GetDestinationOverviewPageBreadcrumbsRefs( + $locale: String! + $uid: String! +) { + destination_overview_page(locale: $locale, uid: $uid) { + web { + breadcrumbs { + ...BreadcrumbsRefs + } + } + system { + ...System + } + } +} diff --git a/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql b/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql new file mode 100644 index 000000000..d9d8e123b --- /dev/null +++ b/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql @@ -0,0 +1,48 @@ +#import "../../Fragments/System.graphql" + +query GetDestinationOverviewPage($locale: String!, $uid: String!) { + destination_overview_page(uid: $uid, locale: $locale) { + title + url + system { + ...System + created_at + updated_at + } + } + trackingProps: destination_overview_page(locale: "en", uid: $uid) { + url + } +} + +query GetDestinationOverviewPageRefs($locale: String!, $uid: String!) { + destination_overview_page(locale: $locale, uid: $uid) { + system { + ...System + } + } +} + +query GetDaDeEnUrlsDestinationOverviewPage($uid: String!) { + de: destination_overview_page(locale: "de", uid: $uid) { + url + } + en: destination_overview_page(locale: "en", uid: $uid) { + url + } + da: destination_overview_page(locale: "da", uid: $uid) { + url + } +} + +query GetFiNoSvUrlsDestinationOverviewPage($uid: String!) { + fi: destination_overview_page(locale: "fi", uid: $uid) { + url + } + no: destination_overview_page(locale: "no", uid: $uid) { + url + } + sv: destination_overview_page(locale: "sv", uid: $uid) { + url + } +} diff --git a/lib/graphql/Query/DestinationOverviewPage/Metadata.graphql b/lib/graphql/Query/DestinationOverviewPage/Metadata.graphql new file mode 100644 index 000000000..5c6f8bf83 --- /dev/null +++ b/lib/graphql/Query/DestinationOverviewPage/Metadata.graphql @@ -0,0 +1,18 @@ +#import "../../Fragments/Metadata.graphql" +#import "../../Fragments/System.graphql" + +query GetDestinationOverviewPageMetadata($locale: String!, $uid: String!) { + destination_overview_page(locale: $locale, uid: $uid) { + web { + breadcrumbs { + title + } + seo_metadata { + ...Metadata + } + } + system { + ...System + } + } +} diff --git a/lib/graphql/Query/ResolveEntry.graphql b/lib/graphql/Query/ResolveEntry.graphql index f512e1110..29b0cb993 100644 --- a/lib/graphql/Query/ResolveEntry.graphql +++ b/lib/graphql/Query/ResolveEntry.graphql @@ -1,6 +1,6 @@ #import "../Fragments/System.graphql" -query ResolveEntryByUrl($locale: String!, $url: String!) { +query EntryByUrlBatch1($locale: String!, $url: String!) { all_account_page(where: { url: $url }, locale: $locale) { items { system { @@ -50,3 +50,14 @@ query ResolveEntryByUrl($locale: String!, $url: String!) { total } } + +query EntryByUrlBatch2($locale: String!, $url: String!) { + all_destination_overview_page(where: { url: $url }, locale: $locale) { + items { + system { + ...System + } + } + total + } +} diff --git a/lib/graphql/batchEdgeRequest.ts b/lib/graphql/batchEdgeRequest.ts new file mode 100644 index 000000000..54f6a09df --- /dev/null +++ b/lib/graphql/batchEdgeRequest.ts @@ -0,0 +1,41 @@ +import deepmerge from "deepmerge" + +import { arrayMerge } from "@/utils/merge" + +import { edgeRequest } from "./edgeRequest" + +import type { BatchRequestDocument } from "graphql-request" + +import type { Data } from "@/types/request" + +export async function batchEdgeRequest( + queries: BatchRequestDocument[] +): Promise> { + try { + const response = await Promise.allSettled( + queries.map((query) => edgeRequest(query.document, query.variables)) + ) + + let data = {} as T + const reasons: PromiseRejectedResult["reason"][] = [] + response.forEach((res) => { + if (res.status === "fulfilled") { + data = deepmerge(data, res.value.data, { arrayMerge }) + } else { + reasons.push(res.reason) + } + }) + + if (reasons.length) { + reasons.forEach((reason) => { + console.error(`Batch request failed`, reason) + }) + } + + return { data } + } catch (error) { + console.error("Error in batched graphql request") + console.error(error) + throw new Error("Something went wrong") + } +} diff --git a/lib/trpc/memoizedRequests/index.ts b/lib/trpc/memoizedRequests/index.ts index 3ab4afd99..5e1903a18 100644 --- a/lib/trpc/memoizedRequests/index.ts +++ b/lib/trpc/memoizedRequests/index.ts @@ -170,3 +170,9 @@ export const getMeetingRooms = cache( return serverClient().hotel.meetingRooms(input) } ) + +export const getDestinationOverviewPage = cache( + async function getMemoizedDestinationOverviewPage() { + return serverClient().contentstack.destinationOverviewPage.get() + } +) diff --git a/server/routers/contentstack/bookingwidget/output.ts b/server/routers/contentstack/bookingwidget/output.ts index d13951a63..b88d4270c 100644 --- a/server/routers/contentstack/bookingwidget/output.ts +++ b/server/routers/contentstack/bookingwidget/output.ts @@ -10,11 +10,12 @@ const bookingWidgetToggleSchema = z export const validateBookingWidgetToggleSchema = z.object({ account_page: bookingWidgetToggleSchema, - loyalty_page: bookingWidgetToggleSchema, collection_page: bookingWidgetToggleSchema, content_page: bookingWidgetToggleSchema, - hotel_page: bookingWidgetToggleSchema, current_blocks_page: bookingWidgetToggleSchema, + destination_overview_page: bookingWidgetToggleSchema, + hotel_page: bookingWidgetToggleSchema, + loyalty_page: bookingWidgetToggleSchema, }) export type ValidateBookingWidgetToggleType = z.infer< diff --git a/server/routers/contentstack/bookingwidget/query.ts b/server/routers/contentstack/bookingwidget/query.ts index a321da4a8..ed244011a 100644 --- a/server/routers/contentstack/bookingwidget/query.ts +++ b/server/routers/contentstack/bookingwidget/query.ts @@ -3,6 +3,7 @@ import { GetCollectionPageSettings, GetContentPageSettings, GetCurrentBlocksPageSettings, + GetDestinationOverviewPageSettings, GetHotelPageSettings, GetLoyaltyPageSettings, } from "@/lib/graphql/Query/BookingWidgetToggle.graphql" @@ -50,6 +51,9 @@ export const bookingwidgetQueryRouter = router({ case PageContentTypeEnum.contentPage: GetPageSettings = GetContentPageSettings break + case PageContentTypeEnum.destinationOverviewPage: + GetPageSettings = GetDestinationOverviewPageSettings + break case PageContentTypeEnum.hotelPage: GetPageSettings = GetHotelPageSettings break diff --git a/server/routers/contentstack/breadcrumbs/query.ts b/server/routers/contentstack/breadcrumbs/query.ts index 9fefc6422..5f9676ef3 100644 --- a/server/routers/contentstack/breadcrumbs/query.ts +++ b/server/routers/contentstack/breadcrumbs/query.ts @@ -13,6 +13,10 @@ import { GetContentPageBreadcrumbs, GetContentPageBreadcrumbsRefs, } from "@/lib/graphql/Query/Breadcrumbs/ContentPage.graphql" +import { + GetDestinationOverviewPageBreadcrumbs, + GetDestinationOverviewPageBreadcrumbsRefs, +} from "@/lib/graphql/Query/Breadcrumbs/DestinationOverviewPage.graphql" import { GetHotelPageBreadcrumbs, GetHotelPageBreadcrumbsRefs, @@ -203,6 +207,17 @@ export const breadcrumbsQueryRouter = router({ }, variables ) + case PageContentTypeEnum.destinationOverviewPage: + return await getBreadcrumbs<{ + destination_overview_page: RawBreadcrumbsSchema + }>( + { + dataKey: "destination_overview_page", + refQuery: GetDestinationOverviewPageBreadcrumbsRefs, + query: GetDestinationOverviewPageBreadcrumbs, + }, + variables + ) case PageContentTypeEnum.hotelPage: return await getBreadcrumbs<{ hotel_page: RawBreadcrumbsSchema diff --git a/server/routers/contentstack/destinationOverviewPage/index.ts b/server/routers/contentstack/destinationOverviewPage/index.ts new file mode 100644 index 000000000..fc9146c0f --- /dev/null +++ b/server/routers/contentstack/destinationOverviewPage/index.ts @@ -0,0 +1,7 @@ +import { mergeRouters } from "@/server/trpc" + +import { destinationOverviewPageQueryRouter } from "./query" + +export const destinationOverviewPageRouter = mergeRouters( + destinationOverviewPageQueryRouter +) diff --git a/server/routers/contentstack/destinationOverviewPage/output.ts b/server/routers/contentstack/destinationOverviewPage/output.ts new file mode 100644 index 000000000..eddd8d13e --- /dev/null +++ b/server/routers/contentstack/destinationOverviewPage/output.ts @@ -0,0 +1,25 @@ +import { z } from "zod" + +import { systemSchema } from "../schemas/system" + +export const destinationOverviewPageSchema = z.object({ + destination_overview_page: z.object({ + title: z.string(), + system: systemSchema.merge( + z.object({ + created_at: z.string(), + updated_at: z.string(), + }) + ), + }), + trackingProps: z.object({ + url: z.string(), + }), +}) + +/** REFS */ +export const destinationOverviewPageRefsSchema = z.object({ + destination_overview_page: z.object({ + system: systemSchema, + }), +}) diff --git a/server/routers/contentstack/destinationOverviewPage/query.ts b/server/routers/contentstack/destinationOverviewPage/query.ts new file mode 100644 index 000000000..f7680cbd2 --- /dev/null +++ b/server/routers/contentstack/destinationOverviewPage/query.ts @@ -0,0 +1,190 @@ +import { + GetDestinationOverviewPage, + GetDestinationOverviewPageRefs, +} from "@/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql" +import { request } from "@/lib/graphql/request" +import { notFound } from "@/server/errors/trpc" +import { contentstackExtendedProcedureUID, router } from "@/server/trpc" + +import { generateTag } from "@/utils/generateTag" + +import { + destinationOverviewPageRefsSchema, + destinationOverviewPageSchema, +} from "./output" +import { + getDestinationOverviewPageCounter, + getDestinationOverviewPageFailCounter, + getDestinationOverviewPageRefsCounter, + getDestinationOverviewPageRefsFailCounter, + getDestinationOverviewPageRefsSuccessCounter, + getDestinationOverviewPageSuccessCounter, +} from "./telemetry" + +import { + TrackingChannelEnum, + type TrackingSDKPageData, +} from "@/types/components/tracking" +import type { + GetDestinationOverviewPageData, + GetDestinationOverviewPageRefsSchema, +} from "@/types/trpc/routers/contentstack/destinationOverviewPage" + +export const destinationOverviewPageQueryRouter = router({ + get: contentstackExtendedProcedureUID.query(async ({ ctx }) => { + const { lang, uid } = ctx + + getDestinationOverviewPageRefsCounter.add(1, { lang, uid: `${uid}` }) + console.info( + "contentstack.destinationOverviewPage.refs start", + JSON.stringify({ + query: { lang, uid }, + }) + ) + const refsResponse = await request( + GetDestinationOverviewPageRefs, + { + locale: lang, + uid, + }, + { + cache: "force-cache", + next: { + tags: [generateTag(lang, uid)], + }, + } + ) + if (!refsResponse.data) { + const notFoundError = notFound(refsResponse) + getDestinationOverviewPageRefsFailCounter.add(1, { + lang, + uid, + error_type: "not_found", + error: JSON.stringify({ code: notFoundError.code }), + }) + console.error( + "contentstack.destinationOverviewPage.refs not found error", + JSON.stringify({ + query: { lang, uid }, + error: { code: notFoundError.code }, + }) + ) + throw notFoundError + } + + const validatedRefsData = destinationOverviewPageRefsSchema.safeParse( + refsResponse.data + ) + + if (!validatedRefsData.success) { + getDestinationOverviewPageRefsFailCounter.add(1, { + lang, + uid, + error_type: "validation_error", + error: JSON.stringify(validatedRefsData.error), + }) + console.error( + "contentstack.destinationOverviewPage.refs validation error", + JSON.stringify({ + query: { lang, uid }, + error: validatedRefsData.error, + }) + ) + return null + } + + getDestinationOverviewPageRefsSuccessCounter.add(1, { lang, uid: `${uid}` }) + console.info( + "contentstack.destinationOverviewPage.refs success", + JSON.stringify({ + query: { lang, uid }, + }) + ) + + getDestinationOverviewPageCounter.add(1, { lang, uid: `${uid}` }) + console.info( + "contentstack.destinationOverviewPage start", + JSON.stringify({ + query: { lang, uid }, + }) + ) + const response = await request( + GetDestinationOverviewPage, + { + locale: lang, + uid, + }, + { + cache: "force-cache", + next: { + tags: [generateTag(lang, uid)], + }, + } + ) + if (!response.data) { + const notFoundError = notFound(response) + getDestinationOverviewPageFailCounter.add(1, { + lang, + uid: `${uid}`, + error_type: "not_found", + error: JSON.stringify({ code: notFoundError.code }), + }) + console.error( + "contentstack.destinationOverviewPage not found error", + JSON.stringify({ + query: { lang, uid }, + error: { code: notFoundError.code }, + }) + ) + throw notFoundError + } + + const destinationOverviewPage = destinationOverviewPageSchema.safeParse( + response.data + ) + + if (!destinationOverviewPage.success) { + getDestinationOverviewPageFailCounter.add(1, { + lang, + uid: `${uid}`, + error_type: "validation_error", + error: JSON.stringify(destinationOverviewPage.error), + }) + console.error( + "contentstack.destinationOverviewPage validation error", + JSON.stringify({ + query: { lang, uid }, + error: destinationOverviewPage.error, + }) + ) + return null + } + + getDestinationOverviewPageSuccessCounter.add(1, { lang, uid: `${uid}` }) + console.info( + "contentstack.destinationOverviewPage success", + JSON.stringify({ + query: { lang, uid }, + }) + ) + + const system = destinationOverviewPage.data.destination_overview_page.system + const tracking: TrackingSDKPageData = { + pageId: system.uid, + domainLanguage: lang, + publishDate: system.updated_at, + createDate: system.created_at, + channel: TrackingChannelEnum["destination-overview-page"], + pageType: "staticcontentpage", + pageName: destinationOverviewPage.data.trackingProps.url, + siteSections: destinationOverviewPage.data.trackingProps.url, + siteVersion: "new-web", + } + + return { + destinationOverviewPage: + destinationOverviewPage.data.destination_overview_page, + tracking, + } + }), +}) diff --git a/server/routers/contentstack/destinationOverviewPage/telemetry.ts b/server/routers/contentstack/destinationOverviewPage/telemetry.ts new file mode 100644 index 000000000..84d93764a --- /dev/null +++ b/server/routers/contentstack/destinationOverviewPage/telemetry.ts @@ -0,0 +1,23 @@ +import { metrics } from "@opentelemetry/api" + +const meter = metrics.getMeter("trpc.contentstack.destinationOverviewPage") + +export const getDestinationOverviewPageRefsCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get" +) +export const getDestinationOverviewPageRefsFailCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get-fail" +) +export const getDestinationOverviewPageRefsSuccessCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get-success" +) + +export const getDestinationOverviewPageCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get" +) +export const getDestinationOverviewPageSuccessCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get-success" +) +export const getDestinationOverviewPageFailCounter = meter.createCounter( + "trpc.contentstack.destinationOverviewPage.get-fail" +) diff --git a/server/routers/contentstack/index.ts b/server/routers/contentstack/index.ts index 68764c6ac..c1c192bc5 100644 --- a/server/routers/contentstack/index.ts +++ b/server/routers/contentstack/index.ts @@ -6,6 +6,7 @@ import { bookingwidgetRouter } from "./bookingwidget" import { breadcrumbsRouter } from "./breadcrumbs" import { collectionPageRouter } from "./collectionPage" import { contentPageRouter } from "./contentPage" +import { destinationOverviewPageRouter } from "./destinationOverviewPage" import { hotelPageRouter } from "./hotelPage" import { languageSwitcherRouter } from "./languageSwitcher" import { loyaltyLevelRouter } from "./loyaltyLevel" @@ -24,6 +25,7 @@ export const contentstackRouter = router({ loyaltyPage: loyaltyPageRouter, collectionPage: collectionPageRouter, contentPage: contentPageRouter, + destinationOverviewPage: destinationOverviewPageRouter, myPages: myPagesRouter, metadata: metadataRouter, rewards: rewardRouter, diff --git a/server/routers/contentstack/languageSwitcher/query.ts b/server/routers/contentstack/languageSwitcher/query.ts index e53ef8478..88e9c32be 100644 --- a/server/routers/contentstack/languageSwitcher/query.ts +++ b/server/routers/contentstack/languageSwitcher/query.ts @@ -19,6 +19,10 @@ import { GetDaDeEnUrlsCurrentBlocksPage, GetFiNoSvUrlsCurrentBlocksPage, } from "@/lib/graphql/Query/Current/LanguageSwitcher.graphql" +import { + GetDaDeEnUrlsDestinationOverviewPage, + GetFiNoSvUrlsDestinationOverviewPage, +} from "@/lib/graphql/Query/DestinationOverviewPage/DestinationOverviewPage.graphql" import { GetDaDeEnUrlsHotelPage, GetFiNoSvUrlsHotelPage, @@ -96,6 +100,10 @@ async function getLanguageSwitcher(options: LanguageSwitcherVariables) { daDeEnDocument = GetDaDeEnUrlsCollectionPage fiNoSvDocument = GetFiNoSvUrlsCollectionPage break + case PageContentTypeEnum.destinationOverviewPage: + daDeEnDocument = GetDaDeEnUrlsDestinationOverviewPage + fiNoSvDocument = GetFiNoSvUrlsDestinationOverviewPage + break default: console.error(`type: [${options.contentType}]`) console.error(`Trying to get a content type that is not supported`) diff --git a/server/routers/contentstack/metadata/query.ts b/server/routers/contentstack/metadata/query.ts index b577c61af..92ae60ef0 100644 --- a/server/routers/contentstack/metadata/query.ts +++ b/server/routers/contentstack/metadata/query.ts @@ -4,6 +4,7 @@ import { cache } from "react" import { GetAccountPageMetadata } from "@/lib/graphql/Query/AccountPage/Metadata.graphql" import { GetCollectionPageMetadata } from "@/lib/graphql/Query/CollectionPage/Metadata.graphql" import { GetContentPageMetadata } from "@/lib/graphql/Query/ContentPage/Metadata.graphql" +import { GetDestinationOverviewPageMetadata } from "@/lib/graphql/Query/DestinationOverviewPage/Metadata.graphql" import { GetHotelPageMetadata } from "@/lib/graphql/Query/HotelPage/Metadata.graphql" import { GetLoyaltyPageMetadata } from "@/lib/graphql/Query/LoyaltyPage/Metadata.graphql" import { request } from "@/lib/graphql/request" @@ -136,6 +137,13 @@ export const metadataQueryRouter = router({ content_page: RawMetadataSchema }>(GetContentPageMetadata, variables) return getTransformedMetadata(contentPageResponse.content_page) + case PageContentTypeEnum.destinationOverviewPage: + const destinationOverviewPageResponse = await fetchMetadata<{ + destination_overview_page: RawMetadataSchema + }>(GetDestinationOverviewPageMetadata, variables) + return getTransformedMetadata( + destinationOverviewPageResponse.destination_overview_page + ) case PageContentTypeEnum.loyaltyPage: const loyaltyPageResponse = await fetchMetadata<{ loyalty_page: RawMetadataSchema diff --git a/types/components/tracking.ts b/types/components/tracking.ts index 06aa0ed2a..f39eada37 100644 --- a/types/components/tracking.ts +++ b/types/components/tracking.ts @@ -6,6 +6,7 @@ export enum TrackingChannelEnum { "static-content-page" = "static-content-page", "hotelreservation" = "hotelreservation", "collection-page" = "collection-page", + "destination-overview-page" = "destination-overview-page", "hotels" = "hotels", } diff --git a/types/params.ts b/types/params.ts index 907c12d13..24c59b915 100644 --- a/types/params.ts +++ b/types/params.ts @@ -23,6 +23,7 @@ export type ContentTypeParams = { | PageContentTypeEnum.contentPage | PageContentTypeEnum.hotelPage | PageContentTypeEnum.collectionPage + | PageContentTypeEnum.destinationOverviewPage } export type ContentTypeWebviewParams = { diff --git a/types/requests/contentType.ts b/types/requests/contentType.ts index 56e6f36d1..a081e0538 100644 --- a/types/requests/contentType.ts +++ b/types/requests/contentType.ts @@ -1,8 +1,9 @@ export enum PageContentTypeEnum { accountPage = "account_page", - loyaltyPage = "loyalty_page", - hotelPage = "hotel_page", collectionPage = "collection_page", contentPage = "content_page", currentBlocksPage = "current_blocks_page", + destinationOverviewPage = "destination_overview_page", + hotelPage = "hotel_page", + loyaltyPage = "loyalty_page", } diff --git a/types/requests/entry.ts b/types/requests/entry.ts index 6429fee68..475473c70 100644 --- a/types/requests/entry.ts +++ b/types/requests/entry.ts @@ -19,4 +19,5 @@ export const validateEntryResolveSchema = z.object({ all_loyalty_page: entryResolveSchema, all_current_blocks_page: entryResolveSchema, all_hotel_page: entryResolveSchema, + all_destination_overview_page: entryResolveSchema, }) diff --git a/types/trpc/routers/contentstack/destinationOverviewPage.ts b/types/trpc/routers/contentstack/destinationOverviewPage.ts new file mode 100644 index 000000000..02a4b7efa --- /dev/null +++ b/types/trpc/routers/contentstack/destinationOverviewPage.ts @@ -0,0 +1,17 @@ +import type { z } from "zod" + +import type { + destinationOverviewPageRefsSchema, + destinationOverviewPageSchema, +} from "@/server/routers/contentstack/destinationOverviewPage/output" + +export interface GetDestinationOverviewPageData + extends z.input {} +export interface DestinationPage + extends z.output {} + +export interface GetDestinationOverviewPageRefsSchema + extends z.input {} + +export interface DestinationOverviewPageRefs + extends z.output {} diff --git a/utils/entry.ts b/utils/entry.ts index 16e9b3608..d66cf8ca5 100644 --- a/utils/entry.ts +++ b/utils/entry.ts @@ -1,23 +1,25 @@ import { Lang } from "@/constants/languages" -import { edgeRequest } from "@/lib/graphql/edgeRequest" -import { ResolveEntryByUrl } from "@/lib/graphql/Query/ResolveEntry.graphql" +import { batchEdgeRequest } from "@/lib/graphql/batchEdgeRequest" +import { + EntryByUrlBatch1, + EntryByUrlBatch2, +} from "@/lib/graphql/Query/ResolveEntry.graphql" import { internalServerError } from "@/server/errors/next" import { validateEntryResolveSchema } from "@/types/requests/entry" export async function resolve(url: string, lang = Lang.en) { - const response = await edgeRequest( - ResolveEntryByUrl, + const variables = { locale: lang, url } + const response = await batchEdgeRequest([ { - locale: lang, - url, + document: EntryByUrlBatch1, + variables, }, { - next: { - revalidate: 3600, - }, - } - ) + document: EntryByUrlBatch2, + variables, + }, + ]) const validatedData = validateEntryResolveSchema.safeParse(response.data)