Merged in fix/SW-1119-select-room-same-currency (pull request #1075)
fix(SW-1119): remove approx currency if same and synchronize price option height * fix(SW-1119): remove approx currency if same and synchronize price option height * fix(SW-1119): use debounce and observer for performance * fix(SW-1119): export selector variable to utils Approved-by: Pontus Dreij Approved-by: Niclas Edenvin
This commit is contained in:
@@ -28,7 +28,10 @@ export default function PriceList({
|
|||||||
const petRoomLocalPrice = petRoomPackage?.localPrice
|
const petRoomLocalPrice = petRoomPackage?.localPrice
|
||||||
const petRoomRequestedPrice = petRoomPackage?.requestedPrice
|
const petRoomRequestedPrice = petRoomPackage?.requestedPrice
|
||||||
|
|
||||||
const showRequestedPrice = publicRequestedPrice && memberRequestedPrice
|
const showRequestedPrice =
|
||||||
|
publicRequestedPrice &&
|
||||||
|
memberRequestedPrice &&
|
||||||
|
publicRequestedPrice.currency !== publicLocalPrice.currency
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const fromDate = searchParams.get("fromDate")
|
const fromDate = searchParams.get("fromDate")
|
||||||
const toDate = searchParams.get("toDate")
|
const toDate = searchParams.get("toDate")
|
||||||
@@ -114,27 +117,22 @@ export default function PriceList({
|
|||||||
)}
|
)}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
{showRequestedPrice && (
|
||||||
<div className={styles.priceRow}>
|
<div className={styles.priceRow}>
|
||||||
<dt>
|
<dt>
|
||||||
<Caption
|
<Caption color="uiTextMediumContrast">
|
||||||
color={showRequestedPrice ? "uiTextMediumContrast" : "disabled"}
|
{intl.formatMessage({ id: "Approx." })}
|
||||||
>
|
</Caption>
|
||||||
{intl.formatMessage({ id: "Approx." })}
|
</dt>
|
||||||
</Caption>
|
<dd>
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
{showRequestedPrice ? (
|
|
||||||
<Caption color="uiTextMediumContrast">
|
<Caption color="uiTextMediumContrast">
|
||||||
{totalPublicRequestedPricePerNight}/
|
{totalPublicRequestedPricePerNight}/
|
||||||
{totalMemberRequestedPricePerNight}{" "}
|
{totalMemberRequestedPricePerNight}{" "}
|
||||||
{publicRequestedPrice.currency}
|
{publicRequestedPrice.currency}
|
||||||
</Caption>
|
</Caption>
|
||||||
) : (
|
</dd>
|
||||||
<Caption color="disabled">- / - EUR</Caption>
|
</div>
|
||||||
)}
|
)}
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</dl>
|
</dl>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import Label from "@/components/TempDesignSystem/Form/Label"
|
|||||||
import Popover from "@/components/TempDesignSystem/Popover"
|
import Popover from "@/components/TempDesignSystem/Popover"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
|
import { rateCardEqualHeightSelector } from "../utils"
|
||||||
import PriceTable from "./PriceList"
|
import PriceTable from "./PriceList"
|
||||||
|
|
||||||
import styles from "./flexibilityOption.module.css"
|
import styles from "./flexibilityOption.module.css"
|
||||||
@@ -26,11 +27,13 @@ export default function FlexibilityOption({
|
|||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.noPricesCard}>
|
<div className={`${styles.noPricesCard} ${rateCardEqualHeightSelector}`}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<InfoCircleIcon width={16} height={16} color="uiTextMediumContrast" />
|
<InfoCircleIcon width={16} height={16} color="uiTextMediumContrast" />
|
||||||
<Caption>{name}</Caption>
|
<div className={styles.priceType}>
|
||||||
<Caption color="uiTextPlaceholder">({paymentTerm})</Caption>
|
<Caption>{name}</Caption>
|
||||||
|
<Caption color="uiTextPlaceholder">({paymentTerm})</Caption>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Label size="regular" className={styles.noPricesLabel}>
|
<Label size="regular" className={styles.noPricesLabel}>
|
||||||
<Caption color="uiTextHighContrast" type="bold">
|
<Caption color="uiTextHighContrast" type="bold">
|
||||||
@@ -70,7 +73,7 @@ export default function FlexibilityOption({
|
|||||||
value={publicPrice?.rateCode}
|
value={publicPrice?.rateCode}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
/>
|
/>
|
||||||
<div className={styles.card}>
|
<div className={`${styles.card} ${rateCardEqualHeightSelector}`}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Popover
|
<Popover
|
||||||
placement="bottom left"
|
placement="bottom left"
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useRouter, useSearchParams } from "next/navigation"
|
import { useRouter, useSearchParams } from "next/navigation"
|
||||||
import { useMemo } from "react"
|
import { useCallback, useEffect, useMemo, useRef } from "react"
|
||||||
|
|
||||||
|
import { debounce } from "@/utils/debounce"
|
||||||
|
|
||||||
import RateSummary from "./RateSummary"
|
import RateSummary from "./RateSummary"
|
||||||
import RoomCard from "./RoomCard"
|
import RoomCard from "./RoomCard"
|
||||||
import { getHotelReservationQueryParams } from "./utils"
|
import {
|
||||||
|
getHotelReservationQueryParams,
|
||||||
|
rateCardEqualHeightSelector,
|
||||||
|
} from "./utils"
|
||||||
|
|
||||||
import styles from "./roomSelection.module.css"
|
import styles from "./roomSelection.module.css"
|
||||||
|
|
||||||
@@ -23,9 +28,65 @@ export default function RoomSelection({
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const isUserLoggedIn = !!user
|
const isUserLoggedIn = !!user
|
||||||
|
const roomRefs = useRef<HTMLLIElement[]>([])
|
||||||
const { roomConfigurations, rateDefinitions } = roomsAvailability
|
const { roomConfigurations, rateDefinitions } = roomsAvailability
|
||||||
|
|
||||||
|
const equalizePriceOptionHeights = useCallback(() => {
|
||||||
|
if (!roomRefs.current.length) return
|
||||||
|
|
||||||
|
roomRefs.current.forEach((room) => {
|
||||||
|
const options = room.querySelectorAll<HTMLDivElement>(
|
||||||
|
`.${rateCardEqualHeightSelector}`
|
||||||
|
)
|
||||||
|
options.forEach((option) => {
|
||||||
|
option.style.height = "auto"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const numOptions =
|
||||||
|
roomRefs.current[0]?.querySelectorAll<HTMLDivElement>(
|
||||||
|
`.${rateCardEqualHeightSelector}`
|
||||||
|
).length || 0
|
||||||
|
|
||||||
|
for (let i = 0; i < numOptions; i++) {
|
||||||
|
let maxHeight = 0
|
||||||
|
|
||||||
|
roomRefs.current.forEach((room) => {
|
||||||
|
const option = room.querySelectorAll<HTMLDivElement>(
|
||||||
|
`.${rateCardEqualHeightSelector}`
|
||||||
|
)[i]
|
||||||
|
if (option) {
|
||||||
|
maxHeight = Math.max(maxHeight, option.offsetHeight)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
roomRefs.current.forEach((room) => {
|
||||||
|
const option = room.querySelectorAll<HTMLDivElement>(
|
||||||
|
`.${rateCardEqualHeightSelector}`
|
||||||
|
)[i]
|
||||||
|
if (option) {
|
||||||
|
option.style.height = `${maxHeight}px`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const debouncedResizeHandler = debounce(function () {
|
||||||
|
equalizePriceOptionHeights()
|
||||||
|
})
|
||||||
|
|
||||||
|
const observer = new ResizeObserver(debouncedResizeHandler)
|
||||||
|
|
||||||
|
observer.observe(document.documentElement)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (observer) {
|
||||||
|
observer.unobserve(document.documentElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [roomRefs, equalizePriceOptionHeights])
|
||||||
|
|
||||||
const queryParams = useMemo(() => {
|
const queryParams = useMemo(() => {
|
||||||
const params = new URLSearchParams(searchParams)
|
const params = new URLSearchParams(searchParams)
|
||||||
const searchParamsObject = getHotelReservationQueryParams(searchParams)
|
const searchParamsObject = getHotelReservationQueryParams(searchParams)
|
||||||
@@ -64,8 +125,13 @@ export default function RoomSelection({
|
|||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
>
|
>
|
||||||
<ul className={styles.roomList}>
|
<ul className={styles.roomList}>
|
||||||
{roomConfigurations.map((roomConfiguration) => (
|
{roomConfigurations.map((roomConfiguration, index) => (
|
||||||
<li key={roomConfiguration.roomTypeCode}>
|
<li
|
||||||
|
key={roomConfiguration.roomTypeCode}
|
||||||
|
ref={(el) => {
|
||||||
|
if (el) roomRefs.current[index] = el
|
||||||
|
}}
|
||||||
|
>
|
||||||
<RoomCard
|
<RoomCard
|
||||||
hotelId={roomsAvailability.hotelId.toString()}
|
hotelId={roomsAvailability.hotelId.toString()}
|
||||||
hotelType={hotelType}
|
hotelType={hotelType}
|
||||||
|
|||||||
@@ -101,3 +101,5 @@ export function createQueryParamsForEnterDetails(
|
|||||||
|
|
||||||
return searchParams
|
return searchParams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const rateCardEqualHeightSelector = "rateCardEqualHeight"
|
||||||
|
|||||||
Reference in New Issue
Block a user