fix(SW-3616): Handle EuroBonus point type everywhere * Add tests to formatPrice * formatPrice * More work replacing config with api points type * More work replacing config with api points type * More fixing with currency * maybe actually fixed it * Fix MyStay * Clean up * Fix comments * Merge branch 'master' into fix/refactor-currency-display * Fix calculateTotalPrice for EB points + SF points + cash Approved-by: Joakim Jäderberg
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
"use client"
|
|
|
|
import { useIntl } from "react-intl"
|
|
|
|
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
|
import { dt } from "@scandic-hotels/common/dt"
|
|
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
|
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
|
|
import useLang from "../../../hooks/useLang"
|
|
import { useBookingConfirmationStore } from "../../../stores/booking-confirmation"
|
|
import { ReceiptRoom } from "./Room"
|
|
import TotalPrice from "./TotalPrice"
|
|
|
|
import styles from "./receipt.module.css"
|
|
|
|
export function Receipt() {
|
|
const lang = useLang()
|
|
const intl = useIntl()
|
|
const { rooms, fromDate, toDate, bookingCode } = useBookingConfirmationStore(
|
|
(state) => ({
|
|
rooms: state.rooms,
|
|
fromDate: state.fromDate,
|
|
toDate: state.toDate,
|
|
bookingCode: state.bookingCode,
|
|
})
|
|
)
|
|
|
|
const totalNights = dt(toDate).diff(fromDate, "days")
|
|
const isCampaignRate = rooms.every(
|
|
(room) => room?.rateDefinition.isCampaignRate
|
|
)
|
|
|
|
const nights = intl.formatMessage(
|
|
{
|
|
id: "booking.numberOfNights",
|
|
defaultMessage: "{totalNights, plural, one {# night} other {# nights}}",
|
|
},
|
|
{ totalNights }
|
|
)
|
|
|
|
const filteredRooms = rooms.filter(
|
|
(room): room is NonNullable<typeof room> => !!room
|
|
)
|
|
|
|
return (
|
|
<section className={styles.receipt}>
|
|
<header>
|
|
<Typography variant="Title/Subtitle/md">
|
|
<h3 className={styles.heading}>
|
|
{intl.formatMessage({
|
|
id: "booking.bookingSummary",
|
|
defaultMessage: "Booking summary",
|
|
})}
|
|
</h3>
|
|
</Typography>
|
|
<Typography variant="Body/Paragraph/mdBold">
|
|
<p className={styles.dates}>
|
|
{dt(fromDate).locale(lang).format(longDateFormat[lang])}
|
|
<MaterialIcon icon="arrow_forward" size={15} color="CurrentColor" />
|
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
|
{dt(toDate).locale(lang).format(longDateFormat[lang])} ({nights})
|
|
</p>
|
|
</Typography>
|
|
</header>
|
|
|
|
<Divider color="Border/Divider/Subtle" />
|
|
|
|
{filteredRooms.map((room, idx) => (
|
|
<ReceiptRoom
|
|
key={room ? room.confirmationNumber : `loader-${idx}`}
|
|
room={room}
|
|
roomNumber={idx + 1}
|
|
roomCount={rooms.length}
|
|
showBookingCodeChip={
|
|
rooms.length !== 1 &&
|
|
(room.rateDefinition.isCampaignRate || !!bookingCode)
|
|
}
|
|
/>
|
|
))}
|
|
|
|
<TotalPrice />
|
|
{rooms.length === 1 && (isCampaignRate || !!bookingCode) && (
|
|
<BookingCodeChip
|
|
isCampaign={isCampaignRate}
|
|
bookingCode={bookingCode}
|
|
alignCenter
|
|
/>
|
|
)}
|
|
</section>
|
|
)
|
|
}
|