import { z } from "zod" import { phoneValidator } from "@scandic-hotels/common/utils/zod/phoneValidator" import { multiroomErrors } from "../../enterDetailsErrors" import { specialRequestSchema } from "../SpecialRequests/schema" // 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 type CrossValidationData = { firstName: string | undefined lastName: string | undefined membershipNo: string | undefined } export type MultiroomDetailsSchema = z.output< ReturnType > export function getMultiroomDetailsSchema( crossValidationData: CrossValidationData[] | undefined = [] ) { return z .object({ countryCode: z.string().min(1, multiroomErrors.COUNTRY_REQUIRED), email: z.string().email(multiroomErrors.EMAIL_REQUIRED), firstName: z .string() .min(1, multiroomErrors.FIRST_NAME_REQUIRED) .refine(isValidString, multiroomErrors.FIRST_NAME_SPECIAL_CHARACTERS), join: z.boolean().default(false), lastName: z .string() .min(1, multiroomErrors.LAST_NAME_REQUIRED) .refine(isValidString, multiroomErrors.LAST_NAME_SPECIAL_CHARACTERS), phoneNumber: phoneValidator( multiroomErrors.PHONE_REQUIRED, multiroomErrors.PHONE_REQUESTED ), phoneNumberCC: z.string(), membershipNo: z .string() .optional() .refine((val) => { if (val) { return !val.match(/[^0-9]/g) } return true }, multiroomErrors.MEMBERSHIP_NO_ONLY_DIGITS) .refine((num) => { if (num) { return num.match(/^30812(?!(0|1|2))[0-9]{9}$/) } return true }, multiroomErrors.MEMBERSHIP_NO_INVALID), specialRequest: specialRequestSchema, }) .refine( (data) => !crossValidationData.some( (room) => room.firstName?.toLowerCase() === data.firstName.toLowerCase() && room.lastName?.toLowerCase() === data.lastName.toLowerCase() ), { message: multiroomErrors.FIRST_AND_LAST_NAME_UNIQUE, path: ["firstName"], } ) .refine( (data) => !crossValidationData.some( (room) => room.firstName?.toLowerCase() === data.firstName.toLowerCase() && room.lastName?.toLowerCase() === data.lastName.toLowerCase() ), { message: multiroomErrors.FIRST_AND_LAST_NAME_UNIQUE, path: ["lastName"], } ) .refine( (data) => !crossValidationData.some( (room) => room.membershipNo && room.membershipNo === data.membershipNo ), { message: multiroomErrors.MEMBERSHIP_NO_UNIQUE, path: ["membershipNo"], } ) }