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), childrenInRoom: 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.childrenInRoom.filter( (c) => c.bed === ChildBedMapEnum.IN_ADULTS_BED ) if (value.adults < childrenInAdultsBed.length) { const lastAdultBedIndex = value.childrenInRoom .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: ["childrenInRoom", lastAdultBedIndex], }) } }) export const guestRoomsSchema = z.array(guestRoomSchema) export const bookingCodeSchema = z .object({ value: z .string() .refine( (value) => { if ( !value || /(^D\d*$)|(^DSH[0-9a-z]*$)|(^L\d*$)|(^LH[0-9a-z]*$)|(^B[a-z]{3}\d{6})|(^VO[0-9a-z]*$)|^[0-9a-z]*$/i.test( value ) ) { return true } else { return false } }, { message: "Invalid booking code" } ) .default(""), remember: z.boolean().default(false), flag: z.boolean().default(false), }) .optional() export const bookingWidgetSchema = z .object({ bookingCode: bookingCodeSchema, date: z.object({ // Update this as required once started working with Date picker in Nights component fromDate: z.string(), toDate: z.string(), }), location: z.string().refine( (value) => { if (!value) { return false } try { const parsedValue: Location = JSON.parse(decodeURIComponent(value)) switch (parsedValue?.type) { case "cities": case "hotels": return true default: return false } } catch { return false } }, { message: "Required" } ), redemption: z.boolean().default(false), rooms: guestRoomsSchema, search: z.string({ coerce: true }).min(1, "Required"), voucher: z.boolean().default(false), hotel: z.number().optional(), city: z.string().optional(), }) .superRefine((value, ctx) => { if (!value.hotel && !value.city) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Destination required", path: ["search"], }) } if ( value.rooms.length > 1 && value.bookingCode?.value.toLowerCase().startsWith("vo") ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Multiroom with voucher error", path: ["bookingCode.value"], }) ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Multiroom with voucher error", path: ["rooms"], }) } })