fix: validate member in enter details store
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
import { getProfileSafely } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import EnterDetailsProvider from "@/components/HotelReservation/EnterDetails/Provider"
|
import EnterDetailsProvider from "@/components/HotelReservation/EnterDetails/Provider"
|
||||||
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
|
import SelectedRoom from "@/components/HotelReservation/EnterDetails/SelectedRoom"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
@@ -20,11 +22,15 @@ export default async function StepLayout({
|
|||||||
hotelHeader: React.ReactNode
|
hotelHeader: React.ReactNode
|
||||||
sidePeek: React.ReactNode
|
sidePeek: React.ReactNode
|
||||||
summary: React.ReactNode
|
summary: React.ReactNode
|
||||||
}>) {
|
}
|
||||||
|
>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
preload()
|
preload()
|
||||||
|
|
||||||
|
const user = await getProfileSafely()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnterDetailsProvider step={params.step} >
|
<EnterDetailsProvider step={params.step} isMember={!!user}>
|
||||||
<main className={styles.layout}>
|
<main className={styles.layout}>
|
||||||
{hotelHeader}
|
{hotelHeader}
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import Input from "@/components/TempDesignSystem/Form/Input"
|
|||||||
import Phone from "@/components/TempDesignSystem/Form/Phone"
|
import Phone from "@/components/TempDesignSystem/Form/Phone"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
|
|
||||||
import { detailsSchema, signedInDetailsSchema } from "./schema"
|
import { guestDetailsSchema, signedInDetailsSchema } from "./schema"
|
||||||
import Signup from "./Signup"
|
import Signup from "./Signup"
|
||||||
|
|
||||||
import styles from "./details.module.css"
|
import styles from "./details.module.css"
|
||||||
@@ -53,7 +53,7 @@ export default function Details({ user }: DetailsProps) {
|
|||||||
},
|
},
|
||||||
criteriaMode: "all",
|
criteriaMode: "all",
|
||||||
mode: "all",
|
mode: "all",
|
||||||
resolver: zodResolver(user ? signedInDetailsSchema : detailsSchema),
|
resolver: zodResolver(user ? signedInDetailsSchema : guestDetailsSchema),
|
||||||
reValidateMode: "onChange",
|
reValidateMode: "onChange",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -36,15 +36,17 @@ export const joinDetailsSchema = baseDetailsSchema.merge(
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
export const detailsSchema = z.discriminatedUnion("join", [
|
export const guestDetailsSchema = z.discriminatedUnion("join", [
|
||||||
notJoinDetailsSchema,
|
notJoinDetailsSchema,
|
||||||
joinDetailsSchema,
|
joinDetailsSchema,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// For signed in users we accept partial or invalid data. Users cannot
|
||||||
|
// change their info in this flow, so we don't want to validate it.
|
||||||
export const signedInDetailsSchema = z.object({
|
export const signedInDetailsSchema = z.object({
|
||||||
countryCode: z.string().optional(),
|
countryCode: z.string().optional(),
|
||||||
email: z.string().email().optional(),
|
email: z.string().optional(),
|
||||||
firstName: z.string().optional(),
|
firstName: z.string().optional(),
|
||||||
lastName: z.string().optional(),
|
lastName: z.string().optional(),
|
||||||
phoneNumber: phoneValidator().optional(),
|
phoneNumber: z.string().optional(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,16 +8,17 @@ import {
|
|||||||
initEditDetailsState,
|
initEditDetailsState,
|
||||||
} from "@/stores/enter-details"
|
} from "@/stores/enter-details"
|
||||||
|
|
||||||
import { StepEnum } from "@/types/components/hotelReservation/enterDetails/step"
|
import { EnterDetailsProviderProps } from "@/types/components/hotelReservation/enterDetails/store"
|
||||||
|
|
||||||
export default function EnterDetailsProvider({
|
export default function EnterDetailsProvider({
|
||||||
step,
|
step,
|
||||||
|
isMember,
|
||||||
children,
|
children,
|
||||||
}: PropsWithChildren<{ step: StepEnum }>) {
|
}: PropsWithChildren<EnterDetailsProviderProps>) {
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
const initialStore = useRef<EnterDetailsStore>()
|
const initialStore = useRef<EnterDetailsStore>()
|
||||||
if (!initialStore.current) {
|
if (!initialStore.current) {
|
||||||
initialStore.current = initEditDetailsState(step, searchParams)
|
initialStore.current = initEditDetailsState(step, searchParams, isMember)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { create, useStore } from "zustand"
|
|||||||
|
|
||||||
import { bedTypeSchema } from "@/components/HotelReservation/EnterDetails/BedType/schema"
|
import { bedTypeSchema } from "@/components/HotelReservation/EnterDetails/BedType/schema"
|
||||||
import { breakfastStoreSchema } from "@/components/HotelReservation/EnterDetails/Breakfast/schema"
|
import { breakfastStoreSchema } from "@/components/HotelReservation/EnterDetails/Breakfast/schema"
|
||||||
import { detailsSchema } from "@/components/HotelReservation/EnterDetails/Details/schema"
|
import {
|
||||||
|
guestDetailsSchema,
|
||||||
|
signedInDetailsSchema,
|
||||||
|
} from "@/components/HotelReservation/EnterDetails/Details/schema"
|
||||||
import { getQueryParamsForEnterDetails } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
|
import { getQueryParamsForEnterDetails } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
|
||||||
|
|
||||||
import type { BookingData } from "@/types/components/hotelReservation/enterDetails/bookingData"
|
import type { BookingData } from "@/types/components/hotelReservation/enterDetails/bookingData"
|
||||||
@@ -39,7 +42,8 @@ interface EnterDetailsState {
|
|||||||
|
|
||||||
export function initEditDetailsState(
|
export function initEditDetailsState(
|
||||||
currentStep: StepEnum,
|
currentStep: StepEnum,
|
||||||
searchParams: ReadonlyURLSearchParams
|
searchParams: ReadonlyURLSearchParams,
|
||||||
|
isMember: boolean
|
||||||
) {
|
) {
|
||||||
const isBrowser = typeof window !== "undefined"
|
const isBrowser = typeof window !== "undefined"
|
||||||
const sessionData = isBrowser
|
const sessionData = isBrowser
|
||||||
@@ -93,6 +97,7 @@ export function initEditDetailsState(
|
|||||||
initialData = { ...initialData, ...validatedBreakfast.data }
|
initialData = { ...initialData, ...validatedBreakfast.data }
|
||||||
isValid[StepEnum.breakfast] = true
|
isValid[StepEnum.breakfast] = true
|
||||||
}
|
}
|
||||||
|
const detailsSchema = isMember ? signedInDetailsSchema : guestDetailsSchema
|
||||||
const validatedDetails = detailsSchema.safeParse(inputUserData)
|
const validatedDetails = detailsSchema.safeParse(inputUserData)
|
||||||
if (validatedDetails.success) {
|
if (validatedDetails.success) {
|
||||||
validPaths.push(StepEnum.payment)
|
validPaths.push(StepEnum.payment)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
import { detailsSchema } from "@/components/HotelReservation/EnterDetails/Details/schema"
|
import { guestDetailsSchema } from "@/components/HotelReservation/EnterDetails/Details/schema"
|
||||||
|
|
||||||
import type { SafeUser } from "@/types/user"
|
import type { SafeUser } from "@/types/user"
|
||||||
|
|
||||||
export type DetailsSchema = z.output<typeof detailsSchema>
|
export type DetailsSchema = z.output<typeof guestDetailsSchema>
|
||||||
|
|
||||||
export interface DetailsProps {
|
export interface DetailsProps {
|
||||||
user: SafeUser
|
user: SafeUser
|
||||||
|
|||||||
3
types/components/hotelReservation/enterDetails/store.ts
Normal file
3
types/components/hotelReservation/enterDetails/store.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { StepEnum } from "./step"
|
||||||
|
|
||||||
|
export type EnterDetailsProviderProps = { step: StepEnum; isMember: boolean }
|
||||||
Reference in New Issue
Block a user