feat: add multiroom signup

This commit is contained in:
Simon Emanuelsson
2025-02-17 15:10:48 +01:00
parent 95917e5e4f
commit 92c5566c59
78 changed files with 2035 additions and 1545 deletions

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

View File

@@ -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}>

View File

@@ -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,