Merged in feat/sw-2874-move-select-rate (pull request #2750)
Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
"use client"
|
||||
import { Fragment } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import useLang from "../../../hooks/useLang"
|
||||
import BookingCodeRow from "./Row/BookingCode"
|
||||
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 { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { Price } from "../../../types/price"
|
||||
|
||||
type RoomPrice =
|
||||
| CorporateChequePriceType
|
||||
| RegularPriceType
|
||||
| RedemptionPriceType
|
||||
| VoucherPriceType
|
||||
|
||||
export interface Room {
|
||||
adults: number
|
||||
bedType:
|
||||
| {
|
||||
description: string
|
||||
type: string
|
||||
roomTypeCode: string
|
||||
}
|
||||
| undefined
|
||||
breakfast: Omit<BreakfastPackage, "requestedPrice"> | false | undefined | null
|
||||
breakfastChildren?: Omit<BreakfastPackage, "requestedPrice"> | null
|
||||
breakfastIncluded: boolean
|
||||
childrenInRoom: Child[] | undefined
|
||||
packages: Packages | null
|
||||
price: RoomPrice
|
||||
rateDefinition: Pick<RateDefinition, "isMemberRate">
|
||||
roomType: string
|
||||
}
|
||||
|
||||
export interface PriceDetailsTableProps {
|
||||
bookingCode?: string
|
||||
fromDate: string
|
||||
isCampaignRate?: boolean
|
||||
rooms: Room[]
|
||||
toDate: string
|
||||
totalPrice: Price
|
||||
vat: number
|
||||
defaultCurrency: CurrencyEnum
|
||||
}
|
||||
|
||||
export default function PriceDetailsTable({
|
||||
bookingCode,
|
||||
fromDate,
|
||||
isCampaignRate,
|
||||
rooms,
|
||||
toDate,
|
||||
totalPrice,
|
||||
vat,
|
||||
defaultCurrency,
|
||||
}: PriceDetailsTableProps) {
|
||||
const intl = useIntl()
|
||||
const lang = useLang()
|
||||
|
||||
const nights = dt(toDate).diff(fromDate, "days")
|
||||
const nightsMsg = intl.formatMessage(
|
||||
{ defaultMessage: "{totalNights, plural, one {# night} other {# nights}}" },
|
||||
{ totalNights: nights }
|
||||
)
|
||||
|
||||
const arrival = dt(fromDate).locale(lang).format(longDateFormat[lang])
|
||||
const departue = dt(toDate).locale(lang).format(longDateFormat[lang])
|
||||
const duration = ` ${arrival} - ${departue} (${nightsMsg})`
|
||||
|
||||
const isAllBreakfastIncluded = rooms.every((room) => room.breakfastIncluded)
|
||||
|
||||
const allPricesIsDiscounted = rooms.every((room) => {
|
||||
if (!("regular" in room.price)) {
|
||||
return false
|
||||
}
|
||||
if (room.rateDefinition.isMemberRate) {
|
||||
return true
|
||||
}
|
||||
if (!room.price.regular) {
|
||||
return false
|
||||
}
|
||||
|
||||
return room.price.regular.pricePerStay > room.price.regular.pricePerStay
|
||||
})
|
||||
|
||||
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 isMemberRate = false
|
||||
let price: RegularPriceType["regular"] | undefined
|
||||
if ("regular" in room.price && room.price.regular) {
|
||||
price = room.price.regular
|
||||
currency = room.price.regular.currency
|
||||
isMemberRate = room.rateDefinition.isMemberRate
|
||||
}
|
||||
|
||||
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) {
|
||||
currency = defaultCurrency
|
||||
}
|
||||
|
||||
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}
|
||||
isMemberRate={isMemberRate}
|
||||
nights={nights}
|
||||
price={price}
|
||||
/>
|
||||
<CorporateChequePrice
|
||||
bedType={room.bedType}
|
||||
currency={currency}
|
||||
nights={nights}
|
||||
packages={room.packages}
|
||||
price={chequePrice}
|
||||
/>
|
||||
<RedemptionPrice
|
||||
bedType={room.bedType}
|
||||
currency={currency}
|
||||
nights={nights}
|
||||
packages={room.packages}
|
||||
price={redemptionPrice}
|
||||
/>
|
||||
<VoucherPrice
|
||||
bedType={room.bedType}
|
||||
currency={currency}
|
||||
nights={nights}
|
||||
packages={room.packages}
|
||||
price={voucherPrice}
|
||||
/>
|
||||
</Tbody>
|
||||
|
||||
<Breakfast
|
||||
adults={room.adults}
|
||||
breakfast={room.breakfast}
|
||||
breakfastChildren={room.breakfastChildren}
|
||||
breakfastIncluded={room.breakfastIncluded}
|
||||
childrenInRoom={room.childrenInRoom}
|
||||
currency={currency}
|
||||
nights={nights}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
})}
|
||||
<Tbody>
|
||||
<HeaderRow title={intl.formatMessage({ defaultMessage: "Total" })} />
|
||||
|
||||
<VatRow totalPrice={totalPrice} vat={vat} />
|
||||
|
||||
<LargeRow
|
||||
allPricesIsDiscounted={allPricesIsDiscounted}
|
||||
label={intl.formatMessage({ defaultMessage: "Price including VAT" })}
|
||||
price={totalPrice}
|
||||
/>
|
||||
|
||||
<BookingCodeRow
|
||||
isCampaignRate={isCampaignRate}
|
||||
isBreakfastIncluded={isAllBreakfastIncluded}
|
||||
bookingCode={bookingCode}
|
||||
/>
|
||||
</Tbody>
|
||||
</table>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user