feat/sw-1602 preliminary receipt * feat(sw-1602): create page for preliminary receipt * Add link to my stay page Approved-by: Pontus Dreij
186 lines
6.6 KiB
TypeScript
186 lines
6.6 KiB
TypeScript
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
|
|
import Divider from "@/components/TempDesignSystem/Divider"
|
|
import { getIntl } from "@/i18n"
|
|
|
|
import styles from "./specification.module.css"
|
|
|
|
import type { SpecificationProps } from "@/types/components/hotelReservation/myStay/receipt"
|
|
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
|
|
|
export default async function Specification({
|
|
ancillaryPackages,
|
|
booking,
|
|
currency,
|
|
}: SpecificationProps) {
|
|
const intl = await getIntl()
|
|
|
|
const breakfastPackages = booking.packages.filter(
|
|
(p) => p.type === "Breakfast"
|
|
)
|
|
const breakfastTotalPriceInMoney = breakfastPackages
|
|
.filter((p) => p.currency !== "Points")
|
|
.reduce((acc, curr) => acc + curr.totalPrice, 0)
|
|
const breakfastTotalPriceInPoints = breakfastPackages
|
|
.filter((p) => p.currency === "Points")
|
|
.reduce((acc, curr) => acc + curr.totalPrice, 0)
|
|
|
|
const breakfastCount = breakfastPackages.reduce(
|
|
(acc, curr) => acc + curr.unit,
|
|
0
|
|
)
|
|
|
|
const breakfastMoneyString =
|
|
breakfastTotalPriceInMoney > 0
|
|
? `${breakfastTotalPriceInMoney} ${currency}`
|
|
: ""
|
|
const breakfastPointsString =
|
|
breakfastTotalPriceInPoints > 0
|
|
? `${breakfastTotalPriceInPoints} ${intl.formatMessage({ id: "Points" })}`
|
|
: ""
|
|
const breakfastPlusString =
|
|
breakfastMoneyString && breakfastPointsString ? " + " : ""
|
|
|
|
const petRoomPackage = booking.packages.find(
|
|
(p) => p.code === RoomPackageCodeEnum.PET_ROOM
|
|
)
|
|
|
|
const roomPriceExclVat =
|
|
booking.roomPrice - (booking.roomPrice * booking.vatPercentage) / 100
|
|
const roomPriceVat = booking.roomPrice - roomPriceExclVat
|
|
|
|
return (
|
|
<div className={styles.container}>
|
|
<div>
|
|
{/****** The room ********/}
|
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
<span>
|
|
{intl.formatMessage({ id: "Accommodation" })}
|
|
{!booking.rateDefinition.mustBeGuaranteed && (
|
|
<>
|
|
{" - "}
|
|
{intl.formatMessage({ id: "Room is prepaid" })}
|
|
</>
|
|
)}
|
|
</span>
|
|
</Typography>
|
|
<dl className={styles.dl}>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt>{intl.formatMessage({ id: "Price including VAT" })}</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd>
|
|
{!booking.rateDefinition.mustBeGuaranteed &&
|
|
`(${intl.formatMessage({ id: "PREPAID" })}) `}
|
|
{`${booking.roomPrice} ${currency}`}
|
|
</dd>
|
|
</Typography>
|
|
|
|
{petRoomPackage && (
|
|
<>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt>
|
|
{intl.formatMessage({ id: "Pet room charge including VAT" })}
|
|
</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd>{`${petRoomPackage.totalPrice} ${petRoomPackage.currency}`}</dd>
|
|
</Typography>
|
|
</>
|
|
)}
|
|
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt className={styles.tertiary}>
|
|
{intl.formatMessage({ id: "Price excluding VAT" })}
|
|
</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd
|
|
className={styles.tertiary}
|
|
>{`${roomPriceExclVat.toFixed(2)} ${currency}`}</dd>
|
|
</Typography>
|
|
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt className={styles.tertiary}>
|
|
{intl.formatMessage({ id: "VAT" })} {booking.vatPercentage} %
|
|
</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd
|
|
className={styles.tertiary}
|
|
>{`${roomPriceVat.toFixed(2)} ${currency}`}</dd>
|
|
</Typography>
|
|
</dl>
|
|
</div>
|
|
|
|
{/****** Ancillaries ********/}
|
|
{booking.ancillaries.map((ancillary) => (
|
|
<>
|
|
<Divider color="subtle" />
|
|
<div>
|
|
<div className={styles.quantifyingHeader}>
|
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
<span>
|
|
{ancillaryPackages?.flatMap((a) =>
|
|
a.ancillaryContent.filter(
|
|
(aa) =>
|
|
aa.id === ancillary.code ||
|
|
aa.loyaltyCode === ancillary.code
|
|
)
|
|
)[0]?.title ?? intl.formatMessage({ id: "Unknown item" })}
|
|
</span>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
<span>{`x ${ancillary.unit}`}</span>
|
|
</Typography>
|
|
</div>
|
|
|
|
<dl className={styles.dl}>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt>
|
|
{ancillary.currency !== "Points"
|
|
? intl.formatMessage({ id: "Price including VAT" })
|
|
: intl.formatMessage({ id: "Price" })}
|
|
</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd>{`${ancillary.totalPrice} ${ancillary.currency}`}</dd>
|
|
</Typography>
|
|
</dl>
|
|
</div>
|
|
</>
|
|
))}
|
|
|
|
{/****** Breakfast ********/}
|
|
{breakfastCount > 0 && (
|
|
<>
|
|
<Divider color="subtle" />
|
|
<div>
|
|
<div className={styles.quantifyingHeader}>
|
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
<span>{intl.formatMessage({ id: "Breakfast" })}</span>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
|
<span>{`x ${breakfastCount}`}</span>
|
|
</Typography>
|
|
</div>
|
|
|
|
<dl className={styles.dl}>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dt>
|
|
{breakfastTotalPriceInMoney > 0
|
|
? intl.formatMessage({ id: "Price including VAT" })
|
|
: intl.formatMessage({ id: "Price" })}
|
|
</dt>
|
|
</Typography>
|
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
<dd>{`${breakfastMoneyString}${breakfastPlusString}${breakfastPointsString}`}</dd>
|
|
</Typography>
|
|
</dl>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|