Files
web/packages/booking-flow/lib/components/BookingConfirmation/Rooms/Room/index.tsx
Erik Tiekstra 4de24e9f2a feat(BOOK-391): Added theme and logos for Bassin Seven
* chore: Updated border-radius variables after import change

Approved-by: Linus Flood
2026-01-22 07:03:25 +00:00

265 lines
9.3 KiB
TypeScript

"use client"
import { useIntl } from "react-intl"
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
import {
changeOrCancelDateFormat,
longDateFormat,
} from "@scandic-hotels/common/constants/dateFormats"
import { dt } from "@scandic-hotels/common/dt"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import Image from "@scandic-hotels/design-system/Image"
import ImageFallback from "@scandic-hotels/design-system/ImageFallback"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { getHotelRoom } from "@scandic-hotels/trpc/routers/booking/helpers"
import { RoomDetailsSidePeek } from "../../../../components/RoomDetailsSidePeek"
import useLang from "../../../../hooks/useLang"
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
import styles from "./room.module.css"
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
interface RoomProps {
booking: BookingConfirmation["booking"]
checkInTime: string
checkOutTime: string
img?: NonNullable<BookingConfirmation["room"]>["images"][number]
roomName: NonNullable<BookingConfirmation["room"]>["name"]
}
export function Room({
booking,
checkInTime,
checkOutTime,
img,
roomName,
}: RoomProps) {
const intl = useIntl()
const lang = useLang()
const { roomCategories } = useBookingConfirmationStore((state) => ({
roomCategories: state.roomCategories,
}))
const room = getHotelRoom(roomCategories, booking.roomTypeCode)
const guestName = `${booking.guest.firstName} ${booking.guest.lastName}`
const fromDate = dt(booking.checkInDate).locale(lang)
const toDate = dt(booking.checkOutDate).locale(lang)
const isFlexBooking =
booking.rateDefinition.cancellationRule ===
CancellationRuleEnum.CancellableBefore6PM
const isChangeBooking =
booking.rateDefinition.cancellationRule === CancellationRuleEnum.Changeable
return (
<article className={styles.room}>
<header className={styles.header}>
<Typography variant="Title/Subtitle/md">
<h2>
{intl.formatMessage(
{
id: "bookingConfirmation.rooms.bookingNumber",
defaultMessage: "Booking number {value}",
},
{ value: booking.confirmationNumber }
)}
</h2>
</Typography>
{booking.rateDefinition.isMemberRate ? (
<div className={styles.benefits}>
<>
<MaterialIcon
color="Icon/Feedback/Success"
icon="check_circle"
size={20}
/>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "bookingConfirmation.rooms.benefitsApplied",
defaultMessage: "Membership benefits applied",
})}
</p>
</Typography>
</>
</div>
) : null}
{booking.guaranteeInfo && (
<div className={styles.benefits}>
<MaterialIcon
icon="check_circle"
color="Icon/Feedback/Success"
size={20}
/>
<Typography
variant="Body/Supporting text (caption)/smBold"
className={styles.guaranteeText}
>
<p>
{intl.formatMessage({
id: "bookingConfirmation.rooms.guaranteeTitle",
defaultMessage: "Booking guaranteed.",
})}
</p>
</Typography>
{/* eslint-disable formatjs/no-literal-string-in-jsx */}{" "}
{/* eslint-enable formatjs/no-literal-string-in-jsx */}
<Typography variant="Body/Supporting text (caption)/smRegular">
<p>
{intl.formatMessage({
id: "bookingConfirmation.rooms.guaranteeDetails",
defaultMessage:
"Your room will remain available for check-in even after 18:00.",
})}
</p>
</Typography>
</div>
)}
</header>
<div className={styles.booking}>
{img?.src ? (
<Image
alt={img.altText || img.altText_En || ""}
className={styles.img}
focalPoint={{ x: 50, y: 50 }}
height={204}
src={img.src}
style={{ borderRadius: "var(--Corner-Radius-md)" }}
title={img.title || img.title_En || ""}
width={204}
/>
) : (
<ImageFallback height="204px" />
)}
<div className={styles.roomDetails}>
<div className={styles.roomName}>
<Typography variant="Title/Subtitle/md">
<h2>{roomName}</h2>
</Typography>
{room && (
<RoomDetailsSidePeek
hotelId={booking.hotelId}
room={room}
roomTypeCode={booking.roomTypeCode}
buttonVariant="primary"
triggerLabel={intl.formatMessage({
id: "hotel.seeRoomDetails",
defaultMessage: "See room details",
})}
wrapping={false}
/>
)}
</div>
<Typography variant="Body/Paragraph/mdRegular">
<ul className={styles.details}>
<li className={styles.listItem}>
<p className={styles.label}>
{intl.formatMessage({
id: "common.checkIn",
defaultMessage: "Check-in",
})}
</p>
<p>
{intl.formatMessage(
{
id: "bookingConfirmation.rooms.checkInDetails",
defaultMessage: "{checkInDate} from {checkInTime}",
},
{
checkInDate: fromDate.format(longDateFormat[lang]),
checkInTime: checkInTime,
}
)}
</p>
</li>
<li className={styles.listItem}>
<p className={styles.label}>
{intl.formatMessage({
id: "common.checkOut",
defaultMessage: "Check-out",
})}
</p>
<p>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{`${toDate.format(longDateFormat[lang])}, ${checkOutTime}`}
</p>
</li>
<li className={styles.listItem}>
<p className={styles.label}>
{intl.formatMessage({
id: "bookingConfirmation.rooms.cancellationPolicy",
defaultMessage: "Cancellation policy",
})}
</p>
<p>{booking.rateDefinition.cancellationText}</p>
</li>
{isFlexBooking || isChangeBooking ? (
<li className={styles.listItem}>
<p className={styles.label}>
{intl.formatMessage({
id: "booking.changeOrCancel",
defaultMessage: "Change or cancel",
})}
</p>
<p>
{intl.formatMessage(
{
id: "common.untilWithTimeAndDate",
defaultMessage: "Until {time}, {date}",
},
{
time: "18:00",
date: fromDate.format(changeOrCancelDateFormat[lang]),
}
)}
</p>
</li>
) : null}
</ul>
</Typography>
<div className={styles.guest}>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.label}>
{intl.formatMessage({
id: "bookingConfirmation.rooms.guestLabel",
defaultMessage: "Guest",
})}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p data-hj-suppress>{guestName}</p>
</Typography>
{booking.guest.membershipNumber ? (
<Typography variant="Body/Paragraph/mdRegular">
<p data-hj-suppress>
{intl.formatMessage(
{
id: "bookingConfirmation.rooms.friendNumber",
defaultMessage: "Friend no. {value}",
},
{
value: booking.guest.membershipNumber,
}
)}
</p>
</Typography>
) : null}
{booking.guest.phoneNumber ? (
<Typography variant="Body/Paragraph/mdRegular">
<p data-hj-suppress>{booking.guest.phoneNumber}</p>
</Typography>
) : null}
{booking.guest.email ? (
<Typography variant="Body/Paragraph/mdRegular">
<p data-hj-suppress>{booking.guest.email}</p>
</Typography>
) : null}
</div>
</div>
</div>
</article>
)
}