Merged in feat/SW-1469-facility-cards (pull request #1393)
Feat(SW-1469): Add check if we should create facility cards * fix(SW-1469): only create facility cards if supposed to Approved-by: Erik Tiekstra Approved-by: Fredrik Thorsson
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import { meetingsAndConferences } from "@/constants/routes/hotelPageParams"
|
import { meetingsAndConferences } from "@/constants/routes/hotelPageParams"
|
||||||
import { getMeetingRooms } from "@/lib/trpc/memoizedRequests"
|
|
||||||
|
|
||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
@@ -20,15 +19,11 @@ import type { MeetingsAndConferencesSidePeekProps } from "@/types/components/hot
|
|||||||
export default async function MeetingsAndConferencesSidePeek({
|
export default async function MeetingsAndConferencesSidePeek({
|
||||||
meetingFacilities,
|
meetingFacilities,
|
||||||
descriptions,
|
descriptions,
|
||||||
hotelId,
|
meetingRooms,
|
||||||
meetingPageUrl,
|
meetingPageUrl,
|
||||||
}: MeetingsAndConferencesSidePeekProps) {
|
}: MeetingsAndConferencesSidePeekProps) {
|
||||||
const lang = getLang()
|
const lang = getLang()
|
||||||
const [intl, meetingRooms] = await Promise.all([
|
const intl = await getIntl()
|
||||||
getIntl(),
|
|
||||||
getMeetingRooms({ hotelId, language: lang }),
|
|
||||||
])
|
|
||||||
|
|
||||||
const { seatingText, roomText } = await getConferenceRoomTexts(meetingRooms)
|
const { seatingText, roomText } = await getConferenceRoomTexts(meetingRooms)
|
||||||
|
|
||||||
const fallbackAlt = intl.formatMessage({ id: "Creative spaces for meetings" })
|
const fallbackAlt = intl.formatMessage({ id: "Creative spaces for meetings" })
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import {
|
|||||||
export default function TabNavigation({
|
export default function TabNavigation({
|
||||||
hasActivities,
|
hasActivities,
|
||||||
hasFAQ,
|
hasFAQ,
|
||||||
|
hasMeetingRooms,
|
||||||
|
hasRestaurants,
|
||||||
|
hasWellness,
|
||||||
tabValues,
|
tabValues,
|
||||||
}: TabNavigationProps) {
|
}: TabNavigationProps) {
|
||||||
const hash = useHash()
|
const hash = useHash()
|
||||||
@@ -43,24 +46,36 @@ export default function TabNavigation({
|
|||||||
hash: HotelHashValues.rooms,
|
hash: HotelHashValues.rooms,
|
||||||
text: tabValues?.rooms || intl.formatMessage({ id: "Rooms" }),
|
text: tabValues?.rooms || intl.formatMessage({ id: "Rooms" }),
|
||||||
},
|
},
|
||||||
{
|
...(hasRestaurants
|
||||||
hash: HotelHashValues.restaurant,
|
? [
|
||||||
text:
|
{
|
||||||
tabValues?.restaurant_bar ||
|
hash: HotelHashValues.restaurant,
|
||||||
intl.formatMessage({ id: "Restaurant & Bar" }),
|
text:
|
||||||
},
|
tabValues?.restaurant_bar ||
|
||||||
{
|
intl.formatMessage({ id: "Restaurant & Bar" }),
|
||||||
hash: HotelHashValues.meetings,
|
},
|
||||||
text:
|
]
|
||||||
tabValues?.conferences_meetings ||
|
: []),
|
||||||
intl.formatMessage({ id: "Meetings & Conferences" }),
|
...(hasMeetingRooms
|
||||||
},
|
? [
|
||||||
{
|
{
|
||||||
hash: HotelHashValues.wellness,
|
hash: HotelHashValues.meetings,
|
||||||
text:
|
text:
|
||||||
tabValues?.health_wellness ||
|
tabValues?.conferences_meetings ||
|
||||||
intl.formatMessage({ id: "Wellness & Exercise" }),
|
intl.formatMessage({ id: "Meetings & Conferences" }),
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
...(hasWellness
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
hash: HotelHashValues.wellness,
|
||||||
|
text:
|
||||||
|
tabValues?.health_wellness ||
|
||||||
|
intl.formatMessage({ id: "Wellness & Exercise" }),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
...(hasActivities
|
...(hasActivities
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { notFound } from "next/navigation"
|
|||||||
import { Suspense } from "react"
|
import { Suspense } from "react"
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { getHotel, getHotelPage } from "@/lib/trpc/memoizedRequests"
|
import {
|
||||||
|
getHotel,
|
||||||
|
getHotelPage,
|
||||||
|
getMeetingRooms,
|
||||||
|
} from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import AccordionSection from "@/components/Blocks/Accordion"
|
import AccordionSection from "@/components/Blocks/Accordion"
|
||||||
import Breadcrumbs from "@/components/Breadcrumbs"
|
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||||
@@ -11,6 +15,7 @@ import Alert from "@/components/TempDesignSystem/Alert"
|
|||||||
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
|
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
|
||||||
import TrackingSDK from "@/components/TrackingSDK"
|
import TrackingSDK from "@/components/TrackingSDK"
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
import { setFacilityCards } from "@/utils/facilityCards"
|
||||||
import { generateHotelSchema } from "@/utils/jsonSchemas"
|
import { generateHotelSchema } from "@/utils/jsonSchemas"
|
||||||
|
|
||||||
import DynamicMap from "./Map/DynamicMap"
|
import DynamicMap from "./Map/DynamicMap"
|
||||||
@@ -37,22 +42,22 @@ import { getTrackingHotelData, getTrackingPageData } from "./utils"
|
|||||||
|
|
||||||
import styles from "./hotelPage.module.css"
|
import styles from "./hotelPage.module.css"
|
||||||
|
|
||||||
import { FacilityCardTypeEnum } from "@/types/components/hotelPage/facilities"
|
|
||||||
import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
|
import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage"
|
||||||
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation"
|
||||||
import type { Facility } from "@/types/hotel"
|
|
||||||
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
import { PageContentTypeEnum } from "@/types/requests/contentType"
|
||||||
|
|
||||||
export default async function HotelPage({ hotelId }: HotelPageProps) {
|
export default async function HotelPage({ hotelId }: HotelPageProps) {
|
||||||
const lang = getLang()
|
const lang = getLang()
|
||||||
const [hotelPageData, hotelData] = await Promise.all([
|
const [hotelPageData, hotelData, meetingRoomsData] = await Promise.all([
|
||||||
getHotelPage(),
|
getHotelPage(),
|
||||||
getHotel({
|
getHotel({
|
||||||
hotelId,
|
hotelId,
|
||||||
isCardOnlyPayment: false,
|
isCardOnlyPayment: false,
|
||||||
language: lang,
|
language: lang,
|
||||||
}),
|
}),
|
||||||
|
getMeetingRooms({ hotelId, language: lang }),
|
||||||
])
|
])
|
||||||
|
|
||||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||||
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
||||||
|
|
||||||
@@ -97,26 +102,18 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
|
|
||||||
const { spaPage, activitiesCards } = content
|
const { spaPage, activitiesCards } = content
|
||||||
|
|
||||||
const facilities: Facility[] = [
|
const hasRestaurants = restaurants.length > 0
|
||||||
{
|
const hasMeetingRooms = meetingRoomsData.length > 0
|
||||||
...restaurantImages,
|
const hasWellness = healthFacilities.length > 0
|
||||||
id: FacilityCardTypeEnum.restaurant,
|
|
||||||
headingText: restaurantImages?.headingText ?? "",
|
const facilities = setFacilityCards(
|
||||||
heroImages: restaurantImages?.heroImages ?? [],
|
restaurantImages,
|
||||||
},
|
conferencesAndMeetings,
|
||||||
{
|
healthAndWellness,
|
||||||
...conferencesAndMeetings,
|
hasRestaurants,
|
||||||
id: FacilityCardTypeEnum.conference,
|
hasMeetingRooms,
|
||||||
headingText: conferencesAndMeetings?.headingText ?? "",
|
hasWellness
|
||||||
heroImages: conferencesAndMeetings?.heroImages ?? [],
|
)
|
||||||
},
|
|
||||||
{
|
|
||||||
...healthAndWellness,
|
|
||||||
id: FacilityCardTypeEnum.wellness,
|
|
||||||
headingText: healthAndWellness?.headingText ?? "",
|
|
||||||
heroImages: healthAndWellness?.heroImages ?? [],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
const topThreePois = pointsOfInterest.slice(0, 3)
|
const topThreePois = pointsOfInterest.slice(0, 3)
|
||||||
|
|
||||||
@@ -151,6 +148,9 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
<TabNavigation
|
<TabNavigation
|
||||||
hasActivities={activitiesCards.length > 0}
|
hasActivities={activitiesCards.length > 0}
|
||||||
hasFAQ={!!faq?.accordions.length}
|
hasFAQ={!!faq?.accordions.length}
|
||||||
|
hasWellness={hasWellness}
|
||||||
|
hasRestaurants={hasRestaurants}
|
||||||
|
hasMeetingRooms={hasMeetingRooms}
|
||||||
tabValues={tabValues}
|
tabValues={tabValues}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -183,12 +183,14 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
<Rooms rooms={roomCategories} preamble={hotelRoomElevatorPitchText} />
|
<Rooms rooms={roomCategories} preamble={hotelRoomElevatorPitchText} />
|
||||||
<Facilities
|
{facilities && (
|
||||||
facilities={facilities}
|
<Facilities
|
||||||
activitiesCards={activitiesCards}
|
facilities={facilities}
|
||||||
amenities={detailedFacilities}
|
activitiesCards={activitiesCards}
|
||||||
healthFacilities={healthFacilities}
|
amenities={detailedFacilities}
|
||||||
/>
|
healthFacilities={healthFacilities}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{faq && faq.accordions.length > 0 && (
|
{faq && faq.accordions.length > 0 && (
|
||||||
<AccordionSection accordion={faq.accordions} title={faq.title} />
|
<AccordionSection accordion={faq.accordions} title={faq.title} />
|
||||||
)}
|
)}
|
||||||
@@ -238,14 +240,18 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
ecoLabels={hotelFacts.ecoLabels}
|
ecoLabels={hotelFacts.ecoLabels}
|
||||||
descriptions={hotelContent.texts}
|
descriptions={hotelContent.texts}
|
||||||
/>
|
/>
|
||||||
<WellnessAndExerciseSidePeek
|
{hasWellness ? (
|
||||||
healthFacilities={healthFacilities}
|
<WellnessAndExerciseSidePeek
|
||||||
spaPage={spaPage?.spa_page}
|
healthFacilities={healthFacilities}
|
||||||
wellnessExercisePageUrl={
|
spaPage={spaPage?.spa_page}
|
||||||
displayWebPage.healthGym ? healthAndFitness.nameInUrl : undefined
|
wellnessExercisePageUrl={
|
||||||
}
|
displayWebPage.healthGym ? healthAndFitness.nameInUrl : undefined
|
||||||
/>
|
}
|
||||||
<RestaurantBarSidePeek restaurants={restaurants} />
|
/>
|
||||||
|
) : null}
|
||||||
|
{hasRestaurants ? (
|
||||||
|
<RestaurantBarSidePeek restaurants={restaurants} />
|
||||||
|
) : null}
|
||||||
{activitiesCards.map((card) => (
|
{activitiesCards.map((card) => (
|
||||||
<ActivitiesSidePeek
|
<ActivitiesSidePeek
|
||||||
key={card.upcoming_activities_card.heading}
|
key={card.upcoming_activities_card.heading}
|
||||||
@@ -254,14 +260,16 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
sidepeekSlug={card.upcoming_activities_card.sidepeekSlug}
|
sidepeekSlug={card.upcoming_activities_card.sidepeekSlug}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
<MeetingsAndConferencesSidePeek
|
{hasMeetingRooms && (
|
||||||
meetingFacilities={conferencesAndMeetings}
|
<MeetingsAndConferencesSidePeek
|
||||||
descriptions={hotelContent.texts.meetingDescription}
|
meetingFacilities={conferencesAndMeetings}
|
||||||
hotelId={hotelId}
|
descriptions={hotelContent.texts.meetingDescription}
|
||||||
meetingPageUrl={
|
meetingRooms={meetingRoomsData}
|
||||||
displayWebPage.meetingRoom ? meetingRooms.nameInUrl : undefined
|
meetingPageUrl={
|
||||||
}
|
displayWebPage.meetingRoom ? meetingRooms.nameInUrl : undefined
|
||||||
/>
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{roomCategories.map((room) => (
|
{roomCategories.map((room) => (
|
||||||
<RoomSidePeek key={room.name} room={room} />
|
<RoomSidePeek key={room.name} room={room} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { Hotel } from "@/types/hotel"
|
import type { Hotel } from "@/types/hotel"
|
||||||
|
import type { MeetingRooms } from "../meetingRooms"
|
||||||
|
|
||||||
export type MeetingsAndConferencesSidePeekProps = {
|
export type MeetingsAndConferencesSidePeekProps = {
|
||||||
meetingFacilities: Hotel["conferencesAndMeetings"]
|
meetingFacilities: Hotel["conferencesAndMeetings"]
|
||||||
descriptions: Hotel["hotelContent"]["texts"]["meetingDescription"]
|
descriptions: Hotel["hotelContent"]["texts"]["meetingDescription"]
|
||||||
hotelId: string
|
meetingRooms: MeetingRooms
|
||||||
meetingPageUrl: string | undefined
|
meetingPageUrl: string | undefined
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,5 +22,8 @@ type Tabs = {
|
|||||||
export type TabNavigationProps = {
|
export type TabNavigationProps = {
|
||||||
hasActivities: boolean
|
hasActivities: boolean
|
||||||
hasFAQ: boolean
|
hasFAQ: boolean
|
||||||
|
hasWellness: boolean
|
||||||
|
hasRestaurants: boolean
|
||||||
|
hasMeetingRooms: boolean
|
||||||
tabValues?: Tabs | null
|
tabValues?: Tabs | null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ export type Amenities = z.output<typeof detailedFacilitiesSchema>
|
|||||||
export type CheckInData = z.output<typeof checkinSchema>
|
export type CheckInData = z.output<typeof checkinSchema>
|
||||||
type CitySchema = z.output<typeof citySchema>
|
type CitySchema = z.output<typeof citySchema>
|
||||||
export type City = Pick<CitySchema, "id" | "type"> & CitySchema["attributes"]
|
export type City = Pick<CitySchema, "id" | "type"> & CitySchema["attributes"]
|
||||||
export type Facility = z.output<typeof facilitySchema> & { id: string }
|
export type FacilityData = z.output<typeof facilitySchema>
|
||||||
|
export type Facility = FacilityData & { id: string }
|
||||||
export type ApiImage = z.output<typeof imageSchema>
|
export type ApiImage = z.output<typeof imageSchema>
|
||||||
export type HealthFacility = z.output<typeof healthFacilitySchema>
|
export type HealthFacility = z.output<typeof healthFacilitySchema>
|
||||||
export type HealthFacilities = HealthFacility[]
|
export type HealthFacilities = HealthFacility[]
|
||||||
|
|||||||
@@ -19,9 +19,53 @@ import {
|
|||||||
WellnessHeadings,
|
WellnessHeadings,
|
||||||
} from "@/types/components/hotelPage/facilities"
|
} from "@/types/components/hotelPage/facilities"
|
||||||
import { FacilityEnum } from "@/types/enums/facilities"
|
import { FacilityEnum } from "@/types/enums/facilities"
|
||||||
import type { Amenities, Facility, HealthFacilities } from "@/types/hotel"
|
import type {
|
||||||
|
Amenities,
|
||||||
|
Facility,
|
||||||
|
FacilityData,
|
||||||
|
HealthFacilities,
|
||||||
|
} from "@/types/hotel"
|
||||||
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
|
import type { CardProps } from "@/components/TempDesignSystem/Card/card"
|
||||||
|
|
||||||
|
export function setFacilityCards(
|
||||||
|
restaurantImages: FacilityData | undefined,
|
||||||
|
conferencesAndMeetings: FacilityData | undefined,
|
||||||
|
healthAndWellness: FacilityData | undefined,
|
||||||
|
hasRestaurants: boolean,
|
||||||
|
hasMeetingRooms: boolean,
|
||||||
|
hasWellness: boolean
|
||||||
|
): Facility[] {
|
||||||
|
const facilities = []
|
||||||
|
if (hasRestaurants) {
|
||||||
|
facilities.push(
|
||||||
|
setFacilityCard(restaurantImages, FacilityCardTypeEnum.restaurant)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (hasMeetingRooms) {
|
||||||
|
facilities.push(
|
||||||
|
setFacilityCard(conferencesAndMeetings, FacilityCardTypeEnum.conference)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (hasWellness) {
|
||||||
|
facilities.push(
|
||||||
|
setFacilityCard(healthAndWellness, FacilityCardTypeEnum.wellness)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return facilities
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFacilityCard(
|
||||||
|
facility: FacilityData | undefined,
|
||||||
|
type: FacilityCardTypeEnum
|
||||||
|
): Facility {
|
||||||
|
return {
|
||||||
|
...facility,
|
||||||
|
id: type,
|
||||||
|
headingText: facility?.headingText ?? "",
|
||||||
|
heroImages: facility?.heroImages ?? [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function isFacilityCard(card: FacilityCardType): card is FacilityCard {
|
export function isFacilityCard(card: FacilityCardType): card is FacilityCard {
|
||||||
return "heading" in card
|
return "heading" in card
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user