"use client" import { useSearchParams } from "next/navigation" import { useEffect } from "react" import { useIntl } from "react-intl" import { alternativeHotels } from "@/constants/routes/hotelReservation" import { useBookingCodeFilterStore } from "@/stores/bookingCode-filter" import { useRatesStore } from "@/stores/select-rate" import BookingCodeFilter from "@/components/HotelReservation/SelectHotel/BookingCodeFilter" import Alert from "@/components/TempDesignSystem/Alert" import { useRoomContext } from "@/contexts/SelectRate/Room" import useLang from "@/hooks/useLang" import RoomCard from "./RoomCard" import RoomTypeFilter from "./RoomTypeFilter" import styles from "./roomSelectionPanel.module.css" import { AvailabilityEnum } from "@/types/components/hotelReservation/selectHotel/selectHotel" import { AlertTypeEnum } from "@/types/enums/alert" import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter" import { RateTypeEnum } from "@/types/enums/rateType" export default function RoomSelectionPanel() { const { rooms } = useRoomContext() const isSingleRoomAndHasSelection = useRatesStore( (state) => state.booking.rooms.length === 1 && !!state.rateSummary.length ) const searchParams = useSearchParams() const bookingCode = searchParams.get("bookingCode") const intl = useIntl() const lang = useLang() const noAvailableRooms = rooms.every( (roomConfig) => roomConfig.status === AvailabilityEnum.NotAvailable ) const activeCodeFilter = useBookingCodeFilterStore( (state) => state.activeCodeFilter ) // Regular Rates (Save, Change and Flex) always should send both public and member rates // so we can check public rates for availability const isRegularRatesAvailableWithCode = bookingCode && rooms.some( (room) => room.status === AvailabilityEnum.Available && room.products.some( (product) => product.public?.rateType === RateTypeEnum.Regular ) ) // Booking codes rate comes with various rate types but Regular is reserved // for non-booking code rates (Save, Change & Flex) // With Booking code rates we will always obtain public rate and maybe a member rate // so we check for public rate and ignore member rate const isBookingCodeRatesAvailable = bookingCode && rooms.some( (room) => room.status === AvailabilityEnum.Available && room.products.some( (product) => product.public?.rateType !== RateTypeEnum.Regular ) ) // Show all rooms if either booking code rates or regular rates are not available // or filter selection is All rooms const showAllRooms = !isBookingCodeRatesAvailable || !isRegularRatesAvailableWithCode || activeCodeFilter === BookingCodeFilterEnum.All const bookingCodeDiscountedRooms = rooms.filter( (room) => room.status === AvailabilityEnum.Available && room.products.every( (product) => product.public?.rateType !== RateTypeEnum.Regular ) ) const regularRateRooms = rooms.filter( (room) => room.status === AvailabilityEnum.Available && room.products.every( (product) => product.public?.rateType === RateTypeEnum.Regular ) ) // Show booking code filter when both of the booking code rates or regular rates are available const showBookingCodeFilter = isRegularRatesAvailableWithCode && isBookingCodeRatesAvailable useEffect(() => { if (isSingleRoomAndHasSelection) { // Required to prevent the history.pushState on the first selection // to scroll user back to top requestAnimationFrame(() => { const SCROLL_OFFSET = 100 const selectedInputRoomCard = document.querySelector( `.${styles.roomList} li:has(input[type=radio]:checked)` ) if (selectedInputRoomCard) { const elementPosition = selectedInputRoomCard.getBoundingClientRect().top const offsetPosition = elementPosition + window.scrollY - SCROLL_OFFSET window.scrollTo({ top: offsetPosition, behavior: "instant", }) } }) } }, [isSingleRoomAndHasSelection]) return ( <> {noAvailableRooms || (bookingCode && !isBookingCodeRatesAvailable) ? (
) : null} {showBookingCodeFilter ? : null} ) }