diff --git a/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx b/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx
index 97ac09a91..6d690a643 100644
--- a/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx
+++ b/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx
@@ -14,7 +14,8 @@ import type { WellnessAndExerciseSidePeekProps } from "@/types/components/hotelP
export default async function WellnessAndExerciseSidePeek({
healthFacilities,
- buttonUrl,
+ wellnessExerciseButton,
+ spaPage,
}: WellnessAndExerciseSidePeekProps) {
const intl = await getIntl()
const lang = getLang()
@@ -29,13 +30,26 @@ export default async function WellnessAndExerciseSidePeek({
))}
- {buttonUrl && (
+ {(spaPage || wellnessExerciseButton) && (
-
+ {spaPage && (
+
+ )}
+ {wellnessExerciseButton && (
+
+ )}
)}
diff --git a/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/wellnessAndExercise.module.css b/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/wellnessAndExercise.module.css
index 11a410f13..f6f47761e 100644
--- a/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/wellnessAndExercise.module.css
+++ b/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/wellnessAndExercise.module.css
@@ -15,4 +15,6 @@
position: absolute;
left: 0;
bottom: 0;
+ display: grid;
+ gap: var(--Spacing-x2);
}
diff --git a/components/ContentType/HotelPage/index.tsx b/components/ContentType/HotelPage/index.tsx
index 992cdc2d2..180a5d16d 100644
--- a/components/ContentType/HotelPage/index.tsx
+++ b/components/ContentType/HotelPage/index.tsx
@@ -9,7 +9,6 @@ import Breadcrumbs from "@/components/Breadcrumbs"
import SidePeekProvider from "@/components/SidePeeks/SidePeekProvider"
import Alert from "@/components/TempDesignSystem/Alert"
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
-import SidePeek from "@/components/TempDesignSystem/SidePeek"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { getRestaurantHeading } from "@/utils/facilityCards"
@@ -43,6 +42,10 @@ import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
import type { Facility } from "@/types/hotel"
import { PageContentTypeEnum } from "@/types/requests/contentType"
+import type {
+ ActivitiesCard,
+ SpaPage,
+} from "@/types/trpc/routers/contentstack/hotelPage"
export default async function HotelPage({ hotelId }: HotelPageProps) {
const lang = getLang()
@@ -83,7 +86,8 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
const restaurants = hotelData.included?.restaurants || []
const images = gallery?.smallerImages
const description = hotelContent.texts.descriptions.medium
- const activitiesCard = content?.[0]?.upcoming_activities_card || null
+
+ const { spaPage, activitiesCard } = content
const facilities: Facility[] = [
{
@@ -162,7 +166,10 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
) : null}
-
+
{faq.accordions.length > 0 && (
)}
@@ -200,10 +207,15 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
ecoLabels={hotelFacts.ecoLabels}
descriptions={hotelContent.texts}
/>
-
+
{activitiesCard && (
-
+
)}
{
+ let spaPage: SpaPage | undefined
+ let activitiesCard: ActivitiesCard | undefined
+ data?.map((block) => {
+ switch (block.typename) {
+ case HotelPageEnum.ContentStack.blocks.ActivitiesCard:
+ activitiesCard = block
+ break
+ case HotelPageEnum.ContentStack.blocks.SpaPage:
+ spaPage = block
+ break
+ default:
+ break
+ }
+ })
+ return { spaPage, activitiesCard }
+ }),
faq: hotelFaqSchema,
hotel_page_id: z.string(),
title: z.string(),
@@ -40,14 +70,21 @@ export const hotelPageSchema = z.object({
})
/** REFS */
-const hotelPageActiviesCardRefs = z
+const hotelPageActivitiesCardRefs = z
.object({
__typename: z.literal(HotelPageEnum.ContentStack.blocks.ActivitiesCard),
})
.merge(activitiesCardRefSchema)
+const hotelPageSpaPageRefs = z
+ .object({
+ __typename: z.literal(HotelPageEnum.ContentStack.blocks.SpaPage),
+ })
+ .merge(spaPageRefSchema)
+
const hotelPageBlockRefsItem = z.discriminatedUnion("__typename", [
- hotelPageActiviesCardRefs,
+ hotelPageActivitiesCardRefs,
+ hotelPageSpaPageRefs,
])
export const hotelPageRefsSchema = z.object({
diff --git a/server/routers/contentstack/schemas/blocks/spaPage.ts b/server/routers/contentstack/schemas/blocks/spaPage.ts
new file mode 100644
index 000000000..f353bd736
--- /dev/null
+++ b/server/routers/contentstack/schemas/blocks/spaPage.ts
@@ -0,0 +1,68 @@
+import { z } from "zod"
+
+import * as pageLinks from "@/server/routers/contentstack/schemas/pageLinks"
+
+import { removeMultipleSlashes } from "@/utils/url"
+
+import { HotelPageEnum } from "@/types/enums/hotelPage"
+
+export const spaPageSchema = z.object({
+ typename: z
+ .literal(HotelPageEnum.ContentStack.blocks.SpaPage)
+ .optional()
+ .default(HotelPageEnum.ContentStack.blocks.SpaPage),
+ spa_page: z
+ .object({
+ button_cta: z.string(),
+ pageConnection: z.object({
+ edges: z.array(
+ z.object({
+ node: z.object({
+ title: z.string(),
+ url: z.string(),
+ system: z.object({
+ content_type_uid: z.string(),
+ locale: z.string(),
+ uid: z.string(),
+ }),
+ web: z.object({ original_url: z.string() }),
+ }),
+ })
+ ),
+ }),
+ })
+ .transform((data) => {
+ let url = ""
+ if (data.pageConnection.edges.length) {
+ const page = data.pageConnection.edges[0].node
+ if (page.web.original_url) {
+ url = page.web.original_url
+ } else {
+ url = removeMultipleSlashes(`/${page.system.locale}/${page.url}`)
+ }
+ }
+ return {
+ buttonCTA: data.button_cta,
+ url: url,
+ }
+ }),
+})
+
+export const spaPageRefSchema = z.object({
+ spa_page: z
+ .object({
+ pageConnection: z.object({
+ edges: z.array(
+ z.object({
+ node: z.discriminatedUnion("__typename", [
+ pageLinks.contentPageRefSchema,
+ pageLinks.collectionPageRefSchema,
+ ]),
+ })
+ ),
+ }),
+ })
+ .transform((data) => {
+ return data.pageConnection.edges.flatMap(({ node }) => node.system) || []
+ }),
+})
diff --git a/types/components/hotelPage/facilities.ts b/types/components/hotelPage/facilities.ts
index 5c753797a..dcc58651f 100644
--- a/types/components/hotelPage/facilities.ts
+++ b/types/components/hotelPage/facilities.ts
@@ -4,7 +4,7 @@ import type { CardProps } from "@/components/TempDesignSystem/Card/card"
export type FacilitiesProps = {
facilities: Facility[]
- activitiesCard: ActivityCard | null
+ activitiesCard?: ActivityCard
}
export type FacilityImage = {
diff --git a/types/components/hotelPage/sidepeek/wellnessAndExercise.ts b/types/components/hotelPage/sidepeek/wellnessAndExercise.ts
index 828f3ee8b..4e70b9210 100644
--- a/types/components/hotelPage/sidepeek/wellnessAndExercise.ts
+++ b/types/components/hotelPage/sidepeek/wellnessAndExercise.ts
@@ -2,5 +2,9 @@ import type { Hotel } from "@/types/hotel"
export type WellnessAndExerciseSidePeekProps = {
healthFacilities: Hotel["healthFacilities"]
- buttonUrl?: string
+ wellnessExerciseButton?: string
+ spaPage?: {
+ buttonCTA: string
+ url: string
+ }
}
diff --git a/types/enums/hotelPage.ts b/types/enums/hotelPage.ts
index bfae4bfbe..8cc5f8839 100644
--- a/types/enums/hotelPage.ts
+++ b/types/enums/hotelPage.ts
@@ -3,6 +3,7 @@ export namespace HotelPageEnum {
export const enum blocks {
Faq = "HotelPageFaq",
ActivitiesCard = "HotelPageContentUpcomingActivitiesCard",
+ SpaPage = "HotelPageContentSpaPage",
}
}
}
diff --git a/types/trpc/routers/contentstack/hotelPage.ts b/types/trpc/routers/contentstack/hotelPage.ts
index 6b98f5ca2..7a983d419 100644
--- a/types/trpc/routers/contentstack/hotelPage.ts
+++ b/types/trpc/routers/contentstack/hotelPage.ts
@@ -7,13 +7,16 @@ import type {
hotelPageUrlSchema,
} from "@/server/routers/contentstack/hotelPage/output"
import type { activitiesCardSchema } from "@/server/routers/contentstack/schemas/blocks/activitiesCard"
+import type { spaPageSchema } from "@/server/routers/contentstack/schemas/blocks/spaPage"
export interface GetHotelPageData extends z.input {}
export interface HotelPage extends z.output {}
export interface ActivitiesCard extends z.output {}
export type ActivityCard = ActivitiesCard["upcoming_activities_card"]
-export interface ContentBlock extends z.output {}
+
+export interface SpaPage extends z.output {}
+export type ContentBlock = z.output
export interface GetHotelPageRefsSchema
extends z.input {}