feat(SW-1717): rewrite select-rate to show all variants of rate-cards
This commit is contained in:
committed by
Michael Zetterberg
parent
adde77eaa9
commit
ebaea78fb3
@@ -21,17 +21,15 @@ import {
|
||||
|
||||
import MobileSummary from "./MobileSummary"
|
||||
import {
|
||||
calculateChequePrice,
|
||||
calculateCorporateChequePrice,
|
||||
calculateRedemptionTotalPrice,
|
||||
calculateTotalPrice,
|
||||
calculateVoucherPrice,
|
||||
} from "./utils"
|
||||
|
||||
import styles from "./rateSummary.module.css"
|
||||
|
||||
import {
|
||||
PointsPriceSchema,
|
||||
type Price,
|
||||
} from "@/types/components/hotelReservation/price"
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { RateSummaryProps } from "@/types/components/hotelReservation/selectRate/rateSummary"
|
||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
@@ -40,7 +38,6 @@ import { RateTypeEnum } from "@/types/enums/rateType"
|
||||
export default function RateSummary({ isUserLoggedIn }: RateSummaryProps) {
|
||||
const {
|
||||
bookingCode,
|
||||
isRedemption,
|
||||
bookingRooms,
|
||||
dates,
|
||||
petRoomPackage,
|
||||
@@ -105,7 +102,9 @@ export default function RateSummary({ isUserLoggedIn }: RateSummaryProps) {
|
||||
|
||||
const totalRoomsRequired = bookingRooms.length
|
||||
const isAllRoomsSelected = rateSummary.length === totalRoomsRequired
|
||||
const hasMemberRates = rateSummary.some((room) => room.member)
|
||||
const hasMemberRates = rateSummary.some(
|
||||
(room) => "member" in room.product && room.product.member
|
||||
)
|
||||
const showMemberDiscountBanner = hasMemberRates && !isUserLoggedIn
|
||||
|
||||
const freeCancelation = intl.formatMessage({ id: "Free cancellation" })
|
||||
@@ -139,21 +138,31 @@ export default function RateSummary({ isUserLoggedIn }: RateSummaryProps) {
|
||||
}
|
||||
|
||||
const isBookingCodeRate = rateSummary.some(
|
||||
(rate) => rate.public?.rateType !== RateTypeEnum.Regular
|
||||
(rate) =>
|
||||
"public" in rate.product &&
|
||||
rate.product.public?.rateType !== RateTypeEnum.Regular
|
||||
)
|
||||
const isVoucherRate = rateSummary.some((rate) => "voucher" in rate.product)
|
||||
const isCorporateChequeRate = rateSummary.some(
|
||||
(rate) => "corporateCheque" in rate.product
|
||||
)
|
||||
const isVoucherRate = rateSummary.some((rate) => rate.voucher)
|
||||
const isChequeRate = rateSummary.some((rate) => rate.bonusCheque)
|
||||
const showDiscounted =
|
||||
isUserLoggedIn || isBookingCodeRate || isVoucherRate || isChequeRate
|
||||
isUserLoggedIn ||
|
||||
isBookingCodeRate ||
|
||||
isVoucherRate ||
|
||||
isCorporateChequeRate
|
||||
|
||||
const mainRoomProduct = rateSummary[0]
|
||||
let totalPriceToShow: Price
|
||||
if (isVoucherRate) {
|
||||
totalPriceToShow = calculateVoucherPrice(rateSummary)
|
||||
} else if (isChequeRate) {
|
||||
totalPriceToShow = calculateChequePrice(rateSummary)
|
||||
} else if (rateSummary[0].redemption) {
|
||||
if ("redemption" in mainRoomProduct.product) {
|
||||
// In case of reward night (redemption) only single room booking is supported by business rules
|
||||
totalPriceToShow = PointsPriceSchema.parse(rateSummary[0].redemption)
|
||||
totalPriceToShow = calculateRedemptionTotalPrice(
|
||||
mainRoomProduct.product.redemption
|
||||
)
|
||||
} else if ("voucher" in mainRoomProduct.product) {
|
||||
totalPriceToShow = calculateVoucherPrice(rateSummary)
|
||||
} else if ("corporateCheque" in mainRoomProduct.product) {
|
||||
totalPriceToShow = calculateCorporateChequePrice(rateSummary)
|
||||
} else {
|
||||
totalPriceToShow = calculateTotalPrice(
|
||||
rateSummary,
|
||||
@@ -162,40 +171,53 @@ export default function RateSummary({ isUserLoggedIn }: RateSummaryProps) {
|
||||
)
|
||||
}
|
||||
|
||||
let mainRoomCurrency = ""
|
||||
if (
|
||||
"member" in mainRoomProduct.product &&
|
||||
mainRoomProduct.product.member?.localPrice
|
||||
) {
|
||||
mainRoomCurrency = mainRoomProduct.product.member.localPrice.currency
|
||||
}
|
||||
if (
|
||||
!mainRoomCurrency &&
|
||||
"public" in mainRoomProduct.product &&
|
||||
mainRoomProduct.product.public?.localPrice
|
||||
) {
|
||||
mainRoomCurrency = mainRoomProduct.product.public.localPrice.currency
|
||||
}
|
||||
|
||||
return (
|
||||
<form action={`details?${params}`} method="GET" onSubmit={handleSubmit}>
|
||||
<div className={styles.summary}>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.summaryText}>
|
||||
{rateSummary.map((room, index) => {
|
||||
return (
|
||||
<div key={index} className={styles.roomSummary}>
|
||||
{rateSummary.length > 1 ? (
|
||||
<>
|
||||
<Subtitle color="uiTextHighContrast">
|
||||
{intl.formatMessage(
|
||||
{ id: "Room {roomIndex}" },
|
||||
{ roomIndex: index + 1 }
|
||||
)}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">{room.roomType}</Body>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{getRateDetails(room.rate)}
|
||||
</Caption>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Subtitle color="uiTextHighContrast">
|
||||
{room.roomType}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">
|
||||
{getRateDetails(room.rate)}
|
||||
</Body>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{rateSummary.map((room, index) => (
|
||||
<div key={index} className={styles.roomSummary}>
|
||||
{rateSummary.length > 1 ? (
|
||||
<>
|
||||
<Subtitle color="uiTextHighContrast">
|
||||
{intl.formatMessage(
|
||||
{ id: "Room {roomIndex}" },
|
||||
{ roomIndex: index + 1 }
|
||||
)}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">{room.roomType}</Body>
|
||||
<Caption color="uiTextMediumContrast">
|
||||
{getRateDetails(room.rate)}
|
||||
</Caption>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Subtitle color="uiTextHighContrast">
|
||||
{room.roomType}
|
||||
</Subtitle>
|
||||
<Body color="uiTextMediumContrast">
|
||||
{getRateDetails(room.rate)}
|
||||
</Body>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{/* Render unselected rooms */}
|
||||
{Array.from({
|
||||
length: totalRoomsRequired - rateSummary.length,
|
||||
@@ -218,28 +240,34 @@ export default function RateSummary({ isUserLoggedIn }: RateSummaryProps) {
|
||||
<div className={styles.promoContainer}>
|
||||
<SignupPromoDesktop
|
||||
memberPrice={{
|
||||
amount: rateSummary.reduce((total, room) => {
|
||||
const memberPrice = room.member?.localPrice.pricePerStay
|
||||
if (!memberPrice) {
|
||||
return total
|
||||
}
|
||||
const hasSelectedPetRoom =
|
||||
room.package === RoomPackageCodeEnum.PET_ROOM
|
||||
if (!hasSelectedPetRoom) {
|
||||
return total + memberPrice
|
||||
}
|
||||
const isPetRoom = room.features.find(
|
||||
(feature) =>
|
||||
feature.code === RoomPackageCodeEnum.PET_ROOM
|
||||
)
|
||||
const petRoomPrice =
|
||||
isPetRoom && petRoomPackage
|
||||
? Number(petRoomPackage.localPrice.totalPrice)
|
||||
: 0
|
||||
return total + memberPrice + petRoomPrice
|
||||
}, 0),
|
||||
currency: (rateSummary[0].member?.localPrice.currency ??
|
||||
rateSummary[0].public?.localPrice.currency)!,
|
||||
amount: rateSummary.reduce(
|
||||
(total, { features, package: roomPackage, product }) => {
|
||||
if (!("member" in product) || !product.member) {
|
||||
return total
|
||||
}
|
||||
const memberPrice =
|
||||
product.member.localPrice.pricePerStay
|
||||
if (!memberPrice) {
|
||||
return total
|
||||
}
|
||||
const hasSelectedPetRoom =
|
||||
roomPackage === RoomPackageCodeEnum.PET_ROOM
|
||||
if (!hasSelectedPetRoom) {
|
||||
return total + memberPrice
|
||||
}
|
||||
const isPetRoom = features.find(
|
||||
(feature) =>
|
||||
feature.code === RoomPackageCodeEnum.PET_ROOM
|
||||
)
|
||||
const petRoomPrice =
|
||||
isPetRoom && petRoomPackage
|
||||
? Number(petRoomPackage.localPrice.totalPrice)
|
||||
: 0
|
||||
return total + memberPrice + petRoomPrice
|
||||
},
|
||||
0
|
||||
),
|
||||
currency: mainRoomCurrency,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user