Files
web/stores/rate-selection.ts
2025-01-30 11:19:22 +01:00

111 lines
3.4 KiB
TypeScript

import { create } from "zustand"
import type {
RoomPackageCodeEnum,
RoomPackageData} from "@/types/components/hotelReservation/selectRate/roomFilter";
import type { RoomParam } from "@/types/components/hotelReservation/selectRate/section"
import type {
Rate,
RateCode,
} from "@/types/components/hotelReservation/selectRate/selectRate"
import type { RoomConfiguration } from "@/server/routers/hotels/output"
interface RateSummaryParams {
getFilteredRooms: (roomIndex: number) => RoomConfiguration[]
availablePackages: RoomPackageData
roomCategories: Array<{ name: string; roomTypes: Array<{ code: string }> }>
selectedPackagesByRoom: Record<number, RoomPackageCodeEnum[]>
}
interface RateSelectionState {
selectedRates: (RateCode | undefined)[]
roomsAndGuests: RoomParam[]
rateSummary: (Rate | null)[]
modifyRate: (index: number) => void
selectRate: (index: number, rate: RateCode | undefined) => void
setRoomsAndGuests: (rooms: RoomParam[]) => void
initializeRates: (count: number) => void
calculateRateSummary: ({
getFilteredRooms,
availablePackages,
roomCategories,
}: RateSummaryParams) => void
}
export const useRateSelectionStore = create<RateSelectionState>((set, get) => ({
selectedRates: [],
roomsAndGuests: [],
rateSummary: [],
modifyRate: (index) =>
set((state) => {
const newRates = [...state.selectedRates]
newRates[index] = undefined
return { selectedRates: newRates }
}),
selectRate: (index, rate) =>
set((state) => {
const newRates = [...state.selectedRates]
newRates[index] = rate
return { selectedRates: newRates }
}),
initializeRates: (count) =>
set({ selectedRates: new Array(count).fill(undefined) }),
setRoomsAndGuests: (rooms) => set({ roomsAndGuests: rooms }),
calculateRateSummary: ({
getFilteredRooms,
availablePackages,
roomCategories,
selectedPackagesByRoom,
}) => {
const state = get()
const summaries = state.roomsAndGuests.map((_, roomIndex) => {
const selectedRate = state.selectedRates[roomIndex]
const filteredRooms = getFilteredRooms(roomIndex)
const selectedPackages = selectedPackagesByRoom[roomIndex] || []
const room = filteredRooms.find(
(room) => room.roomTypeCode === selectedRate?.roomTypeCode
)
if (!room) return null
const product = room.products.find(
(product) =>
product.productType.public.rateCode === selectedRate?.publicRateCode
)
if (!product) return null
const petRoomPackage =
(selectedPackages.includes(RoomPackageCodeEnum.PET_ROOM) &&
availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
)) ||
undefined
const features = filteredRooms.find((room) =>
room.features.some(
(feature) => feature.code === RoomPackageCodeEnum.PET_ROOM
)
)?.features
const roomType = roomCategories.find((roomCategory) =>
roomCategory.roomTypes.some(
(roomType) => roomType.code === room.roomTypeCode
)
)
return {
features: petRoomPackage && features ? features : [],
priceName: selectedRate?.name,
priceTerm: selectedRate?.paymentTerm,
public: product.productType.public,
member: product.productType.member,
roomType: roomType?.name ?? room.roomType,
roomTypeCode: room.roomTypeCode,
}
})
set({ rateSummary: summaries })
},
}))