Files
web/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx
2025-04-23 08:45:50 +00:00

215 lines
6.6 KiB
TypeScript

"use client"
import { Fragment } from "react"
import { useIntl } from "react-intl"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { dt } from "@/lib/dt"
import useLang from "@/hooks/useLang"
import { formatPrice } from "@/utils/numberFormatting"
import BookingCodeRow from "./Row/BookingCode"
import DiscountedRegularPriceRow from "./Row/DiscountedRegularPrice"
import HeaderRow from "./Row/Header"
import LargeRow from "./Row/Large"
import CorporateChequePrice, {
type CorporateChequePriceType,
} from "./Row/Price/CorporateCheque"
import RedemptionPrice, {
type RedemptionPriceType,
} from "./Row/Price/Redemption"
import RegularPrice, { type RegularPriceType } from "./Row/Price/Regular"
import VoucherPrice, { type VoucherPriceType } from "./Row/Price/Voucher"
import VatRow from "./Row/Vat"
import Breakfast from "./Breakfast"
import Tbody from "./Tbody"
import styles from "./priceDetailsTable.module.css"
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
import type { Price } from "@/types/components/hotelReservation/price"
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
import type { Package, Packages } from "@/types/requests/packages"
type RoomPrice =
| CorporateChequePriceType
| RegularPriceType
| RedemptionPriceType
| VoucherPriceType
export interface Room {
adults: number
bedType: BedTypeSchema | undefined
breakfast: BreakfastPackage | false | undefined | null
breakfastIncluded: boolean
childrenInRoom: Child[] | undefined
packages: Packages | null
price: RoomPrice
roomType: string
}
export interface PriceDetailsTableProps {
bookingCode?: string
fromDate: string
rooms: Room[]
toDate: string
totalPrice: Price
vat: number
}
export default function PriceDetailsTable({
bookingCode,
fromDate,
rooms,
toDate,
totalPrice,
vat,
}: PriceDetailsTableProps) {
const intl = useIntl()
const lang = useLang()
const diff = dt(toDate).diff(fromDate, "days")
const nights = intl.formatMessage(
{ defaultMessage: "{totalNights, plural, one {# night} other {# nights}}" },
{ totalNights: diff }
)
const arrival = dt(fromDate).locale(lang).format("ddd, D MMM")
const departue = dt(toDate).locale(lang).format("ddd, D MMM")
const duration = ` ${arrival} - ${departue} (${nights})`
const allRoomsPackages: Package[] = rooms
.flatMap((r) => r.packages)
.filter((r): r is Package => !!r)
return (
<table className={styles.priceDetailsTable}>
{rooms.map((room, idx) => {
let currency = ""
let chequePrice: CorporateChequePriceType["corporateCheque"] | undefined
if ("corporateCheque" in room.price && room.price.corporateCheque) {
chequePrice = room.price.corporateCheque
if (room.price.corporateCheque.currency) {
currency = room.price.corporateCheque.currency
}
}
let price: RegularPriceType["regular"] | undefined
if ("regular" in room.price && room.price.regular) {
price = room.price.regular
currency = room.price.regular.currency
}
let redemptionPrice: RedemptionPriceType["redemption"] | undefined
if ("redemption" in room.price && room.price.redemption) {
redemptionPrice = room.price.redemption
if (room.price.redemption.currency) {
currency = room.price.redemption.currency
}
}
let voucherPrice: VoucherPriceType["voucher"] | undefined
if ("voucher" in room.price && room.price.voucher) {
voucherPrice = room.price.voucher
}
if (!currency) {
if (room.packages?.length) {
currency = room.packages[0].localPrice.currency
} else if (room.breakfast) {
currency = room.breakfast.localPrice.currency
}
}
if (!price && !voucherPrice && !chequePrice && !redemptionPrice) {
return null
}
return (
<Fragment key={idx}>
<Tbody>
{rooms.length > 1 && (
<tr>
<th colSpan={2}>
<Typography variant="Body/Paragraph/mdBold">
<span>
{intl.formatMessage(
{ defaultMessage: "Room {roomIndex}" },
{ roomIndex: idx + 1 }
)}
</span>
</Typography>
</th>
</tr>
)}
<HeaderRow title={room.roomType} subtitle={duration} />
<RegularPrice
bedType={room.bedType}
packages={room.packages}
price={price}
/>
<CorporateChequePrice
bedType={room.bedType}
currency={currency}
nights={diff}
packages={room.packages}
price={chequePrice}
/>
<RedemptionPrice
bedType={room.bedType}
currency={currency}
nights={diff}
packages={room.packages}
price={redemptionPrice}
/>
<VoucherPrice
bedType={room.bedType}
currency={currency}
nights={diff}
packages={room.packages}
price={voucherPrice}
/>
</Tbody>
<Breakfast
adults={room.adults}
breakfast={room.breakfast}
breakfastIncluded={room.breakfastIncluded}
childrenInRoom={room.childrenInRoom}
currency={currency}
nights={diff}
/>
</Fragment>
)
})}
<Tbody>
<HeaderRow title={intl.formatMessage({ defaultMessage: "Total" })} />
<VatRow totalPrice={totalPrice} vat={vat} />
<LargeRow
label={intl.formatMessage({ defaultMessage: "Price including VAT" })}
value={formatPrice(
intl,
totalPrice.local.price,
totalPrice.local.currency,
totalPrice.local.additionalPrice,
totalPrice.local.additionalPriceCurrency
)}
/>
<DiscountedRegularPriceRow
currency={totalPrice.local.currency}
packages={allRoomsPackages}
regularPrice={totalPrice.local.regularPrice}
/>
<BookingCodeRow bookingCode={bookingCode} />
</Tbody>
</table>
)
}