feat(SW-1464): Added meeting url instead of hotel url for hotellisting with meeting information

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-03-18 07:01:56 +00:00
parent d5b47be2f2
commit da3a7c1865
11 changed files with 85 additions and 33 deletions

View File

@@ -18,20 +18,24 @@ import type { HotelListingItemProps } from "@/types/components/contentPage/hotel
export default async function HotelListingItem({
hotel,
additionalData,
contentType = "hotel",
url,
}: HotelListingItemProps) {
const intl = await getIntl()
const { description, imageSrc, altText } = getTypeSpecificInformation(
const { description, image, cta } = getTypeSpecificInformation(
intl,
contentType,
hotel
hotel.hotelContent,
additionalData,
url
)
return (
<article className={styles.container}>
<Image
src={imageSrc}
alt={altText}
src={image.src}
alt={image.alt}
width={300}
height={200}
className={styles.image}
@@ -62,7 +66,8 @@ export default async function HotelListingItem({
</div>
</div>
<Body>{description}</Body>
{url && (
{cta.url && (
<Button
intent="primary"
theme="base"
@@ -70,8 +75,12 @@ export default async function HotelListingItem({
className={styles.button}
asChild
>
<Link href={url} color="white">
{intl.formatMessage({ id: "See hotel details" })}
<Link
href={cta.url}
color="white"
target={cta.openInNewTab ? "_blank" : "_self"}
>
{cta.text}
</Link>
</Button>
)}

View File

@@ -1,36 +1,67 @@
import type { Hotel } from "@/types/hotel"
import type { IntlShape } from "react-intl"
import type { AdditionalData, Hotel } from "@/types/hotel"
import type { HotelListing } from "@/types/trpc/routers/contentstack/blocks"
export function getTypeSpecificInformation(
intl: IntlShape,
contentType: HotelListing["contentType"],
hotel: Hotel
hotelContent: Hotel["hotelContent"],
additionalData: AdditionalData,
url: string | null
) {
const { images } = hotel.hotelContent
const { descriptions, meetingDescription } = hotel.hotelContent.texts
const hotelData = {
const { images, texts } = hotelContent
const { descriptions, meetingDescription } = texts
const { conferencesAndMeetings, restaurantsOverviewPage, restaurantImages } =
additionalData
const data = {
description: descriptions?.short,
imageSrc: images.imageSizes.small,
altText: images.metaData.altText,
image: {
src: images.imageSizes.small,
alt: images.metaData.altText,
},
cta: {
text: intl.formatMessage({ id: "See hotel details" }),
url,
openInNewTab: false,
},
}
switch (contentType) {
case "meeting":
const meetingImage = hotel.conferencesAndMeetings?.heroImages[0]
return {
description: meetingDescription?.short || hotelData.description,
imageSrc: meetingImage?.imageSizes.small || hotelData.imageSrc,
altText: meetingImage?.metaData.altText || hotelData.altText,
const meetingImage = conferencesAndMeetings?.heroImages[0]
const meetingUrl = additionalData.meetingRooms.meetingOnlineLink
if (meetingDescription?.short) {
data.description = meetingDescription.short
}
if (meetingImage) {
data.image = {
src: meetingImage.imageSizes.small,
alt: meetingImage.metaData.altText,
}
}
if (meetingUrl) {
data.cta = {
text: intl.formatMessage({ id: "Book a meeting" }),
url: meetingUrl,
openInNewTab: true,
}
}
return data
case "restaurant":
const restaurantImage = hotel.restaurantImages?.heroImages[0]
return {
description:
hotel.hotelContent.restaurantsOverviewPage
.restaurantsContentDescriptionShort || hotelData.description,
imageSrc: restaurantImage?.imageSizes.small || hotelData.imageSrc,
altText: restaurantImage?.metaData.altText || hotelData.altText,
const restaurantImage = restaurantImages?.heroImages[0]
if (restaurantsOverviewPage.restaurantsContentDescriptionShort) {
data.description =
restaurantsOverviewPage.restaurantsContentDescriptionShort
}
if (restaurantImage) {
data.image = {
src: restaurantImage.imageSizes.small,
alt: restaurantImage.metaData.altText,
}
}
return data
case "hotel":
default:
return hotelData
return data
}
}

View File

@@ -15,7 +15,7 @@ export default async function HotelListing({
}: HotelListingProps) {
const hotels = await getHotelsByCSFilter({
locationFilter,
hotelsToInclude: hotelsToInclude,
hotelsToInclude,
})
if (!hotels.length) {
@@ -27,10 +27,11 @@ export default async function HotelListing({
<Title level="h4" as="h3" textTransform="capitalize">
{heading}
</Title>
{hotels.map(({ url, ...data }) => (
{hotels.map(({ url, hotel, additionalData }) => (
<HotelListingItem
key={data.hotel.name}
hotel={data.hotel}
key={hotel.name}
hotel={hotel}
additionalData={additionalData}
contentType={contentType}
url={url}
/>

View File

@@ -93,6 +93,7 @@
"Boardroom": "Boardroom",
"Book": "Book",
"Book Reward Night": "Book bonusnat",
"Book a meeting": "Book et møde",
"Book a table online": "Book et bord online",
"Book another stay": "Book another stay",
"Book parking": "Book parkering",

View File

@@ -94,6 +94,7 @@
"Boardroom": "Boardroom",
"Book": "Buchen",
"Book Reward Night": "Bonusnacht buchen",
"Book a meeting": "Buchen Sie ein Meeting",
"Book a table online": "Tisch online buchen",
"Book another stay": "Book another stay",
"Book parking": "Parkplatz buchen",

View File

@@ -92,6 +92,7 @@
"Boardroom": "Boardroom",
"Book": "Book",
"Book Reward Night": "Book Reward Night",
"Book a meeting": "Book a meeting",
"Book a table online": "Book a table online",
"Book another stay": "Book another stay",
"Book parking": "Book parking",

View File

@@ -92,6 +92,7 @@
"Boardroom": "Boardroom",
"Book": "Varaa",
"Book Reward Night": "Kirjapalkinto-ilta",
"Book a meeting": "Varaa kokous",
"Book a table online": "Varaa pöytä verkossa",
"Book another stay": "Book another stay",
"Book parking": "Varaa pysäköinti",

View File

@@ -92,6 +92,7 @@
"Boardroom": "Boardroom",
"Book": "Bestill",
"Book Reward Night": "Bestill belønningskveld",
"Book a meeting": "Bestill et møte",
"Book a table online": "Bestill bord online",
"Book another stay": "Book another stay",
"Book parking": "Bestill parkering",

View File

@@ -92,6 +92,7 @@
"Boardroom": "Boardroom",
"Book": "Boka",
"Book Reward Night": "Boka frinatt",
"Book a meeting": "Boka ett möte",
"Book a table online": "Boka ett bord online",
"Book another stay": "Book another stay",
"Book parking": "Boka parkering",

View File

@@ -27,7 +27,11 @@ export const additionalDataSchema = z.object({
hotelRoomElevatorPitchText: nullableStringValidator,
hotelSpecialNeeds: extraPageSchema,
id: nullableStringValidator,
meetingRooms: extraPageSchema,
meetingRooms: extraPageSchema.merge(
z.object({
meetingOnlineLink: z.string().nullish(),
})
),
name: nullableStringValidator,
parkingImages: facilitySchema.nullish(),
restaurantImages: facilitySchema.nullish(),

View File

@@ -1,8 +1,9 @@
import type { Hotel } from "@/types/hotel"
import type { AdditionalData, Hotel } from "@/types/hotel"
import type { HotelListing } from "@/types/trpc/routers/contentstack/blocks"
export interface HotelListingItemProps {
hotel: Hotel
additionalData: AdditionalData
contentType: HotelListing["contentType"]
url: string | null
}