) => {
- handleFilter(filter, index)
- },
- [handleFilter]
- )
-
useEffect(() => {
setTimeout(() => {
const SCROLL_OFFSET = 100
@@ -252,12 +253,10 @@ export default function Rooms({
@@ -268,12 +267,10 @@ export default function Rooms({
})
) : (
diff --git a/hooks/selectRate/useRoomFiltering.ts b/hooks/selectRate/useRoomFiltering.ts
deleted file mode 100644
index 734c01bae..000000000
--- a/hooks/selectRate/useRoomFiltering.ts
+++ /dev/null
@@ -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
- >({})
-
- 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,
- 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,
- }
-}
diff --git a/stores/select-rate/room-filtering.ts b/stores/select-rate/room-filtering.ts
new file mode 100644
index 000000000..9454ce692
--- /dev/null
+++ b/stores/select-rate/room-filtering.ts
@@ -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
+ 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((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,
+ }
+ },
+}))
diff --git a/types/components/hotelReservation/selectRate/roomFilter.ts b/types/components/hotelReservation/selectRate/roomFilter.ts
index 9dc5af31f..981ea0784 100644
--- a/types/components/hotelReservation/selectRate/roomFilter.ts
+++ b/types/components/hotelReservation/selectRate/roomFilter.ts
@@ -19,9 +19,9 @@ export interface FilterValues {
}
export interface RoomFilterProps {
numberOfRooms: number
- onFilter: (filter: Record) => void
filterOptions: DefaultFilterOptions[]
initialFilterValues: FilterValues
+ roomListIndex: number
}
export type RoomPackage = z.output
diff --git a/types/components/hotelReservation/selectRate/roomSelection.ts b/types/components/hotelReservation/selectRate/roomSelection.ts
index 4f0f3c978..014f3a731 100644
--- a/types/components/hotelReservation/selectRate/roomSelection.ts
+++ b/types/components/hotelReservation/selectRate/roomSelection.ts
@@ -3,7 +3,6 @@ import type { RoomsAvailability } from "@/server/routers/hotels/output"
import type {
DefaultFilterOptions,
RoomPackage,
- RoomPackageCodeEnum,
RoomPackageCodes,
RoomPackageData,
} from "./roomFilter"
@@ -26,14 +25,10 @@ export interface SelectRateProps {
}
export interface RoomSelectionPanelProps {
- rooms: RoomsAvailability
roomCategories: RoomData[]
availablePackages: RoomPackage[]
selectedPackages: RoomPackageCodes[]
hotelType: string | undefined
- handleFilter: (
- filter: Record
- ) => void
defaultPackages: DefaultFilterOptions[]
roomListIndex: number
}