feat(SW-718) created useRoomFilteringStore
This commit is contained in:
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,
|
||||
}
|
||||
},
|
||||
}))
|
||||
Reference in New Issue
Block a user