111 lines
3.4 KiB
TypeScript
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 })
|
|
},
|
|
}))
|