feat(SW-718) created useRoomFilteringStore

This commit is contained in:
Pontus Dreij
2025-01-28 14:44:37 +01:00
parent ba20ce2696
commit ab7b826cd2
7 changed files with 144 additions and 137 deletions

View 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,
}
},
}))