fix(SW-1241): Adjusted amenities sidepeek on hotel pages and booking flow

Approved-by: Michael Zetterberg
Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-04-23 08:41:04 +00:00
parent c23a32cd10
commit 8152aea649
46 changed files with 654 additions and 731 deletions

View File

@@ -1,18 +1,21 @@
import Body from "@/components/TempDesignSystem/Text/Body"
import { getIntl } from "@/i18n"
"use client"
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import styles from "./parkingList.module.css"
import type { ParkingListProps } from "@/types/components/hotelPage/sidepeek/parking"
export default async function ParkingList({
export default function ParkingList({
numberOfChargingSpaces,
canMakeReservation,
numberOfParkingSpots,
distanceToHotel,
address,
}: ParkingListProps) {
const intl = await getIntl()
const intl = useIntl()
const canMakeReservationYesMsg = intl.formatMessage({
defaultMessage: "Parking can be reserved in advance: Yes",
@@ -22,7 +25,7 @@ export default async function ParkingList({
})
return (
<Body color="uiTextHighContrast" asChild>
<Typography variant="Body/Paragraph/mdRegular">
<ul className={styles.listStyling}>
{numberOfChargingSpaces ? (
<li>
@@ -71,6 +74,6 @@ export default async function ParkingList({
</li>
) : null}
</ul>
</Body>
</Typography>
)
}

View File

@@ -1,5 +1,9 @@
import Body from "@/components/TempDesignSystem/Text/Body"
import { getIntl } from "@/i18n"
"use client"
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { formatPrice } from "@/utils/numberFormatting"
import { getPeriod } from "./utils"
@@ -11,28 +15,28 @@ import {
Periods,
} from "@/types/components/hotelPage/sidepeek/parking"
export default async function ParkingPrices({
export default function ParkingPrices({
currency = "",
freeParking,
pricing,
}: ParkingPricesProps) {
const intl = await getIntl()
const intl = useIntl()
return freeParking ? (
<Body textTransform="bold" color="uiTextHighContrast">
{intl.formatMessage({
defaultMessage: "Free parking",
})}
</Body>
<Typography variant="Body/Paragraph/mdBold">
<p className={styles.wrapper}>
{intl.formatMessage({ defaultMessage: "Free parking" })}
</p>
</Typography>
) : (
<dl className={styles.wrapper}>
{pricing?.map((parking) => (
<div key={parking.period} className={styles.period}>
<div className={styles.information}>
<Body textTransform="bold" color="uiTextHighContrast" asChild>
<Typography variant="Body/Paragraph/mdBold">
<dt>{getPeriod(intl, parking.period)}</dt>
</Body>
<Body color="uiTextHighContrast" asChild>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<dd>
{parking.amount
? formatPrice(intl, parking.amount, currency)
@@ -40,24 +44,17 @@ export default async function ParkingPrices({
defaultMessage: "At a cost",
})}
</dd>
</Body>
</Typography>
</div>
{parking.startTime &&
parking.endTime &&
parking.period !== Periods.allDay && (
<div className={styles.information}>
<Body color="uiTextHighContrast" asChild>
<dt>
{intl.formatMessage({
defaultMessage: "From",
})}
</dt>
</Body>
<Body color="uiTextHighContrast" asChild>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Typography variant="Body/Paragraph/mdRegular">
<div className={styles.information}>
<dt>{intl.formatMessage({ defaultMessage: "From" })}</dt>
<dd>{`${parking.startTime}-${parking.endTime}`}</dd>
</Body>
</div>
</div>
</Typography>
)}
</div>
))}

View File

@@ -2,6 +2,7 @@
display: grid;
row-gap: var(--Spacing-x1);
margin: 0;
color: var(--Text-Default);
}
.period {
@@ -13,3 +14,7 @@
margin: 0;
flex: 1;
}
.priceHeading {
color: var(--Text-Secondary);
}

View File

@@ -1,13 +1,13 @@
import Link from "next/link"
"use client"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getIntl } from "@/i18n"
import ButtonLink from "@/components/ButtonLink"
import Divider from "@/components/TempDesignSystem/Divider"
import Button from "../TempDesignSystem/Button"
import Divider from "../TempDesignSystem/Divider"
import Caption from "../TempDesignSystem/Text/Caption"
import Subtitle from "../TempDesignSystem/Text/Subtitle"
import ParkingList from "./ParkingList"
import ParkingPrices from "./ParkingPrices"
@@ -20,17 +20,19 @@ interface ParkingInformationProps {
showExternalParkingButton?: boolean
}
export default async function ParkingInformation({
export default function ParkingInformation({
parking,
showExternalParkingButton = true,
}: ParkingInformationProps) {
const intl = await getIntl()
const intl = useIntl()
const title = `${parking.type}${parking.name ? ` (${parking.name})` : ""}`
return (
<div className={styles.parkingInformation}>
<div className={styles.list}>
<Subtitle type="two" asChild>
<h4>{parking.type}</h4>
</Subtitle>
<Typography variant="Title/Subtitle/md">
<h4 className={styles.heading}>{title}</h4>
</Typography>
<ParkingList
numberOfChargingSpaces={parking.numberOfChargingSpaces}
canMakeReservation={parking.canMakeReservation}
@@ -40,19 +42,17 @@ export default async function ParkingInformation({
/>
</div>
<div className={styles.prices}>
<Subtitle type="two" asChild>
<h5>
{intl.formatMessage({
defaultMessage: "Prices",
})}
<Typography variant="Body/Paragraph/mdBold">
<h5 className={styles.heading}>
{intl.formatMessage({ defaultMessage: "Prices" })}
</h5>
</Subtitle>
</Typography>
<div className={styles.priceWrapper}>
<Caption color="uiTextMediumContrast" textTransform="uppercase">
{intl.formatMessage({
defaultMessage: "Weekday prices",
})}
</Caption>
<Typography variant="Title/Overline/sm">
<h6 className={styles.priceHeading}>
{intl.formatMessage({ defaultMessage: "Weekday prices" })}
</h6>
</Typography>
<Divider color="baseSurfaceSubtleHover" />
{parking.pricing.localCurrency ? (
<ParkingPrices
@@ -63,11 +63,11 @@ export default async function ParkingInformation({
) : null}
</div>
<div className={styles.priceWrapper}>
<Caption color="uiTextMediumContrast" textTransform="uppercase">
{intl.formatMessage({
defaultMessage: "Weekend prices",
})}
</Caption>
<Typography variant="Title/Overline/sm">
<h6 className={styles.priceHeading}>
{intl.formatMessage({ defaultMessage: "Weekend prices" })}
</h6>
</Typography>
<Divider color="baseSurfaceSubtleHover" />
{parking.pricing.localCurrency ? (
<ParkingPrices
@@ -79,14 +79,10 @@ export default async function ParkingInformation({
</div>
</div>
{parking.externalParkingUrl && showExternalParkingButton && (
<Button theme="base" intent="primary" variant="icon" asChild>
<Link href={parking.externalParkingUrl} target="_blank">
{intl.formatMessage({
defaultMessage: "Book parking",
})}
<MaterialIcon icon="open_in_new" color="CurrentColor" />
</Link>
</Button>
<ButtonLink href={parking.externalParkingUrl} target="_blank">
{intl.formatMessage({ defaultMessage: "Book parking" })}
<MaterialIcon icon="open_in_new" color="CurrentColor" />
</ButtonLink>
)}
</div>
)

View File

@@ -16,3 +16,11 @@
display: grid;
gap: var(--Spacing-x1);
}
.heading {
color: var(--Text-Default);
}
.priceHeading {
color: var(--Text-Secondary);
}