feat(SW-718) Refactor select rate to support multiroom

This commit is contained in:
Pontus Dreij
2025-01-21 10:31:15 +01:00
parent 7d716dcf4a
commit edcf146ce1
27 changed files with 202 additions and 131 deletions

View File

@@ -0,0 +1,143 @@
import { useSearchParams } from "next/navigation"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { calculatePricesPerNight } from "./utils"
import styles from "./priceList.module.css"
import type { PriceListProps } from "@/types/components/hotelReservation/selectRate/flexibilityOption"
export default function PriceList({
publicPrice = {},
memberPrice = {},
petRoomPackage,
}: PriceListProps) {
const intl = useIntl()
const { localPrice: publicLocalPrice, requestedPrice: publicRequestedPrice } =
publicPrice
const { localPrice: memberLocalPrice, requestedPrice: memberRequestedPrice } =
memberPrice
const petRoomLocalPrice = petRoomPackage?.localPrice
const petRoomRequestedPrice = petRoomPackage?.requestedPrice
const showRequestedPrice =
publicRequestedPrice &&
memberRequestedPrice &&
publicRequestedPrice.currency !== publicLocalPrice.currency
const searchParams = useSearchParams()
const fromDate = searchParams.get("fromDate")
const toDate = searchParams.get("toDate")
let nights = 1
if (fromDate && toDate) {
nights = dt(toDate).diff(dt(fromDate), "days")
}
const {
totalPublicLocalPricePerNight,
totalMemberLocalPricePerNight,
totalPublicRequestedPricePerNight,
totalMemberRequestedPricePerNight,
} = calculatePricesPerNight({
publicLocalPrice,
memberLocalPrice,
publicRequestedPrice,
memberRequestedPrice,
petRoomLocalPrice,
petRoomRequestedPrice,
nights,
})
return (
<dl className={styles.priceList}>
<div className={styles.priceRow}>
<dt>
<Caption
type="bold"
color={
totalPublicLocalPricePerNight ? "uiTextHighContrast" : "disabled"
}
>
{intl.formatMessage({ id: "Standard price" })}
</Caption>
</dt>
<dd>
{publicLocalPrice ? (
<div className={styles.price}>
<Subtitle type="two" color="uiTextHighContrast">
{totalPublicLocalPricePerNight}
</Subtitle>
<Body color="uiTextHighContrast" textTransform="bold">
{publicLocalPrice.currency}
<span className={styles.perNight}>
/{intl.formatMessage({ id: "night" })}
</span>
</Body>
</div>
) : (
<Subtitle type="two" color="baseTextDisabled">
{intl.formatMessage({ id: "N/A" })}
</Subtitle>
)}
</dd>
</div>
<div className={styles.priceRow}>
<dt>
<Caption type="bold" color={memberLocalPrice ? "red" : "disabled"}>
{intl.formatMessage({ id: "Member price" })}
</Caption>
</dt>
<dd>
{memberLocalPrice ? (
<div className={styles.price}>
<Subtitle type="two" color="red">
{totalMemberLocalPricePerNight}
</Subtitle>
<Body color="red" textTransform="bold">
{memberLocalPrice.currency}
<span className={styles.perNight}>
/{intl.formatMessage({ id: "night" })}
</span>
</Body>
</div>
) : (
<Body textTransform="bold" color="disabled">
-
</Body>
)}
</dd>
</div>
{showRequestedPrice && (
<div className={styles.priceRow}>
<dt>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}
</Caption>
</dt>
<dd>
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{ id: "{publicPrice}/{memberPrice} {currency}" },
{
publicPrice: totalPublicRequestedPricePerNight,
memberPrice: totalMemberRequestedPricePerNight,
currency: publicRequestedPrice.currency,
}
)}
</Caption>
</dd>
</div>
)}
</dl>
)
}

View File

@@ -0,0 +1,23 @@
.priceList {
margin: 0;
}
.priceRow {
display: flex;
justify-content: space-between;
align-items: baseline;
}
.priceTable {
margin: 0;
}
.price {
display: flex;
gap: var(--Spacing-x-half);
}
.perNight {
font-weight: 400;
font-size: var(--typography-Caption-Regular-fontSize);
}

View File

@@ -0,0 +1,54 @@
import type { CalculatePricesPerNightProps } from "@/types/components/hotelReservation/selectRate/roomCard"
export function calculatePricesPerNight({
publicLocalPrice,
memberLocalPrice,
publicRequestedPrice,
memberRequestedPrice,
petRoomLocalPrice,
petRoomRequestedPrice,
nights,
}: CalculatePricesPerNightProps) {
const totalPublicLocalPricePerNight = publicLocalPrice
? petRoomLocalPrice
? Math.floor(
Number(publicLocalPrice.pricePerNight) +
Number(petRoomLocalPrice.price) / nights
)
: Math.floor(Number(publicLocalPrice.pricePerNight))
: undefined
const totalMemberLocalPricePerNight = memberLocalPrice
? petRoomLocalPrice
? Math.floor(
Number(memberLocalPrice.pricePerNight) +
Number(petRoomLocalPrice.price) / nights
)
: Math.floor(Number(memberLocalPrice.pricePerNight))
: undefined
const totalPublicRequestedPricePerNight = publicRequestedPrice
? petRoomRequestedPrice
? Math.floor(
Number(publicRequestedPrice.pricePerNight) +
Number(petRoomRequestedPrice.price) / nights
)
: Math.floor(Number(publicRequestedPrice.pricePerNight))
: undefined
const totalMemberRequestedPricePerNight = memberRequestedPrice
? petRoomRequestedPrice
? Math.floor(
Number(memberRequestedPrice.pricePerNight) +
Number(petRoomRequestedPrice.price) / nights
)
: Math.floor(Number(memberRequestedPrice.pricePerNight))
: undefined
return {
totalPublicLocalPricePerNight,
totalMemberLocalPricePerNight,
totalPublicRequestedPricePerNight,
totalMemberRequestedPricePerNight,
}
}