feat(SW-718) created useRoomFilteringStore
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import { useSearchParams } from "next/navigation"
|
import { useSearchParams } from "next/navigation"
|
||||||
import { useMemo } from "react"
|
import { useMemo } from "react"
|
||||||
|
|
||||||
|
import { useRoomFilteringStore } from "@/stores/select-rate/room-filtering"
|
||||||
|
|
||||||
import RoomTypeFilter from "../RoomTypeFilter"
|
import RoomTypeFilter from "../RoomTypeFilter"
|
||||||
import RoomTypeList from "../RoomTypeList"
|
import RoomTypeList from "../RoomTypeList"
|
||||||
|
|
||||||
@@ -8,16 +10,17 @@ import type { FilterValues } from "@/types/components/hotelReservation/selectRat
|
|||||||
import type { RoomSelectionPanelProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
|
import type { RoomSelectionPanelProps } from "@/types/components/hotelReservation/selectRate/roomSelection"
|
||||||
|
|
||||||
export function RoomSelectionPanel({
|
export function RoomSelectionPanel({
|
||||||
rooms,
|
|
||||||
roomCategories,
|
roomCategories,
|
||||||
availablePackages,
|
availablePackages,
|
||||||
selectedPackages,
|
selectedPackages,
|
||||||
hotelType,
|
hotelType,
|
||||||
handleFilter,
|
|
||||||
defaultPackages,
|
defaultPackages,
|
||||||
roomListIndex,
|
roomListIndex,
|
||||||
}: RoomSelectionPanelProps) {
|
}: RoomSelectionPanelProps) {
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
|
const { getRooms } = useRoomFilteringStore()
|
||||||
|
|
||||||
|
const rooms = getRooms(roomListIndex)
|
||||||
|
|
||||||
const initialFilterValues = useMemo(() => {
|
const initialFilterValues = useMemo(() => {
|
||||||
const packagesFromSearchParams =
|
const packagesFromSearchParams =
|
||||||
@@ -32,11 +35,12 @@ export function RoomSelectionPanel({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<RoomTypeFilter
|
<RoomTypeFilter
|
||||||
numberOfRooms={rooms.roomConfigurations.length}
|
numberOfRooms={rooms?.roomConfigurations.length ?? 0}
|
||||||
onFilter={handleFilter}
|
|
||||||
filterOptions={defaultPackages}
|
filterOptions={defaultPackages}
|
||||||
initialFilterValues={initialFilterValues}
|
initialFilterValues={initialFilterValues}
|
||||||
|
roomListIndex={roomListIndex}
|
||||||
/>
|
/>
|
||||||
|
{rooms && (
|
||||||
<RoomTypeList
|
<RoomTypeList
|
||||||
roomsAvailability={rooms}
|
roomsAvailability={rooms}
|
||||||
roomCategories={roomCategories}
|
roomCategories={roomCategories}
|
||||||
@@ -45,6 +49,7 @@ export function RoomSelectionPanel({
|
|||||||
hotelType={hotelType}
|
hotelType={hotelType}
|
||||||
roomListIndex={roomListIndex}
|
roomListIndex={roomListIndex}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import { useIntl } from "react-intl"
|
|||||||
import { useMediaQuery } from "usehooks-ts"
|
import { useMediaQuery } from "usehooks-ts"
|
||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
|
import { useRoomFilteringStore } from "@/stores/select-rate/room-filtering"
|
||||||
|
|
||||||
import { getIconForFeatureCode } from "@/components/HotelReservation/utils"
|
import { getIconForFeatureCode } from "@/components/HotelReservation/utils"
|
||||||
import { InfoCircleIcon } from "@/components/Icons"
|
import { InfoCircleIcon } from "@/components/Icons"
|
||||||
import CheckboxChip from "@/components/TempDesignSystem/Form/FilterChip/Checkbox"
|
import CheckboxChip from "@/components/TempDesignSystem/Form/FilterChip/Checkbox"
|
||||||
@@ -24,13 +26,12 @@ import {
|
|||||||
|
|
||||||
export default function RoomFilter({
|
export default function RoomFilter({
|
||||||
numberOfRooms,
|
numberOfRooms,
|
||||||
onFilter,
|
|
||||||
filterOptions,
|
filterOptions,
|
||||||
initialFilterValues,
|
initialFilterValues,
|
||||||
|
roomListIndex,
|
||||||
}: RoomFilterProps) {
|
}: RoomFilterProps) {
|
||||||
const isTabletAndUp = useMediaQuery("(min-width: 768px)")
|
const isTabletAndUp = useMediaQuery("(min-width: 768px)")
|
||||||
const [isAboveMobile, setIsAboveMobile] = useState(false)
|
const [isAboveMobile, setIsAboveMobile] = useState(false)
|
||||||
const [isInitialized, setIsInitialized] = useState(false)
|
|
||||||
|
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const methods = useForm<FilterValues>({
|
const methods = useForm<FilterValues>({
|
||||||
@@ -40,6 +41,8 @@ export default function RoomFilter({
|
|||||||
resolver: zodResolver(z.object({})),
|
resolver: zodResolver(z.object({})),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { handleFilter } = useRoomFilteringStore()
|
||||||
|
|
||||||
const { watch, getValues } = methods
|
const { watch, getValues } = methods
|
||||||
const petFriendly = watch(RoomPackageCodeEnum.PET_ROOM)
|
const petFriendly = watch(RoomPackageCodeEnum.PET_ROOM)
|
||||||
const allergyFriendly = watch(RoomPackageCodeEnum.ALLERGY_ROOM)
|
const allergyFriendly = watch(RoomPackageCodeEnum.ALLERGY_ROOM)
|
||||||
@@ -51,23 +54,18 @@ export default function RoomFilter({
|
|||||||
})
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialFilterValues || isInitialized) return
|
if (!initialFilterValues) return
|
||||||
|
|
||||||
onFilter(initialFilterValues)
|
handleFilter(initialFilterValues, roomListIndex)
|
||||||
setIsInitialized(true)
|
}, [initialFilterValues, handleFilter, roomListIndex])
|
||||||
}, [initialFilterValues, onFilter, isInitialized])
|
|
||||||
|
|
||||||
// Watch for filter changes
|
// Watch for filter changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const subscription = watch((value, { name }) => {
|
const subscription = watch((value, { name }) => {
|
||||||
if (!name || !isInitialized) return
|
if (name) handleFilter(getValues(), roomListIndex)
|
||||||
|
|
||||||
const currentValues = getValues()
|
|
||||||
onFilter(currentValues)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => subscription.unsubscribe()
|
return () => subscription.unsubscribe()
|
||||||
}, [watch, getValues, onFilter, isInitialized])
|
}, [watch, getValues, handleFilter, roomListIndex])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsAboveMobile(isTabletAndUp)
|
setIsAboveMobile(isTabletAndUp)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||||
import { useCallback, useEffect, useMemo } from "react"
|
import { useEffect, useMemo } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useRateSelectionStore } from "@/stores/select-rate/rate-selection"
|
import { useRateSelectionStore } from "@/stores/select-rate/rate-selection"
|
||||||
|
import { useRoomFilteringStore } from "@/stores/select-rate/room-filtering"
|
||||||
|
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import { useRoomFiltering } from "@/hooks/selectRate/useRoomFiltering"
|
|
||||||
import { trackLowestRoomPrice } from "@/utils/tracking"
|
import { trackLowestRoomPrice } from "@/utils/tracking"
|
||||||
import { convertObjToSearchParams, convertSearchParamsToObj } from "@/utils/url"
|
import { convertObjToSearchParams, convertSearchParamsToObj } from "@/utils/url"
|
||||||
|
|
||||||
@@ -45,6 +45,13 @@ export default function Rooms({
|
|||||||
const { selectedRates, rateSummary, calculateRateSummary, initializeRates } =
|
const { selectedRates, rateSummary, calculateRateSummary, initializeRates } =
|
||||||
useRateSelectionStore()
|
useRateSelectionStore()
|
||||||
|
|
||||||
|
const {
|
||||||
|
selectedPackagesByRoom,
|
||||||
|
setVisibleRooms,
|
||||||
|
setRoomsAvailability,
|
||||||
|
getFilteredRooms,
|
||||||
|
} = useRoomFilteringStore()
|
||||||
|
|
||||||
const bookingWidgetSearchData = useMemo(
|
const bookingWidgetSearchData = useMemo(
|
||||||
() =>
|
() =>
|
||||||
convertSearchParamsToObj<SelectRateSearchParams>(
|
convertSearchParamsToObj<SelectRateSearchParams>(
|
||||||
@@ -109,8 +116,10 @@ export default function Rooms({
|
|||||||
[availablePackages, intl]
|
[availablePackages, intl]
|
||||||
)
|
)
|
||||||
|
|
||||||
const { selectedPackagesByRoom, getRooms, handleFilter, getFilteredRooms } =
|
useEffect(() => {
|
||||||
useRoomFiltering({ roomsAvailability })
|
setRoomsAvailability(roomsAvailability)
|
||||||
|
setVisibleRooms()
|
||||||
|
}, [roomsAvailability, setRoomsAvailability, setVisibleRooms])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@@ -183,14 +192,6 @@ export default function Rooms({
|
|||||||
router.push(`select-bed?${queryParams}`)
|
router.push(`select-bed?${queryParams}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleFilterForRoom = useCallback(
|
|
||||||
(index: number) =>
|
|
||||||
(filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
|
|
||||||
handleFilter(filter, index)
|
|
||||||
},
|
|
||||||
[handleFilter]
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const SCROLL_OFFSET = 100
|
const SCROLL_OFFSET = 100
|
||||||
@@ -252,12 +253,10 @@ export default function Rooms({
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.roomSelectionPanel}>
|
<div className={styles.roomSelectionPanel}>
|
||||||
<RoomSelectionPanel
|
<RoomSelectionPanel
|
||||||
rooms={getRooms(index)}
|
|
||||||
roomCategories={roomCategories}
|
roomCategories={roomCategories}
|
||||||
availablePackages={availablePackages}
|
availablePackages={availablePackages}
|
||||||
selectedPackages={selectedPackagesByRoom[index]}
|
selectedPackages={selectedPackagesByRoom[index]}
|
||||||
hotelType={hotelType}
|
hotelType={hotelType}
|
||||||
handleFilter={handleFilterForRoom(index)}
|
|
||||||
defaultPackages={defaultPackages}
|
defaultPackages={defaultPackages}
|
||||||
roomListIndex={index}
|
roomListIndex={index}
|
||||||
/>
|
/>
|
||||||
@@ -268,12 +267,10 @@ export default function Rooms({
|
|||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<RoomSelectionPanel
|
<RoomSelectionPanel
|
||||||
rooms={getRooms(0)}
|
|
||||||
roomCategories={roomCategories}
|
roomCategories={roomCategories}
|
||||||
availablePackages={availablePackages}
|
availablePackages={availablePackages}
|
||||||
selectedPackages={selectedPackagesByRoom[0]}
|
selectedPackages={selectedPackagesByRoom[0]}
|
||||||
hotelType={hotelType}
|
hotelType={hotelType}
|
||||||
handleFilter={handleFilterForRoom(0)}
|
|
||||||
defaultPackages={defaultPackages}
|
defaultPackages={defaultPackages}
|
||||||
roomListIndex={0}
|
roomListIndex={0}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
104
stores/select-rate/room-filtering.ts
Normal file
104
stores/select-rate/room-filtering.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import { create } from "zustand"
|
||||||
|
|
||||||
|
import { filterDuplicateRoomTypesByLowestPrice } from "@/components/HotelReservation/SelectRate/Rooms/utils"
|
||||||
|
|
||||||
|
import type {
|
||||||
|
FilterValues,
|
||||||
|
RoomPackageCodeEnum,
|
||||||
|
RoomPackageCodes,
|
||||||
|
} from "@/types/components/hotelReservation/selectRate/roomFilter"
|
||||||
|
import type {
|
||||||
|
RoomConfiguration,
|
||||||
|
RoomsAvailability,
|
||||||
|
} from "@/server/routers/hotels/output"
|
||||||
|
|
||||||
|
interface RoomFilteringState {
|
||||||
|
selectedPackagesByRoom: Record<number, RoomPackageCodes[]>
|
||||||
|
roomsAvailability: RoomsAvailability | null
|
||||||
|
visibleRooms: RoomConfiguration[]
|
||||||
|
setVisibleRooms: () => void
|
||||||
|
setRoomsAvailability: (rooms: RoomsAvailability) => void
|
||||||
|
handleFilter: (filter: FilterValues, roomIndex: number) => void
|
||||||
|
getFilteredRooms: (roomIndex: number) => RoomConfiguration[]
|
||||||
|
getRooms: (roomIndex: number) => RoomsAvailability | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useRoomFilteringStore = create<RoomFilteringState>((set, get) => ({
|
||||||
|
selectedPackagesByRoom: {},
|
||||||
|
roomsAvailability: null,
|
||||||
|
visibleRooms: [],
|
||||||
|
setRoomsAvailability: (rooms) => {
|
||||||
|
set({ roomsAvailability: rooms })
|
||||||
|
},
|
||||||
|
setVisibleRooms: () => {
|
||||||
|
const { roomsAvailability } = get()
|
||||||
|
if (!roomsAvailability) return null
|
||||||
|
|
||||||
|
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: [] }
|
||||||
|
)
|
||||||
|
|
||||||
|
set({ visibleRooms: [...separated.available, ...separated.notAvailable] })
|
||||||
|
},
|
||||||
|
|
||||||
|
handleFilter: (filter, roomIndex) => {
|
||||||
|
const filteredPackages = Object.entries(filter)
|
||||||
|
.filter(([_, isSelected]) => isSelected)
|
||||||
|
.map(([code]) => code) as RoomPackageCodeEnum[]
|
||||||
|
|
||||||
|
set((state) => {
|
||||||
|
const currentPackages = state.selectedPackagesByRoom[roomIndex] || []
|
||||||
|
const sortedCurrent = [...currentPackages].sort()
|
||||||
|
const sortedNew = [...filteredPackages].sort()
|
||||||
|
|
||||||
|
if (JSON.stringify(sortedCurrent) === JSON.stringify(sortedNew)) {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
selectedPackagesByRoom: {
|
||||||
|
...state.selectedPackagesByRoom,
|
||||||
|
[roomIndex]: filteredPackages,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getFilteredRooms: (roomIndex) => {
|
||||||
|
const state = get()
|
||||||
|
const selectedPackages = state.selectedPackagesByRoom[roomIndex] || []
|
||||||
|
|
||||||
|
return state.visibleRooms.filter((room) =>
|
||||||
|
selectedPackages.every((filteredPackage) =>
|
||||||
|
room.features.some((feature) => feature.code === filteredPackage)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
getRooms: (roomIndex) => {
|
||||||
|
const state = get()
|
||||||
|
if (!state.roomsAvailability) return null
|
||||||
|
|
||||||
|
const selectedPackages = state.selectedPackagesByRoom[roomIndex] || []
|
||||||
|
const filteredRooms = state.getFilteredRooms(roomIndex)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...state.roomsAvailability,
|
||||||
|
roomConfigurations:
|
||||||
|
selectedPackages.length === 0 ? state.visibleRooms : filteredRooms,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}))
|
||||||
@@ -19,9 +19,9 @@ export interface FilterValues {
|
|||||||
}
|
}
|
||||||
export interface RoomFilterProps {
|
export interface RoomFilterProps {
|
||||||
numberOfRooms: number
|
numberOfRooms: number
|
||||||
onFilter: (filter: Record<string, boolean | undefined>) => void
|
|
||||||
filterOptions: DefaultFilterOptions[]
|
filterOptions: DefaultFilterOptions[]
|
||||||
initialFilterValues: FilterValues
|
initialFilterValues: FilterValues
|
||||||
|
roomListIndex: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RoomPackage = z.output<typeof packagesSchema>
|
export type RoomPackage = z.output<typeof packagesSchema>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { RoomsAvailability } from "@/server/routers/hotels/output"
|
|||||||
import type {
|
import type {
|
||||||
DefaultFilterOptions,
|
DefaultFilterOptions,
|
||||||
RoomPackage,
|
RoomPackage,
|
||||||
RoomPackageCodeEnum,
|
|
||||||
RoomPackageCodes,
|
RoomPackageCodes,
|
||||||
RoomPackageData,
|
RoomPackageData,
|
||||||
} from "./roomFilter"
|
} from "./roomFilter"
|
||||||
@@ -26,14 +25,10 @@ export interface SelectRateProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface RoomSelectionPanelProps {
|
export interface RoomSelectionPanelProps {
|
||||||
rooms: RoomsAvailability
|
|
||||||
roomCategories: RoomData[]
|
roomCategories: RoomData[]
|
||||||
availablePackages: RoomPackage[]
|
availablePackages: RoomPackage[]
|
||||||
selectedPackages: RoomPackageCodes[]
|
selectedPackages: RoomPackageCodes[]
|
||||||
hotelType: string | undefined
|
hotelType: string | undefined
|
||||||
handleFilter: (
|
|
||||||
filter: Record<RoomPackageCodeEnum, boolean | undefined>
|
|
||||||
) => void
|
|
||||||
defaultPackages: DefaultFilterOptions[]
|
defaultPackages: DefaultFilterOptions[]
|
||||||
roomListIndex: number
|
roomListIndex: number
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user