"use client" import { useCallback, useEffect, useMemo, useState } from "react" import { useIntl } from "react-intl" import RoomFilter from "../RoomFilter" import RoomSelection from "../RoomSelection" import { filterDuplicateRoomTypesByLowestPrice } from "./utils" import styles from "./rooms.module.css" import { type DefaultFilterOptions, RoomPackageCodeEnum, type RoomPackageCodes, } from "@/types/components/hotelReservation/selectRate/roomFilter" import type { SelectRateProps } from "@/types/components/hotelReservation/selectRate/roomSelection" import type { Rate, RateCode, } from "@/types/components/hotelReservation/selectRate/selectRate" import type { RoomConfiguration } from "@/server/routers/hotels/output" export default function Rooms({ roomsAvailability, roomCategories = [], availablePackages, hotelType, isUserLoggedIn, }: SelectRateProps) { const intl = useIntl() const visibleRooms: RoomConfiguration[] = useMemo(() => { const deduped = filterDuplicateRoomTypesByLowestPrice( roomsAvailability.roomConfigurations ) const separated = deduped.reduce<{ available: RoomConfiguration[] notAvailable: RoomConfiguration[] }>( (acc, curr) => { if (curr.status === "NotAvailable") { return { ...acc, notAvailable: [...acc.notAvailable, curr] } } return { ...acc, available: [...acc.available, curr] } }, { available: [], notAvailable: [] } ) return [...separated.available, ...separated.notAvailable] }, [roomsAvailability.roomConfigurations]) const [selectedRate, setSelectedRate] = useState( undefined ) const [selectedPackages, setSelectedPackages] = useState( [] ) const defaultPackages: DefaultFilterOptions[] = useMemo( () => [ { code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM, description: intl.formatMessage({ id: "Accessible Room" }), itemCode: availablePackages.find( (pkg) => pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM )?.itemCode, }, { code: RoomPackageCodeEnum.ALLERGY_ROOM, description: intl.formatMessage({ id: "Allergy Room" }), itemCode: availablePackages.find( (pkg) => pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM )?.itemCode, }, { code: RoomPackageCodeEnum.PET_ROOM, description: intl.formatMessage({ id: "Pet Room" }), itemCode: availablePackages.find( (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM )?.itemCode, }, ], [availablePackages, intl] ) const handleFilter = useCallback( (filter: Record) => { const filteredPackages = Object.keys(filter).filter( (key) => filter[key as RoomPackageCodeEnum] ) as RoomPackageCodeEnum[] setSelectedPackages(filteredPackages) }, [] ) const filteredRooms = useMemo(() => { return visibleRooms.filter((room) => selectedPackages.every((filteredPackage) => room.features.some((feature) => feature.code === filteredPackage) ) ) }, [visibleRooms, selectedPackages]) const rooms = useMemo(() => { if (selectedPackages.length === 0) { return { ...roomsAvailability, roomConfigurations: visibleRooms, } } return { ...roomsAvailability, roomConfigurations: [...filteredRooms], } }, [roomsAvailability, visibleRooms, selectedPackages, filteredRooms]) const rateSummary: Rate | null = useMemo(() => { const room = filteredRooms.find( (room) => room.roomTypeCode === selectedRate?.roomTypeCode ) if (!room) return null const product = room.products.find( (product) => product.productType.public.rateCode === selectedRate?.publicRateCode ) if (!product) return null const petRoomPackage = (selectedPackages.includes(RoomPackageCodeEnum.PET_ROOM) && availablePackages.find( (pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM )) || undefined const features = filteredRooms.find((room) => room.features.some( (feature) => feature.code === RoomPackageCodeEnum.PET_ROOM ) )?.features const roomType = roomCategories.find((roomCategory) => roomCategory.roomTypes.some( (roomType) => roomType.code === room.roomTypeCode ) ) const rateSummary: Rate = { features: petRoomPackage && features ? features : [], priceName: selectedRate?.name, priceTerm: selectedRate?.paymentTerm, public: product.productType.public, member: product.productType.member, roomType: roomType?.name || room.roomType, roomTypeCode: room.roomTypeCode, } return rateSummary }, [ filteredRooms, availablePackages, selectedPackages, selectedRate, roomCategories, ]) useEffect(() => { if (rateSummary) return if (!selectedRate) return setSelectedRate(undefined) }, [rateSummary, selectedRate]) return (
) }