Merged in feat/SW-1880-wellness-details (pull request #2016)

feat(SW-1880): add wellness details to sidepeek

* feat(SW-1880): add wellness details


Approved-by: Christian Andolf
This commit is contained in:
Matilda Landström
2025-05-09 08:04:46 +00:00
parent 7c3b6774aa
commit 2a830f2386
4 changed files with 188 additions and 2 deletions

View File

@@ -24,3 +24,15 @@
.title {
color: var(--Text-Interactive-Default);
}
.heartList {
list-style-type: none;
}
.heartList > li::before {
content: url("/_static/icons/heart.svg");
position: relative;
height: 8px;
top: 3px;
margin-right: var(--Space-x1);
}

View File

@@ -4,9 +4,14 @@ import Image from "@/components/Image"
import { getIntl } from "@/i18n"
import { translateWellnessType } from "../../../utils"
import { translateWellnessDetails } from "./utils"
import styles from "./facility.module.css"
import {
ExternalGymDetails,
HealthFacilitiesEnum,
} from "@/types/components/hotelPage/facilities"
import type { FacilityProps } from "@/types/components/hotelPage/sidepeek/facility"
export default async function Facility({ data }: FacilityProps) {
@@ -16,8 +21,14 @@ export default async function Facility({ data }: FacilityProps) {
const weekendOpeningTimes = data.openingDetails.openingHours.weekends
const shortDescription = data.content.texts.descriptions?.short
const isExternalGym =
data.type === "Gym" &&
data.details.find((d) => d.name === "ExternalGym")?.value === "True"
data.type === HealthFacilitiesEnum.Gym &&
data.details.find((d) => d.name === ExternalGymDetails.ExternalGym)
?.value === "True"
const details = await translateWellnessDetails({
details: data.details,
type: data.type,
})
return (
<div className={styles.content}>
@@ -34,6 +45,15 @@ export default async function Facility({ data }: FacilityProps) {
<Typography variant="Title/Subtitle/lg" className={styles.title}>
<h3>{translateWellnessType(data.type, intl)}</h3>
</Typography>
{details && (
<Typography variant="Body/Paragraph/mdRegular">
<ul className={styles.heartList}>
{details.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</Typography>
)}
{isExternalGym ? null : (
<div>
<Typography variant="Title/Subtitle/md">

View File

@@ -0,0 +1,128 @@
import { getIntl } from "@/i18n"
import {
ExternalGymDetails,
HealthFacilitiesEnum,
IndoorPoolDetails,
SaunaDetails,
} from "@/types/components/hotelPage/facilities"
interface WellnessDetails {
details: {
value: string
type: string
name: string
}[]
type: string
}
export async function translateWellnessDetails({
details,
type,
}: WellnessDetails) {
const intl = await getIntl()
switch (type) {
case HealthFacilitiesEnum.Sauna:
return details
.map(({ name, value }) => {
switch (name) {
case SaunaDetails.SeparateMenAndWomen:
if (value === "True") {
return intl.formatMessage({
defaultMessage: "Separate men and women: Yes",
})
}
return intl.formatMessage({
defaultMessage: "Separate men and women: No",
})
}
})
.filter((d): d is string => !!d)
case HealthFacilitiesEnum.OutdoorPool:
case HealthFacilitiesEnum.IndoorPool:
return details
.map(({ name, value }) => {
switch (name) {
case IndoorPoolDetails.DepthFrom:
return intl.formatMessage(
{
defaultMessage: "Pool depth from: {value} m",
},
{ value: value }
)
case IndoorPoolDetails.DepthTo:
return intl.formatMessage(
{
defaultMessage: "Pool depth to: {value} m",
},
{ value: value }
)
case IndoorPoolDetails.Length:
return intl.formatMessage(
{
defaultMessage: "Pool length: {value} m",
},
{ value: value }
)
case IndoorPoolDetails.Width:
return intl.formatMessage(
{
defaultMessage: "Pool width: {value} m",
},
{ value: value }
)
/* TODO: Awaiting clarification from Content on how to handle these parts
case OutdoorPoolDetails.OpenMonthFrom:
if (type === HealthFacilitiesEnum.OutdoorPool)
return intl.formatMessage(
{
defaultMessage: "Open from: {value}",
},
{ value: value }
)
case OutdoorPoolDetails.OpenMonthTo:
if (type === HealthFacilitiesEnum.OutdoorPool)
return intl.formatMessage(
{
defaultMessage: "Open to: {value}",
},
{ value: value }
)*/
}
})
.filter((d): d is string => !!d)
case HealthFacilitiesEnum.Gym:
if (
details.find((d) => d.name === ExternalGymDetails.ExternalGym)
?.value === "False"
)
return null
return details
.map(({ name, value }) => {
switch (name) {
case ExternalGymDetails.NameOfExternalGym:
return intl.formatMessage(
{
defaultMessage: "External gym: {value}",
},
{ value: value }
)
case ExternalGymDetails.DistanceToExternalGym:
return intl.formatMessage(
{
defaultMessage: "Distance to gym: {value} m",
},
{ value: value }
)
}
})
.filter((d): d is string => !!d)
default:
console.warn(`Unsupported type given: ${type}`)
}
}

View File

@@ -82,3 +82,29 @@ export const FacilityCardButtonText = {
MEETINGS: "Read more",
WELLNESS: "Read more",
} as const
export enum ExternalGymDetails {
NameOfExternalGym = "NameOfExternalGym",
DistanceToExternalGym = "DistanceToExternalGym",
ExternalGym = "ExternalGym",
}
export enum IndoorPoolDetails {
Length = "Length",
Width = "Width",
DepthTo = "DepthTo",
DepthFrom = "DepthFrom",
}
export enum OutdoorPoolDetails {
Length = "Length",
Width = "Width",
DepthTo = "DepthTo",
DepthFrom = "DepthFrom",
OpenMonthFrom = "OpenMonthFrom",
OpenMonthTo = "OpenMonthTo",
}
export enum SaunaDetails {
SeparateMenAndWomen = "SeparateMenAndWomen",
}