From 9189d588d1c256651954bca03ef30a5e79df0a2c Mon Sep 17 00:00:00 2001 From: Christel Westerberg Date: Thu, 14 Nov 2024 11:41:56 +0100 Subject: [PATCH] fix: validation --- components/Forms/BookingWidget/schema.ts | 39 ++++++++++---- .../GuestsRoomsPicker/AdultSelector/index.tsx | 38 +++----------- .../ChildSelector/ChildInfoSelector.tsx | 52 ++++++++++++------- .../GuestsRoomsPicker/ChildSelector/index.tsx | 19 +++---- components/GuestsRoomsPicker/Form.tsx | 26 ++++++++-- components/GuestsRoomsPicker/index.tsx | 40 +++++++------- 6 files changed, 120 insertions(+), 94 deletions(-) diff --git a/components/Forms/BookingWidget/schema.ts b/components/Forms/BookingWidget/schema.ts index 90f4f6712..9d0c8f247 100644 --- a/components/Forms/BookingWidget/schema.ts +++ b/components/Forms/BookingWidget/schema.ts @@ -1,18 +1,37 @@ import { z } from "zod" +import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" import type { Location } from "@/types/trpc/routers/hotel/locations" -export const guestRoomSchema = z.object({ - adults: z.number().default(1), - child: z - .array( - z.object({ - age: z.number().nonnegative(), - bed: z.number(), - }) +export const guestRoomSchema = z + .object({ + adults: z.number().default(1), + child: z + .array( + z.object({ + age: z.number().min(0, "Age is required"), + bed: z.number().min(0, "Bed choice is required"), + }) + ) + .default([]), + }) + .superRefine((value, ctx) => { + const childrenInAdultsBed = value.child.filter( + (c) => c.bed === ChildBedMapEnum.IN_ADULTS_BED ) - .default([]), -}) + if (value.adults < childrenInAdultsBed.length) { + const lastAdultBedIndex = value.child + .map((c) => c.bed) + .lastIndexOf(ChildBedMapEnum.IN_ADULTS_BED) + + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: + "You cannot have more children in adults bed than adults in the room", + path: ["child", lastAdultBedIndex], + }) + } + }) export const guestRoomsSchema = z.array(guestRoomSchema) diff --git a/components/GuestsRoomsPicker/AdultSelector/index.tsx b/components/GuestsRoomsPicker/AdultSelector/index.tsx index d9069b6d0..008037300 100644 --- a/components/GuestsRoomsPicker/AdultSelector/index.tsx +++ b/components/GuestsRoomsPicker/AdultSelector/index.tsx @@ -9,44 +9,26 @@ import Counter from "../Counter" import styles from "./adult-selector.module.css" -import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" -import { - Child, - SelectorProps, -} from "@/types/components/bookingWidget/guestsRoomsPicker" +import { SelectorProps } from "@/types/components/bookingWidget/guestsRoomsPicker" export default function AdultSelector({ roomIndex = 0, currentAdults, - currentChildren, - childrenInAdultsBed, }: SelectorProps) { + const name = `rooms.${roomIndex}.adults` const intl = useIntl() const adultsLabel = intl.formatMessage({ id: "Adults" }) const { setValue } = useFormContext() - function increaseAdultsCount(roomIndex: number) { + function increaseAdultsCount() { if (currentAdults < 6) { - setValue(`rooms.${roomIndex}.adults`, currentAdults + 1) + setValue(name, currentAdults + 1) } } - function decreaseAdultsCount(roomIndex: number) { + function decreaseAdultsCount() { if (currentAdults > 1) { - setValue(`rooms.${roomIndex}.adults`, currentAdults - 1) - if (childrenInAdultsBed > currentAdults) { - const toUpdateIndex = currentChildren.findIndex( - (child: Child) => child.bed == ChildBedMapEnum.IN_ADULTS_BED - ) - if (toUpdateIndex != -1) { - setValue( - `rooms.${roomIndex}.children.${toUpdateIndex}.bed`, - currentChildren[toUpdateIndex].age < 3 - ? ChildBedMapEnum.IN_CRIB - : ChildBedMapEnum.IN_EXTRA_BED - ) - } - } + setValue(name, currentAdults - 1) } } @@ -57,12 +39,8 @@ export default function AdultSelector({ { - decreaseAdultsCount(roomIndex) - }} - handleOnIncrease={() => { - increaseAdultsCount(roomIndex) - }} + handleOnDecrease={decreaseAdultsCount} + handleOnIncrease={increaseAdultsCount} disableDecrease={currentAdults == 1} disableIncrease={currentAdults == 6} /> diff --git a/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx index 08ff83423..b5a34c168 100644 --- a/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx +++ b/components/GuestsRoomsPicker/ChildSelector/ChildInfoSelector.tsx @@ -15,9 +15,9 @@ import { ChildInfoSelectorProps, } from "@/types/components/bookingWidget/guestsRoomsPicker" -const ageList = Array.from(Array(13).keys()).map((age) => ({ - label: age.toString(), - value: age, +const ageList = [...Array(13)].map((_, i) => ({ + label: i.toString(), + value: i, })) export default function ChildInfoSelector({ @@ -27,22 +27,23 @@ export default function ChildInfoSelector({ index = 0, roomIndex = 0, }: ChildInfoSelectorProps) { + const ageFieldName = `rooms.${roomIndex}.child.${index}.age` + const bedFieldName = `rooms.${roomIndex}.child.${index}.bed` const intl = useIntl() const ageLabel = intl.formatMessage({ id: "Age" }) - const ageReqdErrMsg = intl.formatMessage({ id: "Child age is required" }) const bedLabel = intl.formatMessage({ id: "Bed" }) - const { setValue, formState } = useFormContext() - - function updateSelectedAge(age: number) { - setValue(`rooms.${roomIndex}.child.${index}.age`, age, { - shouldValidate: true, - }) - const availableBedTypes = getAvailableBeds(age) - updateSelectedBed(availableBedTypes[0].value) - } + const errorMessage = intl.formatMessage({ id: "Child age is required" }) + const { setValue, formState, register, trigger } = useFormContext() function updateSelectedBed(bed: number) { setValue(`rooms.${roomIndex}.child.${index}.bed`, bed) + trigger() + } + + function updateSelectedAge(age: number) { + setValue(`rooms.${roomIndex}.child.${index}.age`, age) + const availableBedTypes = getAvailableBeds(age) + updateSelectedBed(availableBedTypes[0].value) } const allBedTypes: ChildBed[] = [ @@ -76,6 +77,10 @@ export default function ChildInfoSelector({ //@ts-expect-error: formState is typed with FormValues const roomErrors = formState.errors.rooms?.[roomIndex]?.child?.[index] + + const ageError = roomErrors?.age + const bedError = roomErrors?.bed + return ( <>
@@ -89,13 +94,15 @@ export default function ChildInfoSelector({ onSelect={(key) => { updateSelectedAge(key as number) }} - name={`rooms.${roomIndex}.child.${index}.age`} placeholder={ageLabel} maxHeight={150} + {...register(ageFieldName, { + required: true, + })} />
- {child.age !== -1 ? ( + {child.age >= 0 ? (