93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
import { useCallback, useMemo, useState } from "react"
|
|
|
|
import { filterDuplicateRoomTypesByLowestPrice } from "@/components/HotelReservation/SelectRate/Rooms/utils"
|
|
|
|
import type {
|
|
RoomPackageCodeEnum,
|
|
RoomPackageCodes,
|
|
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
|
import type {
|
|
RoomConfiguration,
|
|
RoomsAvailability,
|
|
} from "@/server/routers/hotels/output"
|
|
|
|
interface UseRoomFilteringProps {
|
|
roomsAvailability: RoomsAvailability
|
|
}
|
|
|
|
export function useRoomFiltering({ roomsAvailability }: UseRoomFilteringProps) {
|
|
const [selectedPackagesByRoom, setSelectedPackagesByRoom] = useState<
|
|
Record<number, RoomPackageCodes[]>
|
|
>({})
|
|
|
|
const visibleRooms = 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 handleFilter = useCallback(
|
|
(
|
|
filter: Record<RoomPackageCodeEnum, boolean | undefined>,
|
|
roomIndex: number
|
|
) => {
|
|
const filteredPackages = Object.keys(filter).filter(
|
|
(key) => filter[key as RoomPackageCodeEnum]
|
|
) as RoomPackageCodeEnum[]
|
|
|
|
setSelectedPackagesByRoom((prev) => ({
|
|
...prev,
|
|
[roomIndex]: filteredPackages,
|
|
}))
|
|
},
|
|
[]
|
|
)
|
|
|
|
const getFilteredRooms = useCallback(
|
|
(roomIndex: number) => {
|
|
const selectedPackages = selectedPackagesByRoom[roomIndex] || []
|
|
|
|
return visibleRooms.filter((room) =>
|
|
selectedPackages.every((filteredPackage) =>
|
|
room.features.some((feature) => feature.code === filteredPackage)
|
|
)
|
|
)
|
|
},
|
|
[visibleRooms, selectedPackagesByRoom]
|
|
)
|
|
const getRooms = useCallback(
|
|
(roomIndex: number) => {
|
|
const selectedPackages = selectedPackagesByRoom[roomIndex] || []
|
|
const filteredRooms = getFilteredRooms(roomIndex)
|
|
|
|
return {
|
|
...roomsAvailability,
|
|
roomConfigurations:
|
|
selectedPackages.length === 0 ? visibleRooms : filteredRooms,
|
|
}
|
|
},
|
|
[roomsAvailability, visibleRooms, selectedPackagesByRoom, getFilteredRooms]
|
|
)
|
|
|
|
return {
|
|
selectedPackagesByRoom,
|
|
getFilteredRooms,
|
|
getRooms,
|
|
handleFilter,
|
|
}
|
|
}
|