Files
web/components/HotelReservation/SelectRate/RoomSelection/index.tsx
Linus Flood fa20f128ef Merged in feat/check-session-fix-2 (pull request #1154)
fix: is user logged in fix

* fix: is user logged in fix
2025-01-08 15:38:36 +00:00

173 lines
5.2 KiB
TypeScript

"use client"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { useSession } from "next-auth/react"
import { useCallback, useEffect, useMemo, useRef } from "react"
import { debounce } from "@/utils/debounce"
import { isValidSession } from "@/utils/session"
import RateSummary from "./RateSummary"
import RoomCard from "./RoomCard"
import {
getHotelReservationQueryParams,
RATE_CARD_EQUAL_HEIGHT_CLASS,
RATE_CARDS_AVAILABLE_HEIGHT_CLASS,
RATE_CARDS_NOT_AVAILABLE_HEIGHT_CLASS,
} from "./utils"
import styles from "./roomSelection.module.css"
import type { RoomSelectionProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
export default function RoomSelection({
roomsAvailability,
roomCategories,
availablePackages,
selectedPackages,
isUserLoggedIn,
setRateCode,
rateSummary,
hotelType,
}: RoomSelectionProps) {
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
const roomRefs = useRef<HTMLLIElement[]>([])
const { roomConfigurations, rateDefinitions } = roomsAvailability
const equalizePriceOptionHeights = useCallback(() => {
if (!roomRefs.current.length) return
const optionsSelector = `.${RATE_CARD_EQUAL_HEIGHT_CLASS}`
const availableSelector = `.${RATE_CARDS_AVAILABLE_HEIGHT_CLASS}`
const notAvailableSelector = `.${RATE_CARDS_NOT_AVAILABLE_HEIGHT_CLASS}`
const DEFAULT_RATE_CARD_HEIGHT = 380
const maxOptionHeights: number[] = []
let maxPriceCardHeight = DEFAULT_RATE_CARD_HEIGHT
roomRefs.current.forEach((room) => {
const options = room.querySelectorAll<HTMLDivElement>(optionsSelector)
options.forEach((option, i) => {
option.style.height = "auto"
const optionHeight = option.getBoundingClientRect().height
maxOptionHeights[i] = Math.max(maxOptionHeights[i] || 0, optionHeight)
})
const priceCard = room.querySelector(availableSelector) as HTMLElement
if (priceCard) {
const priceCardHeight = priceCard.getBoundingClientRect().height
maxPriceCardHeight = Math.max(maxPriceCardHeight, priceCardHeight)
}
})
roomRefs.current.forEach((room) => {
const options = room.querySelectorAll<HTMLDivElement>(optionsSelector)
options.forEach((option, i) => {
if (option) {
option.style.height = `${maxOptionHeights[i]}px`
}
})
const noPriceCard = room.querySelector(
notAvailableSelector
) as HTMLElement
if (noPriceCard) {
noPriceCard.style.height = `${maxPriceCardHeight}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 params = new URLSearchParams(searchParams)
const searchParamsObject = getHotelReservationQueryParams(searchParams)
searchParamsObject.room.forEach((item, index) => {
if (rateSummary?.roomTypeCode) {
params.set(`room[${index}].roomtype`, rateSummary.roomTypeCode)
}
if (rateSummary?.public?.rateCode) {
params.set(`room[${index}].ratecode`, rateSummary.public.rateCode)
}
if (rateSummary?.member?.rateCode) {
params.set(
`room[${index}].counterratecode`,
rateSummary.member.rateCode
)
}
selectedPackages.length > 0
? params.set(`room[${index}].packages`, selectedPackages.join(","))
: params.delete(`room[${index}].packages`)
})
return params
}, [searchParams, rateSummary, selectedPackages])
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
window.history.replaceState(
null,
"",
`${pathname}?${queryParams.toString()}`
)
router.push(`select-bed?${queryParams}`)
}
return (
<div className={styles.wrapper}>
<form
method="GET"
action={`select-bed?${searchParams}`}
onSubmit={handleSubmit}
>
<ul className={styles.roomList}>
{roomConfigurations.map((roomConfiguration, index) => (
<li
key={roomConfiguration.roomTypeCode}
ref={(el) => {
if (el) roomRefs.current[index] = el
}}
>
<RoomCard
hotelId={roomsAvailability.hotelId.toString()}
hotelType={hotelType}
rateDefinitions={rateDefinitions}
roomConfiguration={roomConfiguration}
roomCategories={roomCategories}
handleSelectRate={setRateCode}
selectedPackages={selectedPackages}
packages={availablePackages}
/>
</li>
))}
</ul>
{rateSummary && (
<RateSummary
rateSummary={rateSummary}
isUserLoggedIn={isUserLoggedIn}
packages={availablePackages}
roomsAvailability={roomsAvailability}
/>
)}
</form>
</div>
)
}