Feat/SW-822 handle breakfast included * feat(SW-822): Added flag for breakfast included and hide breakfast step if included * fix: check if window is defined to avoid error during SSR * fix: remove return if rate definition is not found because its expected if input is undefined Approved-by: Christel Westerberg Approved-by: Arvid Norlin
143 lines
4.3 KiB
TypeScript
143 lines
4.3 KiB
TypeScript
"use client"
|
|
import { useEffect, useRef } from "react"
|
|
|
|
import { createDetailsStore } from "@/stores/enter-details"
|
|
import {
|
|
calcTotalMemberPrice,
|
|
calcTotalPublicPrice,
|
|
navigate,
|
|
writeToSessionStorage,
|
|
} from "@/stores/enter-details/helpers"
|
|
|
|
import { bedTypeSchema } from "@/components/HotelReservation/EnterDetails/BedType/schema"
|
|
import { breakfastStoreSchema } from "@/components/HotelReservation/EnterDetails/Breakfast/schema"
|
|
import {
|
|
guestDetailsSchema,
|
|
signedInDetailsSchema,
|
|
} from "@/components/HotelReservation/EnterDetails/Details/schema"
|
|
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 { DetailsState, InitialState } from "@/types/stores/enter-details"
|
|
|
|
export default function EnterDetailsProvider({
|
|
bedTypes,
|
|
booking,
|
|
showBreakfastStep,
|
|
children,
|
|
packages,
|
|
roomRate,
|
|
searchParamsStr,
|
|
step,
|
|
user,
|
|
vat,
|
|
}: DetailsProviderProps) {
|
|
const storeRef = useRef<DetailsStore>()
|
|
|
|
if (!storeRef.current) {
|
|
const initialData: InitialState = { booking, packages, roomRate, vat }
|
|
if (bedTypes.length === 1) {
|
|
initialData.bedType = {
|
|
description: bedTypes[0].description,
|
|
roomTypeCode: bedTypes[0].value,
|
|
}
|
|
}
|
|
if (!showBreakfastStep) {
|
|
initialData.breakfast = false
|
|
}
|
|
|
|
storeRef.current = createDetailsStore(
|
|
initialData,
|
|
step,
|
|
searchParamsStr,
|
|
user
|
|
)
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (storeRef.current) {
|
|
storeRef.current.setState((state) => {
|
|
const newState: DetailsState = { ...state }
|
|
|
|
newState.bedType = state.formValues.bedType
|
|
newState.breakfast = state.formValues.breakfast
|
|
|
|
if (state.formValues.guest && !user) {
|
|
newState.guest = state.formValues.guest
|
|
}
|
|
|
|
if (
|
|
(newState.guest!.join || newState.guest!.membershipNo || user) &&
|
|
state.roomRate.memberRate
|
|
) {
|
|
const memberPrice = calcTotalMemberPrice(newState)
|
|
newState.roomPrice = memberPrice.roomPrice
|
|
newState.totalPrice = memberPrice.totalPrice
|
|
} else {
|
|
const publicPrice = calcTotalPublicPrice(newState)
|
|
newState.roomPrice = publicPrice.roomPrice
|
|
newState.totalPrice = publicPrice.totalPrice
|
|
}
|
|
|
|
const isValid = { ...newState.isValid }
|
|
|
|
const validateBooking = state.formValues
|
|
const validPaths = [StepEnum.selectBed]
|
|
const validatedBedType = bedTypeSchema.safeParse(validateBooking)
|
|
if (validatedBedType.success) {
|
|
isValid[StepEnum.selectBed] = true
|
|
validPaths.push(state.steps[1])
|
|
}
|
|
|
|
const validatedBreakfast =
|
|
breakfastStoreSchema.safeParse(validateBooking)
|
|
if (validatedBreakfast.success) {
|
|
isValid[StepEnum.breakfast] = true
|
|
validPaths.push(StepEnum.details)
|
|
}
|
|
|
|
const detailsSchema = user ? signedInDetailsSchema : guestDetailsSchema
|
|
const validatedDetails = detailsSchema.safeParse(validateBooking.guest)
|
|
/**
|
|
* Need to add the breakfast check here too since
|
|
* when a member comes into the flow, their data is
|
|
* already added and valid, and thus to avoid showing a
|
|
* step the user hasn't been on yet as complete
|
|
*/
|
|
if (isValid.breakfast && validatedDetails.success) {
|
|
isValid[StepEnum.details] = true
|
|
validPaths.push(StepEnum.payment)
|
|
}
|
|
|
|
if (!validPaths.includes(newState.currentStep!)) {
|
|
newState.currentStep = validPaths.at(-1)!
|
|
}
|
|
|
|
if (step !== newState.currentStep) {
|
|
const stateCurrentStep = newState.currentStep!
|
|
setTimeout(() => {
|
|
navigate(stateCurrentStep, searchParamsStr)
|
|
})
|
|
}
|
|
|
|
writeToSessionStorage({
|
|
bedType: newState.bedType,
|
|
booking: newState.booking,
|
|
breakfast: newState.breakfast,
|
|
guest: newState.guest,
|
|
})
|
|
|
|
return { ...newState, isValid }
|
|
})
|
|
}
|
|
}, [searchParamsStr, step, user])
|
|
|
|
return (
|
|
<DetailsContext.Provider value={storeRef.current}>
|
|
{children}
|
|
</DetailsContext.Provider>
|
|
)
|
|
}
|