fix: unite all price details modals to one and align on ui
This commit is contained in:
committed by
Michael Zetterberg
parent
8152aea649
commit
1f94c581ae
@@ -1,36 +0,0 @@
|
||||
.priceDetailsTable {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.price {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.tableSection {
|
||||
display: flex;
|
||||
gap: var(--Spacing-x-half);
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tableSection:has(tr > th) {
|
||||
padding-top: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.tableSection:has(tr > th):not(:first-of-type) {
|
||||
border-top: 1px solid var(--Primary-Light-On-Surface-Divider-subtle);
|
||||
}
|
||||
|
||||
.tableSection:not(:last-child) {
|
||||
padding-bottom: var(--Spacing-x2);
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
@media screen and (min-width: 768px) {
|
||||
.priceDetailsTable {
|
||||
min-width: 512px;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
|
||||
import { dt } from "@/lib/dt"
|
||||
import { useRatesStore } from "@/stores/select-rate"
|
||||
|
||||
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
|
||||
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
|
||||
@@ -18,7 +19,7 @@ import useLang from "@/hooks/useLang"
|
||||
import { formatPrice } from "@/utils/numberFormatting"
|
||||
|
||||
import { isBookingCodeRate } from "./isBookingCodeRate"
|
||||
import PriceDetailsTable from "./PriceDetailsTable"
|
||||
import { mapToPrice } from "./mapToPrice"
|
||||
|
||||
import styles from "./summary.module.css"
|
||||
|
||||
@@ -34,6 +35,7 @@ export default function Summary({
|
||||
vat,
|
||||
toggleSummaryOpen,
|
||||
}: SelectRateSummaryProps) {
|
||||
const rateSummary = useRatesStore((state) => state.rateSummary)
|
||||
const intl = useIntl()
|
||||
const lang = useLang()
|
||||
|
||||
@@ -66,6 +68,8 @@ export default function Summary({
|
||||
)
|
||||
const showDiscounted = containsBookingCodeRate || isMember
|
||||
|
||||
const priceDetailsRooms = mapToPrice(rateSummary, booking, isMember)
|
||||
|
||||
return (
|
||||
<section className={styles.summary}>
|
||||
<header className={styles.header}>
|
||||
@@ -304,17 +308,14 @@ export default function Summary({
|
||||
{ b: (str) => <b>{str}</b> }
|
||||
)}
|
||||
</Body>
|
||||
<PriceDetailsModal>
|
||||
<PriceDetailsTable
|
||||
bookingCode={booking.bookingCode}
|
||||
fromDate={booking.fromDate}
|
||||
isMember={isMember}
|
||||
rooms={rooms}
|
||||
toDate={booking.toDate}
|
||||
totalPrice={totalPrice}
|
||||
vat={vat}
|
||||
/>
|
||||
</PriceDetailsModal>
|
||||
<PriceDetailsModal
|
||||
bookingCode={booking.bookingCode}
|
||||
fromDate={booking.fromDate}
|
||||
rooms={priceDetailsRooms}
|
||||
toDate={booking.toDate}
|
||||
totalPrice={totalPrice}
|
||||
vat={vat}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Body
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import type {
|
||||
Rate,
|
||||
SelectRateSearchParams,
|
||||
} from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
import type { Room } from "@/components/HotelReservation/PriceDetailsModal/PriceDetailsTable"
|
||||
|
||||
export function mapToPrice(
|
||||
rooms: (Rate | null)[],
|
||||
booking: SelectRateSearchParams,
|
||||
isUserLoggedIn: boolean
|
||||
) {
|
||||
return rooms
|
||||
.map((room, idx) => {
|
||||
if (!room) {
|
||||
return null
|
||||
}
|
||||
|
||||
let price = null
|
||||
if ("corporateCheque" in room.product) {
|
||||
price = {
|
||||
corporateCheque: room.product.corporateCheque.localPrice,
|
||||
}
|
||||
} else if ("redemption" in room.product) {
|
||||
price = {
|
||||
redemption: room.product.redemption.localPrice,
|
||||
}
|
||||
} else if ("voucher" in room.product) {
|
||||
price = {
|
||||
voucher: room.product.voucher,
|
||||
}
|
||||
} else {
|
||||
const isMainRoom = idx === 0
|
||||
const memberRate = room.product.member
|
||||
const onlyMemberRate = !room.product.public && memberRate
|
||||
if ((isUserLoggedIn && isMainRoom && memberRate) || onlyMemberRate) {
|
||||
price = {
|
||||
regular: memberRate.localPrice,
|
||||
}
|
||||
} else if (room.product.public) {
|
||||
price = {
|
||||
regular: room.product.public.localPrice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bookingRoom = booking.rooms[idx]
|
||||
return {
|
||||
adults: bookingRoom.adults,
|
||||
bedType: undefined,
|
||||
breakfast: undefined,
|
||||
breakfastIncluded: room.product.rateDefinition.breakfastIncluded,
|
||||
childrenInRoom: bookingRoom.childrenInRoom,
|
||||
packages: room.packages,
|
||||
price,
|
||||
roomType: room.roomType,
|
||||
}
|
||||
})
|
||||
.filter((r) => !!(r && r.price)) as Room[]
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||
import { CurrencyEnum } from "@/types/enums/currency"
|
||||
import type { Packages } from "@/types/requests/packages"
|
||||
import type { RedemptionProduct } from "@/types/trpc/routers/hotel/roomAvailability"
|
||||
|
||||
export function calculateTotalPrice(
|
||||
@@ -87,16 +90,28 @@ export function calculateTotalPrice(
|
||||
}
|
||||
|
||||
export function calculateRedemptionTotalPrice(
|
||||
redemption: RedemptionProduct["redemption"]
|
||||
redemption: RedemptionProduct["redemption"],
|
||||
packages: Packages | null
|
||||
) {
|
||||
const pkgsSum = sumPackages(packages)
|
||||
let additionalPrice
|
||||
if (redemption.localPrice.additionalPricePerStay) {
|
||||
additionalPrice =
|
||||
redemption.localPrice.additionalPricePerStay + pkgsSum.price
|
||||
} else if (pkgsSum.price) {
|
||||
additionalPrice = pkgsSum.price
|
||||
}
|
||||
|
||||
let additionalPriceCurrency
|
||||
if (redemption.localPrice.currency) {
|
||||
additionalPriceCurrency = redemption.localPrice.currency
|
||||
} else if (pkgsSum.currency) {
|
||||
additionalPriceCurrency = pkgsSum.currency
|
||||
}
|
||||
return {
|
||||
local: {
|
||||
additionalPrice: redemption.localPrice.additionalPricePerStay
|
||||
? redemption.localPrice.additionalPricePerStay
|
||||
: undefined,
|
||||
additionalPriceCurrency: redemption.localPrice.currency
|
||||
? redemption.localPrice.currency
|
||||
: undefined,
|
||||
additionalPrice,
|
||||
additionalPriceCurrency,
|
||||
currency: CurrencyEnum.POINTS,
|
||||
price: redemption.localPrice.pointsPerStay,
|
||||
},
|
||||
@@ -111,13 +126,9 @@ export function calculateVoucherPrice(selectedRateSummary: Rate[]) {
|
||||
}
|
||||
const rate = room.product.voucher
|
||||
|
||||
return {
|
||||
local: {
|
||||
currency: total.local.currency,
|
||||
price: total.local.price + rate.numberOfVouchers,
|
||||
},
|
||||
requested: undefined,
|
||||
}
|
||||
total.local.price = total.local.price + rate.numberOfVouchers
|
||||
|
||||
return total
|
||||
},
|
||||
{
|
||||
local: {
|
||||
@@ -136,12 +147,17 @@ export function calculateCorporateChequePrice(selectedRateSummary: Rate[]) {
|
||||
return total
|
||||
}
|
||||
const rate = room.product.corporateCheque
|
||||
const pkgsSum = sumPackages(room.packages)
|
||||
|
||||
total.local.price = total.local.price + rate.localPrice.numberOfCheques
|
||||
if (rate.localPrice.additionalPricePerStay) {
|
||||
total.local.additionalPrice =
|
||||
(total.local.additionalPrice || 0) +
|
||||
rate.localPrice.additionalPricePerStay
|
||||
rate.localPrice.additionalPricePerStay +
|
||||
pkgsSum.price
|
||||
} else if (pkgsSum.price) {
|
||||
total.local.additionalPrice =
|
||||
(total.local.additionalPrice || 0) + pkgsSum.price
|
||||
}
|
||||
if (rate.localPrice.currency) {
|
||||
total.local.additionalPriceCurrency = rate.localPrice.currency
|
||||
@@ -196,11 +212,11 @@ export function getTotalPrice(
|
||||
return calculateTotalPrice(summaryArray, isUserLoggedIn)
|
||||
}
|
||||
|
||||
const { product } = mainRoomProduct
|
||||
const { packages, product } = mainRoomProduct
|
||||
|
||||
// In case of reward night (redemption) or voucher only single room booking is supported by business rules
|
||||
if ("redemption" in product) {
|
||||
return calculateRedemptionTotalPrice(product.redemption)
|
||||
return calculateRedemptionTotalPrice(product.redemption, packages)
|
||||
}
|
||||
if ("voucher" in product) {
|
||||
return calculateVoucherPrice(summaryArray)
|
||||
|
||||
@@ -4,6 +4,10 @@ import { useIntl } from "react-intl"
|
||||
import CampaignRateCard from "@scandic-hotels/design-system/CampaignRateCard"
|
||||
import NoRateAvailableCard from "@scandic-hotels/design-system/NoRateAvailableCard"
|
||||
|
||||
import {
|
||||
sumPackages,
|
||||
sumPackagesRequestedPrice,
|
||||
} from "@/components/HotelReservation/utils"
|
||||
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||
|
||||
@@ -22,11 +26,15 @@ export default function Campaign({
|
||||
campaign,
|
||||
handleSelectRate,
|
||||
nights,
|
||||
petRoomPackage,
|
||||
roomTypeCode,
|
||||
}: CampaignProps) {
|
||||
const intl = useIntl()
|
||||
const { roomNr, selectedFilter, selectedRate } = useRoomContext()
|
||||
const {
|
||||
roomNr,
|
||||
selectedFilter,
|
||||
selectedPackages,
|
||||
selectedRate,
|
||||
} = useRoomContext()
|
||||
const rateTitles = useRateTitles()
|
||||
|
||||
const isCampaignRate = campaign.some(
|
||||
@@ -52,6 +60,9 @@ export default function Campaign({
|
||||
campaign = campaign.filter((product) => !product.bookingCode)
|
||||
}
|
||||
|
||||
const pkgsSum = sumPackages(selectedPackages)
|
||||
const pkgsSumRequested = sumPackagesRequestedPrice(selectedPackages)
|
||||
|
||||
return campaign.map((product) => {
|
||||
if (!product.public) {
|
||||
return (
|
||||
@@ -67,21 +78,21 @@ export default function Campaign({
|
||||
|
||||
const rateTermDetails = product.rateDefinitionMember
|
||||
? [
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
{
|
||||
title: product.rateDefinitionMember.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
{
|
||||
title: product.rateDefinitionMember.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
|
||||
const isSelected = isSelectedPriceProduct(
|
||||
product,
|
||||
@@ -110,16 +121,18 @@ export default function Campaign({
|
||||
product.public.localPrice.pricePerNight,
|
||||
product.public.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
|
||||
const pricePerNightMember = product.member
|
||||
? calculatePricePerNightPriceProduct(
|
||||
product.member.localPrice.pricePerNight,
|
||||
product.member.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
)
|
||||
product.member.localPrice.pricePerNight,
|
||||
product.member.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
: undefined
|
||||
|
||||
let approximateRatePrice = undefined
|
||||
@@ -135,12 +148,12 @@ export default function Campaign({
|
||||
const approximateRate =
|
||||
approximateRatePrice && product.public.requestedPrice
|
||||
? {
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Approx.",
|
||||
}),
|
||||
price: approximateRatePrice,
|
||||
unit: product.public.requestedPrice.currency,
|
||||
}
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Approx.",
|
||||
}),
|
||||
price: approximateRatePrice,
|
||||
unit: product.public.requestedPrice.currency,
|
||||
}
|
||||
: undefined
|
||||
|
||||
return (
|
||||
@@ -154,12 +167,12 @@ export default function Campaign({
|
||||
memberRate={
|
||||
pricePerNightMember
|
||||
? {
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Member price",
|
||||
}),
|
||||
price: pricePerNightMember.totalPrice,
|
||||
unit: `${product.member!.localPrice.currency}/${night}`,
|
||||
}
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Member price",
|
||||
}),
|
||||
price: pricePerNightMember.totalPrice,
|
||||
unit: `${product.member!.localPrice.currency}/${night}`,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
name={`rateCode-${roomNr}-${product.public.rateCode}`}
|
||||
@@ -173,15 +186,15 @@ export default function Campaign({
|
||||
omnibusRate={
|
||||
product.public.localPrice.omnibusPricePerNight
|
||||
? {
|
||||
label: intl
|
||||
.formatMessage({
|
||||
defaultMessage: "Lowest price (last 30 days)",
|
||||
})
|
||||
.toUpperCase(),
|
||||
price:
|
||||
product.public.localPrice.omnibusPricePerNight.toString(),
|
||||
unit: product.public.localPrice.currency,
|
||||
}
|
||||
label: intl
|
||||
.formatMessage({
|
||||
defaultMessage: "Lowest price (last 30 days)",
|
||||
})
|
||||
.toUpperCase(),
|
||||
price:
|
||||
product.public.localPrice.omnibusPricePerNight.toString(),
|
||||
unit: product.public.localPrice.currency,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
rateTermDetails={rateTermDetails}
|
||||
|
||||
@@ -6,6 +6,10 @@ import CodeRateCard from "@scandic-hotels/design-system/CodeRateCard"
|
||||
|
||||
import { useRatesStore } from "@/stores/select-rate"
|
||||
|
||||
import {
|
||||
sumPackages,
|
||||
sumPackagesRequestedPrice,
|
||||
} from "@/components/HotelReservation/utils"
|
||||
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||
|
||||
@@ -28,11 +32,11 @@ export default function Code({
|
||||
code,
|
||||
handleSelectRate,
|
||||
nights,
|
||||
petRoomPackage,
|
||||
roomTypeCode,
|
||||
}: CodeProps) {
|
||||
const intl = useIntl()
|
||||
const { roomNr, selectedFilter, selectedRate } = useRoomContext()
|
||||
const { roomNr, selectedFilter, selectedPackages, selectedRate } =
|
||||
useRoomContext()
|
||||
const bookingCode = useRatesStore((state) => state.booking.bookingCode)
|
||||
const rateTitles = useRateTitles()
|
||||
const night = intl
|
||||
@@ -74,11 +78,16 @@ export default function Code({
|
||||
},
|
||||
]
|
||||
|
||||
const pkgsSum = sumPackages(selectedPackages)
|
||||
const pkgsSumRequested = sumPackagesRequestedPrice(selectedPackages)
|
||||
|
||||
if ("corporateCheque" in product) {
|
||||
const { localPrice, rateCode } = product.corporateCheque
|
||||
let price = `${localPrice.numberOfCheques} CC`
|
||||
if (localPrice.additionalPricePerStay) {
|
||||
price = `${price} + ${localPrice.additionalPricePerStay}`
|
||||
price = `${price} + ${localPrice.additionalPricePerStay + pkgsSum.price}`
|
||||
} else if (pkgsSum.price) {
|
||||
price = `${price} + ${pkgsSum.price}`
|
||||
}
|
||||
|
||||
const isSelected = isSelectedCorporateCheque(
|
||||
@@ -87,6 +96,8 @@ export default function Code({
|
||||
roomTypeCode
|
||||
)
|
||||
|
||||
const currency = localPrice.currency ?? pkgsSum.currency?.toString() ?? ""
|
||||
|
||||
return (
|
||||
<CodeRateCard
|
||||
key={product.rate}
|
||||
@@ -98,7 +109,7 @@ export default function Code({
|
||||
rate={{
|
||||
label: product.rateDefinition?.title,
|
||||
price,
|
||||
unit: localPrice.currency ?? "",
|
||||
unit: currency,
|
||||
}}
|
||||
rateTitle={rateTitles[product.rate].title}
|
||||
rateTermDetails={rateTermDetails}
|
||||
@@ -140,7 +151,8 @@ export default function Code({
|
||||
localPrice.pricePerNight,
|
||||
requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
|
||||
const approximateRate = pricePerNight.totalRequestedPrice
|
||||
@@ -157,7 +169,8 @@ export default function Code({
|
||||
localPrice.regularPricePerNight,
|
||||
requestedPrice?.regularPricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
|
||||
const comparisonRate =
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useIntl } from "react-intl"
|
||||
|
||||
import PointsRateCard from "@scandic-hotels/design-system/PointsRateCard"
|
||||
|
||||
import { sumPackages } from "@/components/HotelReservation/utils"
|
||||
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||
|
||||
@@ -21,7 +22,7 @@ export default function Redemptions({
|
||||
}: RedemptionsProps) {
|
||||
const intl = useIntl()
|
||||
const rateTitles = useRateTitles()
|
||||
const { selectedFilter, selectedRate } = useRoomContext()
|
||||
const { selectedFilter, selectedPackages, selectedRate } = useRoomContext()
|
||||
|
||||
if (
|
||||
selectedFilter === BookingCodeFilterEnum.Discounted ||
|
||||
@@ -34,6 +35,8 @@ export default function Redemptions({
|
||||
const rewardNight = intl.formatMessage({
|
||||
defaultMessage: "Reward night",
|
||||
})
|
||||
const pkgsSum = sumPackages(selectedPackages)
|
||||
|
||||
const breakfastIncluded = intl.formatMessage({
|
||||
defaultMessage: "Breakfast included",
|
||||
})
|
||||
@@ -58,20 +61,34 @@ export default function Redemptions({
|
||||
}
|
||||
}
|
||||
|
||||
const rates = redemptions.map((r) => ({
|
||||
additionalPrice:
|
||||
r.redemption.localPrice.additionalPricePerStay &&
|
||||
r.redemption.localPrice.currency
|
||||
? {
|
||||
currency: r.redemption.localPrice.currency,
|
||||
price: r.redemption.localPrice.additionalPricePerStay.toString(),
|
||||
const rates = redemptions.map((r) => {
|
||||
let additionalPrice
|
||||
if (r.redemption.localPrice.additionalPricePerStay) {
|
||||
additionalPrice =
|
||||
r.redemption.localPrice.additionalPricePerStay + pkgsSum.price
|
||||
} else if (pkgsSum.price) {
|
||||
additionalPrice = pkgsSum.price
|
||||
}
|
||||
let additionalPriceCurrency
|
||||
if (r.redemption.localPrice.currency) {
|
||||
additionalPriceCurrency = r.redemption.localPrice.currency
|
||||
} else if (pkgsSum.currency) {
|
||||
additionalPriceCurrency = pkgsSum.currency
|
||||
}
|
||||
return {
|
||||
additionalPrice:
|
||||
additionalPrice && additionalPriceCurrency
|
||||
? {
|
||||
currency: additionalPriceCurrency,
|
||||
price: additionalPrice.toString(),
|
||||
}
|
||||
: undefined,
|
||||
currency: "PTS",
|
||||
isDisabled: !r.redemption.hasEnoughPoints,
|
||||
points: r.redemption.localPrice.pointsPerStay.toString(),
|
||||
rateCode: r.redemption.rateCode,
|
||||
}))
|
||||
: undefined,
|
||||
currency: "PTS",
|
||||
isDisabled: !r.redemption.hasEnoughPoints,
|
||||
points: r.redemption.localPrice.pointsPerStay.toString(),
|
||||
rateCode: r.redemption.rateCode,
|
||||
}
|
||||
})
|
||||
|
||||
const notEnoughPoints = rates.every((rate) => rate.isDisabled)
|
||||
const firstRedemption = redemptions[0]
|
||||
|
||||
@@ -6,6 +6,10 @@ import RegularRateCard from "@scandic-hotels/design-system/RegularRateCard"
|
||||
|
||||
import { useRatesStore } from "@/stores/select-rate"
|
||||
|
||||
import {
|
||||
sumPackages,
|
||||
sumPackagesRequestedPrice,
|
||||
} from "@/components/HotelReservation/utils"
|
||||
import { useRoomContext } from "@/contexts/SelectRate/Room"
|
||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||
|
||||
@@ -34,13 +38,13 @@ interface RegularProps extends SharedRateCardProps {
|
||||
export default function Regular({
|
||||
handleSelectRate,
|
||||
nights,
|
||||
petRoomPackage,
|
||||
regular,
|
||||
roomTypeCode,
|
||||
}: RegularProps) {
|
||||
const intl = useIntl()
|
||||
const rateTitles = useRateTitles()
|
||||
const { isMainRoom, roomNr, selectedFilter, selectedRate } = useRoomContext()
|
||||
const { isMainRoom, roomNr, selectedFilter, selectedPackages, selectedRate } =
|
||||
useRoomContext()
|
||||
const isUserLoggedIn = useRatesStore((state) => state.isUserLoggedIn)
|
||||
|
||||
if (selectedFilter === BookingCodeFilterEnum.Discounted) {
|
||||
@@ -52,6 +56,8 @@ export default function Regular({
|
||||
defaultMessage: "night",
|
||||
})
|
||||
.toUpperCase()
|
||||
const pkgsSum = sumPackages(selectedPackages)
|
||||
const pkgsSumRequested = sumPackagesRequestedPrice(selectedPackages)
|
||||
|
||||
return regular.map((product) => {
|
||||
const { member, public: standard } = product
|
||||
@@ -81,19 +87,21 @@ export default function Regular({
|
||||
|
||||
const memberPricePerNight = member
|
||||
? calculatePricePerNightPriceProduct(
|
||||
member.localPrice.pricePerNight,
|
||||
member.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
)
|
||||
member.localPrice.pricePerNight,
|
||||
member.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
: undefined
|
||||
const standardPricePerNight = standard
|
||||
? calculatePricePerNightPriceProduct(
|
||||
standard.localPrice.pricePerNight,
|
||||
standard.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
petRoomPackage
|
||||
)
|
||||
standard.localPrice.pricePerNight,
|
||||
standard.requestedPrice?.pricePerNight,
|
||||
nights,
|
||||
pkgsSum.price,
|
||||
pkgsSumRequested.price
|
||||
)
|
||||
: undefined
|
||||
|
||||
let approximateMemberRatePrice = null
|
||||
@@ -141,12 +149,12 @@ export default function Regular({
|
||||
const approximateRate =
|
||||
approximatePrice && requestedCurrency
|
||||
? {
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Approx.",
|
||||
}),
|
||||
price: approximatePrice,
|
||||
unit: requestedCurrency,
|
||||
}
|
||||
label: intl.formatMessage({
|
||||
defaultMessage: "Approx.",
|
||||
}),
|
||||
price: approximatePrice,
|
||||
unit: requestedCurrency,
|
||||
}
|
||||
: undefined
|
||||
|
||||
const isSelected = isSelectedPriceProduct(
|
||||
@@ -157,21 +165,21 @@ export default function Regular({
|
||||
|
||||
const rateTermDetails = product.rateDefinitionMember
|
||||
? [
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
{
|
||||
title: product.rateDefinitionMember.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
{
|
||||
title: product.rateDefinitionMember.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
{
|
||||
title: product.rateDefinition.title,
|
||||
terms: product.rateDefinition.generalTerms,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<RegularRateCard
|
||||
|
||||
@@ -14,7 +14,6 @@ import Redemptions from "./Redemptions"
|
||||
import Regular from "./Regular"
|
||||
|
||||
import type { RatesProps } from "@/types/components/hotelReservation/selectRate/rates"
|
||||
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||
import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter"
|
||||
import type { Product } from "@/types/trpc/routers/hotel/roomAvailability"
|
||||
|
||||
@@ -35,7 +34,6 @@ export default function Rates({
|
||||
actions: { selectRate },
|
||||
isFetchingAdditionalRate,
|
||||
selectedFilter,
|
||||
selectedPackages,
|
||||
} = useRoomContext()
|
||||
const nights = useRatesStore((state) =>
|
||||
dt(state.booking.toDate).diff(state.booking.fromDate, "days")
|
||||
@@ -44,14 +42,9 @@ export default function Rates({
|
||||
selectRate({ features, product, roomType, roomTypeCode })
|
||||
}
|
||||
|
||||
const petRoomPackageSelected = selectedPackages.find(
|
||||
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
|
||||
)
|
||||
|
||||
const sharedProps = {
|
||||
handleSelectRate,
|
||||
nights,
|
||||
petRoomPackage: petRoomPackageSelected,
|
||||
roomTypeCode,
|
||||
}
|
||||
const showAllRates = selectedFilter === BookingCodeFilterEnum.All
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import type { Package } from "@/types/requests/packages"
|
||||
|
||||
export function calculatePricePerNightPriceProduct(
|
||||
pricePerNight: number,
|
||||
requestedPricePerNight: number | undefined,
|
||||
nights: number,
|
||||
petRoomPackage?: Package
|
||||
packagesSumLocal: number,
|
||||
packagesSumRequested: number
|
||||
) {
|
||||
const totalPrice = petRoomPackage?.localPrice
|
||||
? Math.floor(pricePerNight + petRoomPackage.localPrice.price / nights)
|
||||
const totalPrice = packagesSumLocal
|
||||
? Math.floor(pricePerNight + packagesSumLocal / nights)
|
||||
: Math.floor(pricePerNight)
|
||||
|
||||
let totalRequestedPrice = undefined
|
||||
if (requestedPricePerNight) {
|
||||
if (petRoomPackage?.requestedPrice) {
|
||||
if (packagesSumRequested) {
|
||||
totalRequestedPrice = Math.floor(
|
||||
requestedPricePerNight + petRoomPackage.requestedPrice.price / nights
|
||||
requestedPricePerNight + packagesSumRequested / nights
|
||||
)
|
||||
} else {
|
||||
totalRequestedPrice = Math.floor(requestedPricePerNight)
|
||||
|
||||
Reference in New Issue
Block a user