feat: add multiroom signup
This commit is contained in:
39
apps/scandic-web/providers/Details/RoomProvider.tsx
Normal file
39
apps/scandic-web/providers/Details/RoomProvider.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
"use client"
|
||||
|
||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||
|
||||
import { RoomContext } from "@/contexts/Details/Room"
|
||||
|
||||
import type { RoomProviderProps } from "@/types/providers/details/room"
|
||||
|
||||
export default function RoomProvider({ children, idx }: RoomProviderProps) {
|
||||
const actions = useEnterDetailsStore((state) => ({
|
||||
setStep: state.actions.setStep(idx),
|
||||
updateBedType: state.actions.updateBedType(idx),
|
||||
updateBreakfast: state.actions.updateBreakfast(idx),
|
||||
updateDetails: state.actions.updateDetails(idx),
|
||||
}))
|
||||
const { activeRoom, currentStep, isComplete, room, steps } =
|
||||
useEnterDetailsStore((state) => ({
|
||||
activeRoom: state.activeRoom,
|
||||
currentStep: state.rooms[idx].currentStep,
|
||||
isComplete: state.rooms[idx].isComplete,
|
||||
room: state.rooms[idx].room,
|
||||
steps: state.rooms[idx].steps,
|
||||
}))
|
||||
return (
|
||||
<RoomContext.Provider
|
||||
value={{
|
||||
actions,
|
||||
currentStep,
|
||||
isComplete,
|
||||
isActiveRoom: activeRoom === idx,
|
||||
room,
|
||||
roomNr: idx + 1,
|
||||
steps,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</RoomContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
"use client"
|
||||
import { useEffect, useRef } from "react"
|
||||
|
||||
import { dt } from "@/lib/dt"
|
||||
import { createDetailsStore } from "@/stores/enter-details"
|
||||
import {
|
||||
calcTotalPrice,
|
||||
checkIsSameBedTypes,
|
||||
checkIsSameBooking as checkIsSameBooking,
|
||||
clearSessionStorage,
|
||||
@@ -12,15 +14,14 @@ import {
|
||||
import { DetailsContext } from "@/contexts/Details"
|
||||
|
||||
import type { DetailsStore } from "@/types/contexts/enter-details"
|
||||
import { StepEnum } from "@/types/enums/step"
|
||||
import type { DetailsProviderProps } from "@/types/providers/enter-details"
|
||||
import type { InitialState } from "@/types/stores/enter-details"
|
||||
|
||||
export default function EnterDetailsProvider({
|
||||
booking,
|
||||
showBreakfastStep,
|
||||
breakfastPackages,
|
||||
children,
|
||||
roomsData,
|
||||
rooms,
|
||||
searchParamsStr,
|
||||
user,
|
||||
vat,
|
||||
@@ -29,14 +30,17 @@ export default function EnterDetailsProvider({
|
||||
if (!storeRef.current) {
|
||||
const initialData: InitialState = {
|
||||
booking,
|
||||
rooms: roomsData
|
||||
rooms: rooms
|
||||
.filter((r) => r.bedTypes?.length) // TODO: how to handle room without bedtypes?
|
||||
.map((room) => ({
|
||||
breakfastIncluded: !!room.breakfastIncluded,
|
||||
cancellationText: room.cancellationText,
|
||||
rateDetails: room.rateDetails,
|
||||
roomFeatures: room.packages,
|
||||
roomRate: room.roomRate,
|
||||
roomType: room.roomType,
|
||||
cancellationText: room.cancellationText,
|
||||
rateDetails: room.rateDetails,
|
||||
roomTypeCode: room.roomTypeCode,
|
||||
bedTypes: room.bedTypes!,
|
||||
bedType:
|
||||
room.bedTypes?.length === 1
|
||||
? {
|
||||
@@ -48,11 +52,12 @@ export default function EnterDetailsProvider({
|
||||
vat,
|
||||
}
|
||||
|
||||
if (!showBreakfastStep) {
|
||||
initialData.breakfast = false
|
||||
}
|
||||
|
||||
storeRef.current = createDetailsStore(initialData, searchParamsStr, user)
|
||||
storeRef.current = createDetailsStore(
|
||||
initialData,
|
||||
searchParamsStr,
|
||||
user,
|
||||
breakfastPackages
|
||||
)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -68,26 +73,26 @@ export default function EnterDetailsProvider({
|
||||
|
||||
const updatedRooms = storedValues.rooms.map((storedRoom, idx) => {
|
||||
const currentRoom = booking.rooms[idx]
|
||||
const roomData = roomsData[idx]
|
||||
const room = rooms[idx]
|
||||
|
||||
if (!storedRoom.bedType) {
|
||||
if (!storedRoom.room?.bedType) {
|
||||
return storedRoom
|
||||
}
|
||||
|
||||
const isSameBedTypes = checkIsSameBedTypes(
|
||||
storedRoom.bedType.roomTypeCode,
|
||||
storedRoom.room.bedType.roomTypeCode,
|
||||
currentRoom.roomTypeCode
|
||||
)
|
||||
if (isSameBedTypes) {
|
||||
return storedRoom
|
||||
}
|
||||
|
||||
if (roomData?.bedTypes?.length === 1 && roomData.bedTypes[0]) {
|
||||
if (room?.bedTypes?.length === 1 && room.bedTypes[0]) {
|
||||
return {
|
||||
...storedRoom,
|
||||
bedType: {
|
||||
roomTypeCode: roomData.bedTypes[0].value,
|
||||
description: roomData.bedTypes[0].description,
|
||||
roomTypeCode: room.bedTypes[0].value,
|
||||
description: room.bedTypes[0].description,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -99,34 +104,20 @@ export default function EnterDetailsProvider({
|
||||
}
|
||||
})
|
||||
|
||||
const updatedProgress = {
|
||||
...storedValues.bookingProgress,
|
||||
roomStatuses: storedValues.bookingProgress.roomStatuses.map(
|
||||
(status, idx) => {
|
||||
const hasValidBedType = Boolean(updatedRooms[idx].bedType)
|
||||
if (hasValidBedType) return status
|
||||
const canProceedToPayment = updatedRooms.every((room) => room.isComplete)
|
||||
|
||||
return {
|
||||
...status,
|
||||
steps: {
|
||||
...status.steps,
|
||||
[StepEnum.selectBed]: {
|
||||
step: StepEnum.selectBed,
|
||||
isValid: false,
|
||||
},
|
||||
},
|
||||
currentStep: StepEnum.selectBed,
|
||||
isComplete: false,
|
||||
}
|
||||
}
|
||||
),
|
||||
}
|
||||
const nights = dt(booking.toDate).diff(booking.fromDate, "days")
|
||||
const currency =
|
||||
updatedRooms[0].room.roomRate.publicRate.localPrice.currency
|
||||
const totalPrice = calcTotalPrice(updatedRooms, currency, !!user, nights)
|
||||
|
||||
storeRef.current?.setState({
|
||||
activeRoom: storedValues.activeRoom,
|
||||
canProceedToPayment,
|
||||
rooms: updatedRooms,
|
||||
bookingProgress: updatedProgress,
|
||||
totalPrice,
|
||||
})
|
||||
}, [booking, roomsData])
|
||||
}, [booking, rooms, user])
|
||||
|
||||
return (
|
||||
<DetailsContext.Provider value={storeRef.current}>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import { useRatesStore } from "@/stores/select-rate"
|
||||
|
||||
import { RoomContext } from "@/contexts/Room"
|
||||
import { RoomContext } from "@/contexts/SelectRate/Room"
|
||||
|
||||
import type { RoomProviderProps } from "@/types/providers/room"
|
||||
import type { RoomProviderProps } from "@/types/providers/select-rate/room"
|
||||
|
||||
export default function RoomProvider({
|
||||
children,
|
||||
Reference in New Issue
Block a user