import { z } from "zod" import { dt } from "@/lib/dt" import { specialRequestSchema } from "@/components/HotelReservation/EnterDetails/Details/SpecialRequests/schema" import { phoneValidator } from "@/utils/zod/phoneValidator" // stringMatcher regex is copied from current web as specified by requirements. const stringMatcher = /^[A-Za-z¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ0-9-\s]*$/ const isValidString = (key: string) => stringMatcher.test(key) export const baseDetailsSchema = z.object({ countryCode: z.string().min(1, { message: "Country is required" }), email: z.string().email({ message: "Email address is required" }), firstName: z .string() .min(1, { message: "First name is required" }) .refine(isValidString, { message: "First name can't contain any special characters", }), lastName: z .string() .min(1, { message: "Last name is required" }) .refine(isValidString, { message: "Last name can't contain any special characters", }), phoneNumber: phoneValidator(), specialRequest: specialRequestSchema, }) export const notJoinDetailsSchema = baseDetailsSchema.merge( z.object({ join: z.literal(false), zipCode: z.string().optional(), dateOfBirth: z.string().optional(), membershipNo: z .string() .optional() .refine((val) => { if (val) { return !val.match(/[^0-9]/g) } return true }, "Only digits are allowed") .refine((num) => { if (num) { return num.match(/^30812(?!(0|1|2))[0-9]{9}$/) } return true }, "Invalid membership number format"), }) ) export const joinDetailsSchema = baseDetailsSchema.merge( z.object({ join: z.literal(true), zipCode: z.string().min(1, { message: "Zip code is required" }), dateOfBirth: z .string() .min(1, { message: "Date of birth is required" }) .refine( (date) => { const today = dt() const dob = dt(date) const age = today.diff(dob, "year") return age >= 18 }, { message: "Must be at least 18 years of age to continue" } ), membershipNo: z.string().default(""), }) ) export const guestDetailsSchema = z.discriminatedUnion("join", [ notJoinDetailsSchema, 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({ countryCode: z.string().default(""), email: z.string().default(""), firstName: z.string().default(""), lastName: z.string().default(""), membershipNo: z.string().default(""), phoneNumber: z.string().default(""), join: z .boolean() .optional() .transform((_) => false), dateOfBirth: z.string().default(""), zipCode: z.string().default(""), specialRequest: specialRequestSchema, })