fix(SW-1042)(SW-1114)(SW-1123): fix select room bugs

This commit is contained in:
Bianca Widstam
2024-12-03 11:16:28 +01:00
parent 3c8a83ac59
commit 61f9290487
8 changed files with 173 additions and 106 deletions

View File

@@ -18,9 +18,7 @@ export default function FlexibilityOption({
name,
paymentTerm,
priceInformation,
roomType,
roomTypeCode,
features,
petRoomPackage,
handleSelectRate,
}: FlexibilityOptionProps) {
@@ -45,10 +43,22 @@ export default function FlexibilityOption({
const { public: publicPrice, member: memberPrice } = product.productType
function onChange() {
handleSelectRate({
publicRateCode: publicPrice.rateCode,
roomTypeCode: roomTypeCode,
const onClick: React.MouseEventHandler<HTMLInputElement> = (e) => {
handleSelectRate((prev) => {
if (
prev &&
prev.publicRateCode === publicPrice.rateCode &&
prev.roomTypeCode === roomTypeCode
) {
if (e.currentTarget?.checked) e.currentTarget.checked = false
return undefined
} else
return {
publicRateCode: publicPrice.rateCode,
roomTypeCode: roomTypeCode,
name: name,
paymentTerm: paymentTerm,
}
})
}
@@ -58,7 +68,7 @@ export default function FlexibilityOption({
type="radio"
name="rateCode"
value={publicPrice?.rateCode}
onChange={onChange}
onClick={onClick}
/>
<div className={styles.card}>
<div className={styles.header}>

View File

@@ -34,6 +34,7 @@ export default function RateSummary({
features,
roomType,
priceName,
priceTerm,
} = rateSummary
const priceToShow = isUserLoggedIn && member ? member : publicRate
@@ -80,87 +81,93 @@ export default function RateSummary({
</Footnote>
</div>
)}
<div className={styles.summaryText}>
<Subtitle color="uiTextHighContrast">{roomType}</Subtitle>
<Body color="uiTextMediumContrast">{priceName}</Body>
</div>
<div className={styles.summaryPriceContainer}>
{showMemberDiscountBanner && (
<div className={styles.memberDiscountBannerDesktop}>
<Footnote color="burgundy">
{intl.formatMessage<React.ReactNode>(
{
id: "To get the member price <span>{amount} {currency}</span>, log in or join when completing the booking.",
},
{
span: (str) => (
<Caption color="red" type="bold" asChild>
<span>{str}</span>
</Caption>
),
amount: member.localPrice.pricePerStay,
currency: member.localPrice.currency,
}
)}
</Footnote>
</div>
)}
<div className={styles.summaryPriceTextDesktop}>
<Body>
{intl.formatMessage<React.ReactNode>(
{ id: "<b>Total price</b> (incl VAT)" },
{ b: (str) => <b>{str}</b> }
)}
</Body>
<Caption color="uiTextMediumContrast">{summaryPriceTex}</Caption>
<div className={styles.content}>
<div className={styles.summaryText}>
<Subtitle color="uiTextHighContrast">{roomType}</Subtitle>
<Body color="uiTextMediumContrast">{`${priceName}, ${priceTerm}`}</Body>
</div>
<div className={styles.summaryPrice}>
<div className={styles.summaryPriceTextDesktop}>
<Subtitle
color={isUserLoggedIn ? "red" : "uiTextHighContrast"}
textAlign="right"
>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
</Subtitle>
<Body color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{priceToShow?.requestedPrice?.pricePerStay}{" "}
{priceToShow?.requestedPrice?.currency}
</Body>
</div>
<div className={styles.summaryPriceTextMobile}>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Total price" })}
</Caption>
<Subtitle color={isUserLoggedIn ? "red" : "uiTextHighContrast"}>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
</Subtitle>
<Footnote
color="uiTextMediumContrast"
className={styles.summaryPriceTextMobile}
>
{summaryPriceTex}
</Footnote>
</div>
{isPetRoomSelected && (
<div className={styles.petInfo}>
<Body
color="uiTextHighContrast"
textTransform="bold"
textAlign="right"
>
+ {petRoomPrice} {petRoomCurrency}
</Body>
<Body color="uiTextMediumContrast" textAlign="right">
{intl.formatMessage({ id: "Pet charge" })}
</Body>
<div className={styles.summaryPriceContainer}>
{showMemberDiscountBanner && (
<div className={styles.memberDiscountBannerDesktop}>
<Footnote color="burgundy">
{intl.formatMessage<React.ReactNode>(
{
id: "To get the member price <span>{amount} {currency}</span>, log in or join when completing the booking.",
},
{
span: (str) => (
<Caption color="red" type="bold" asChild>
<span>{str}</span>
</Caption>
),
amount: member.localPrice.pricePerStay,
currency: member.localPrice.currency,
}
)}
</Footnote>
</div>
)}
<Button type="submit" theme="base" className={styles.continueButton}>
{intl.formatMessage({ id: "Continue" })}
</Button>
<div className={styles.summaryPriceTextDesktop}>
<Body>
{intl.formatMessage<React.ReactNode>(
{ id: "<b>Total price</b> (incl VAT)" },
{ b: (str) => <b>{str}</b> }
)}
</Body>
<Caption color="uiTextMediumContrast">{summaryPriceTex}</Caption>
</div>
<div className={styles.summaryPrice}>
<div className={styles.summaryPriceTextDesktop}>
<Subtitle
color={isUserLoggedIn ? "red" : "uiTextHighContrast"}
textAlign="right"
>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
</Subtitle>
<Body color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{priceToShow?.requestedPrice?.pricePerStay}{" "}
{priceToShow?.requestedPrice?.currency}
</Body>
</div>
<div className={styles.summaryPriceTextMobile}>
<Caption color="uiTextHighContrast">
{intl.formatMessage({ id: "Total price" })}
</Caption>
<Subtitle color={isUserLoggedIn ? "red" : "uiTextHighContrast"}>
{priceToShow?.localPrice.pricePerStay}{" "}
{priceToShow?.localPrice.currency}
</Subtitle>
<Footnote
color="uiTextMediumContrast"
className={styles.summaryPriceTextMobile}
>
{summaryPriceTex}
</Footnote>
</div>
{isPetRoomSelected && (
<div className={styles.petInfo}>
<Body
color="uiTextHighContrast"
textTransform="bold"
textAlign="right"
>
+ {petRoomPrice} {petRoomCurrency}
</Body>
<Body color="uiTextMediumContrast" textAlign="right">
{intl.formatMessage({ id: "Pet charge" })}
</Body>
</div>
)}
<Button
type="submit"
theme="base"
className={styles.continueButton}
>
{intl.formatMessage({ id: "Continue" })}
</Button>
</div>
</div>
</div>
</div>

View File

@@ -6,12 +6,19 @@
right: 0;
background-color: var(--Base-Surface-Primary-light-Normal);
padding: 0 0 var(--Spacing-x5);
align-items: center;
border-top: 1px solid var(--Base-Border-Subtle);
transition: bottom 300ms ease-in-out;
}
.content {
width: 100%;
max-width: var(--max-width-navigation);
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
border-top: 1px solid var(--Base-Border-Subtle);
transition: bottom 300ms ease-in-out;
}
.summary[data-visible="true"] {
@@ -80,7 +87,9 @@
@media (min-width: 768px) {
.summary {
padding: var(--Spacing-x3) var(--Spacing-x2) var(--Spacing-x5);
padding: var(--Spacing-x3) var(--Spacing-x7) var(--Spacing-x5);
}
.content {
flex-direction: row;
}
.petInfo,
@@ -102,5 +111,6 @@
.summaryPriceContainer {
width: auto;
padding: 0;
align-items: center;
}
}

View File

@@ -26,7 +26,13 @@ export default function Rooms({
const visibleRooms: RoomConfiguration[] =
filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
const [selectedRate, setSelectedRate] = useState<
{ publicRateCode: string; roomTypeCode: string } | undefined
| {
publicRateCode: string
roomTypeCode: string
name: string
paymentTerm: string
}
| undefined
>(undefined)
const [selectedPackages, setSelectedPackages] = useState<RoomPackageCodes[]>(
[]
@@ -115,17 +121,30 @@ export default function Rooms({
)
)?.features
const roomType = roomCategories.find((roomCategory) =>
roomCategory.roomTypes.some(
(roomType) => roomType.code === room.roomTypeCode
)
)
const rateSummary: Rate = {
features: petRoomPackage && features ? features : [],
priceName: room.roomType,
priceName: selectedRate?.name,
priceTerm: selectedRate?.paymentTerm,
public: product.productType.public,
member: product.productType.member,
roomType: room.roomType,
roomType: roomType?.name || room.roomType,
roomTypeCode: room.roomTypeCode,
}
return rateSummary
}, [filteredRooms, availablePackages, selectedPackages, selectedRate])
}, [
filteredRooms,
availablePackages,
selectedPackages,
selectedRate,
roomCategories,
])
useEffect(() => {
if (rateSummary) return