Files
web/components/HotelReservation/SelectRate/Rooms/index.tsx
2024-12-04 14:09:16 +01:00

172 lines
4.7 KiB
TypeScript

"use client"
import { useCallback, useEffect, useMemo, useState } from "react"
import RoomFilter from "../RoomFilter"
import RoomSelection from "../RoomSelection"
import { filterDuplicateRoomTypesByLowestPrice } from "./utils"
import styles from "./rooms.module.css"
import {
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 = [],
user,
availablePackages,
}: SelectRateProps) {
const visibleRooms: RoomConfiguration[] =
filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
const [selectedRate, setSelectedRate] = useState<RateCode | undefined>(
undefined
)
const [selectedPackages, setSelectedPackages] = useState<RoomPackageCodes[]>(
[]
)
const defaultPackages: DefaultFilterOptions[] = [
{
code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
description: "Accessible Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM
)?.itemCode,
},
{
code: RoomPackageCodeEnum.ALLERGY_ROOM,
description: "Allergy Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM
)?.itemCode,
},
{
code: RoomPackageCodeEnum.PET_ROOM,
description: "Pet Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
)?.itemCode,
},
]
const handleFilter = useCallback(
(filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
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 (
<div className={styles.content}>
<RoomFilter
numberOfRooms={rooms.roomConfigurations.length}
onFilter={handleFilter}
filterOptions={defaultPackages}
/>
<RoomSelection
roomsAvailability={rooms}
roomCategories={roomCategories}
user={user}
availablePackages={availablePackages}
selectedPackages={selectedPackages}
setRateCode={setSelectedRate}
rateSummary={rateSummary}
/>
</div>
)
}