Files
web/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/Room/index.tsx
Hrishikesh Vaipurkar 73cb423c95 Merged in feat/SW-2078-update-confirmation-page-vouchers (pull request #1731)
Feat/SW-2078 update confirmation page vouchers and Corp Cheques rate

* feat: SW-2078 Tablet bookingCode ref forward issue fix

(cherry picked from commit 16a6a00fd99b6b6220a98ad74de062d67d35e1c0)

* feat: SW-2078 Display Vouchers and Cheques prices on confirmation page

(cherry picked from commit a76494de497a7d5e7641cb0036bd7055acf875c1)

* feat: SW-2078 Rebase issue fix

* feat: SW-2079 Updated rate title in terms modal

* feat: SW-2078 Optimized code

* feat: SW-2078 Removed extra tags


Approved-by: Christian Andolf
2025-04-08 07:27:40 +00:00

231 lines
7.8 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/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
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 { 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, isVatCurrency } = useBookingConfirmationStore(
(state) => ({
room: state.rooms[roomIndex],
currencyCode: state.currencyCode,
isVatCurrency: state.isVatCurrency,
})
)
if (!room) {
return <RoomSkeletonLoader />
}
const breakfastIncluded =
room.breakfastIncluded || room.rateDefinition.breakfastIncluded
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}>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>{room.name}</p>
</Typography>
{room.rateDefinition.isMemberRate ? (
<div className={styles.memberPrice}>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.red}>{room.formattedTotalCost}</p>
</Typography>
</div>
) : (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{room.formattedTotalCost}
</p>
</Typography>
)}
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextMediumContrast}>
{intl.formatMessage(
{ id: "{totalAdults, plural, one {# adult} other {# adults}}" },
{
totalAdults: room.adults,
}
)}
</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextMediumContrast}>
{room.rateDefinition.cancellationText}
</p>
</Typography>
<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={
(isVatCurrency
? room.rateDefinition.cancellationText
: room.rateDefinition.title) || ""
}
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) => (
<Typography
key={info}
className={styles.termsText}
variant="Body/Paragraph/mdRegular"
>
<span>
<MaterialIcon
icon="check"
color="Icon/Feedback/Success"
size={20}
className={styles.termsIcon}
/>
{info}
</span>
</Typography>
))}
</div>
</Modal>
</header>
{room.roomFeatures
? room.roomFeatures.map((feature) => (
<div className={styles.entry} key={feature.code}>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{feature.description}
</p>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{formatPrice(intl, feature.totalPrice, feature.currency)}
</p>
</Typography>
</div>
))
: null}
<div className={styles.entry}>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>{room.bedDescription}</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{formatPrice(intl, 0, currencyCode)}
</p>
</Typography>
</div>
{childBedCrib ? (
<div className={styles.entry}>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage(
{ id: "Crib (child) × {count}" },
{ count: childBedCrib.quantity }
)}
</p>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage({ id: "Based on availability" })}
</p>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{formatPrice(intl, 0, currencyCode)}
</p>
</Typography>
</div>
) : null}
{childBedExtraBed ? (
<div className={styles.entry}>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{intl.formatMessage(
{ id: "Extra bed (child) × {count}" },
{
count: childBedExtraBed.quantity,
}
)}
</p>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{formatPrice(intl, 0, currencyCode)}
</p>
</Typography>
</div>
) : null}
{room.breakfast || breakfastIncluded ? (
<div className={styles.entry}>
<Typography variant="Body/Paragraph/mdRegular">
<p>{intl.formatMessage({ id: "Breakfast buffet" })}</p>
</Typography>
{breakfastIncluded ? (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.red}>
{intl.formatMessage({ id: "Included" })}
</p>
</Typography>
) : null}
{room.breakfast && !breakfastIncluded ? (
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.uiTextHighContrast}>
{formatPrice(
intl,
room.breakfast.totalPrice,
room.breakfast.currency
)}
</p>
</Typography>
) : null}
</div>
) : null}
</article>
)
}