Files
web/apps/scandic-web/components/HotelReservation/BookingConfirmation/Receipt/Room/index.tsx
Hrishikesh Vaipurkar ae1010bfce Merged in feat/SW-2079-update-booking-page-to-show-points- (pull request #1683)
feat: SW-2079 Show points in confirmation page

* feat: SW-2079 Show points in confirmation page

* feat: SW-2079 Optimized code

* feat: SW-2079 Updated Body to Typography

* feat: SW-2079 Multi-room total cost display

* feat: SW-2079 Add reward nights condition rate title

* feat: SW-2079 Removed extra checks

* feat: SW-2079 Optimmized formatPrice function

* feat: SW-2079 Typo fix


Approved-by: Christian Andolf
2025-04-04 09:39:55 +00:00

228 lines
7.7 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 { 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 } = useBookingConfirmationStore((state) => ({
room: state.rooms[roomIndex],
currencyCode: state.currencyCode,
}))
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}>
{formatPrice(intl, room.roomPrice, currencyCode)}
</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={
(room.roomPoints
? room.rateDefinition.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) => (
<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>
)
}