Files
web/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/Room/index.tsx
2025-04-02 15:00:39 +00:00

186 lines
5.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons"
import { CancellationRuleEnum, ChildBedTypeEnum } from "@/constants/booking"
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
import Modal from "@/components/Modal"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import { formatPrice } from "@/utils/numberFormatting"
import RoomSkeletonLoader from "./RoomSkeletonLoader"
import styles from "./room.module.css"
import type { BookingConfirmationReceiptRoomProps } from "@/types/components/hotelReservation/bookingConfirmation/receipt"
export default function ReceiptRoom({
roomIndex,
}: BookingConfirmationReceiptRoomProps) {
const intl = useIntl()
const { room, currencyCode } = useBookingConfirmationStore((state) => ({
room: state.rooms[roomIndex],
currencyCode: state.currencyCode,
}))
if (!room) {
return <RoomSkeletonLoader />
}
const childBedCrib = room.childBedPreferences.find(
(c) => c.bedType === ChildBedTypeEnum.Crib
)
const childBedExtraBed = room.childBedPreferences.find(
(c) => c.bedType === ChildBedTypeEnum.ExtraBed
)
return (
<article className={styles.room}>
<header className={styles.roomHeader}>
<Body color="uiTextHighContrast">{room.name}</Body>
{room.rateDefinition.isMemberRate ? (
<div className={styles.memberPrice}>
<Body color="red">
{formatPrice(intl, room.roomPrice, currencyCode)}
</Body>
</div>
) : (
<Body color="uiTextHighContrast">
{formatPrice(intl, room.roomPrice, currencyCode)}
</Body>
)}
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
totalAdults: room.adults,
}
)}
</Caption>
<Caption color="uiTextMediumContrast">
{room.rateDefinition.cancellationText}
</Caption>
<Modal
trigger={
<Button intent="text" className={styles.termsLink}>
<Link
color="peach80"
href=""
size="small"
textDecoration="underline"
variant="icon"
>
{intl.formatMessage({ id: "Reservation policy" })}
<MaterialIcon icon="info" color="CurrentColor" />
</Link>
</Button>
}
title={room.rateDefinition.cancellationText || ""}
subtitle={
room.rateDefinition.cancellationRule ===
CancellationRuleEnum.CancellableBefore6PM
? intl.formatMessage({ id: "Pay later" })
: intl.formatMessage({ id: "Pay now" })
}
>
<div className={styles.terms}>
{room.rateDefinition.generalTerms?.map((info) => (
<Body
key={info}
color="uiTextHighContrast"
className={styles.termsText}
>
<MaterialIcon
icon="check"
color="Icon/Feedback/Success"
size={20}
className={styles.termsIcon}
/>
{info}
</Body>
))}
</div>
</Modal>
</header>
{room.roomFeatures
? room.roomFeatures.map((feature) => (
<div className={styles.entry} key={feature.code}>
<div>
<Body color="uiTextHighContrast">{feature.description}</Body>
</div>
<Body color="uiTextHighContrast">
{formatPrice(intl, feature.totalPrice, feature.currency)}
</Body>
</div>
))
: null}
<div className={styles.entry}>
<Body color="uiTextHighContrast">{room.bedDescription}</Body>
<Body color="uiTextHighContrast">
{formatPrice(intl, 0, currencyCode)}
</Body>
</div>
{childBedCrib ? (
<div className={styles.entry}>
<div>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Crib (child) × {count}" },
{ count: childBedCrib.quantity }
)}
</Body>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Based on availability" })}
</Caption>
</div>
<Body color="uiTextHighContrast">
{formatPrice(intl, 0, currencyCode)}
</Body>
</div>
) : null}
{childBedExtraBed ? (
<div className={styles.entry}>
<div>
<Body color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Extra bed (child) × {count}" },
{
count: childBedExtraBed.quantity,
}
)}
</Body>
</div>
<Body color="uiTextHighContrast">
{formatPrice(intl, 0, currencyCode)}
</Body>
</div>
) : null}
{room.breakfast || room.breakfastIncluded ? (
<div className={styles.entry}>
<Body>{intl.formatMessage({ id: "Breakfast buffet" })}</Body>
{(room.rateDefinition.breakfastIncluded ?? room.breakfastIncluded) ? (
<Body color="red">{intl.formatMessage({ id: "Included" })}</Body>
) : null}
{room.breakfast ? (
<Body color="uiTextHighContrast">
{formatPrice(
intl,
room.breakfast.totalPrice,
room.breakfast.currency
)}
</Body>
) : null}
</div>
) : null}
</article>
)
}