import dayjs from "dayjs" import { z } from "zod" import { Lang } from "@/constants/languages" import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" import { BreakfastPackageEnum } from "@/types/enums/breakfast" import { Country } from "@/types/enums/country" export const hotelsAvailabilityInputSchema = z .object({ cityId: z.string(), roomStayStartDate: z.string().refine( (val) => { const fromDate = dayjs(val) return fromDate.isValid() }, { message: "FROMDATE_INVALID", } ), roomStayEndDate: z.string().refine( (val) => { const fromDate = dayjs(val) return fromDate.isValid() }, { message: "TODATE_INVALID", } ), adults: z.number(), children: z.string().optional(), bookingCode: z.string().optional().default(""), redemption: z.boolean().optional().default(false), }) .refine( (data) => { const fromDate = dayjs(data.roomStayStartDate).startOf("day") const toDate = dayjs(data.roomStayEndDate).startOf("day") return fromDate.isBefore(toDate) }, { message: "FROMDATE_BEFORE_TODATE", } ) .refine( (data) => { const fromDate = dayjs(data.roomStayStartDate) const today = dayjs().startOf("day") return fromDate.isSameOrAfter(today) }, { message: "FROMDATE_CANNOT_BE_IN_THE_PAST", } ) export const getHotelsByHotelIdsAvailabilityInputSchema = z .object({ hotelIds: z.array(z.number()), roomStayStartDate: z.string().refine( (val) => { const fromDate = dayjs(val) return fromDate.isValid() }, { message: "FROMDATE_INVALID", } ), roomStayEndDate: z.string().refine( (val) => { const toDate = dayjs(val) return toDate.isValid() }, { message: "TODATE_INVALID", } ), adults: z.number(), children: z.string().optional(), bookingCode: z.string().optional().default(""), }) .refine( (data) => { const fromDate = dayjs(data.roomStayStartDate).startOf("day") const toDate = dayjs(data.roomStayEndDate).startOf("day") return fromDate.isBefore(toDate) }, { message: "FROMDATE_BEFORE_TODATE", } ) .refine( (data) => { const fromDate = dayjs(data.roomStayStartDate) const today = dayjs().startOf("day") return fromDate.isSameOrAfter(today) }, { message: "FROMDATE_CANNOT_BE_IN_THE_PAST", } ) const childrenInRoomSchema = z .array( z.object({ age: z.number(), bed: z.nativeEnum(ChildBedMapEnum), }) ) .optional() const baseRoomSchema = z.object({ adults: z.number().int().min(1), bookingCode: z.string().optional(), childrenInRoom: childrenInRoomSchema, packages: z .array(z.nativeEnum({ ...BreakfastPackageEnum, ...RoomPackageCodeEnum })) .optional(), }) const selectedRoomSchema = z.object({ counterRateCode: z.string().optional(), rateCode: z.string(), roomTypeCode: z.string(), }) const baseBookingSchema = z.object({ bookingCode: z.string().optional(), fromDate: z.string(), hotelId: z.string(), searchType: z.string().optional(), toDate: z.string(), }) export const selectRateRoomsAvailabilityInputSchema = z .object({ booking: baseBookingSchema.extend({ rooms: z.array(baseRoomSchema), }), lang: z.nativeEnum(Lang), }) .refine( (data) => { const fromDate = dayjs(data.booking.fromDate) return fromDate.isValid() }, { message: "FROMDATE_INVALID", } ) .refine( (data) => { const toDate = dayjs(data.booking.toDate) return toDate.isValid() }, { message: "TODATE_INVALID", } ) .refine( (data) => { const fromDate = dayjs(data.booking.fromDate).startOf("day") const toDate = dayjs(data.booking.toDate).startOf("day") return fromDate.isBefore(toDate) }, { message: "TODATE_MUST_BE_AFTER_FROMDATE", } ) .refine( (data) => { const fromDate = dayjs(data.booking.fromDate) const today = dayjs().startOf("day") return fromDate.isSameOrAfter(today) }, { message: "FROMDATE_CANNOT_BE_IN_THE_PAST", } ) export const selectRateRoomAvailabilityInputSchema = z.object({ booking: baseBookingSchema.extend({ room: baseRoomSchema, }), lang: z.nativeEnum(Lang), }) export const enterDetailsRoomsAvailabilityInputSchema = z.object({ booking: baseBookingSchema.extend({ rooms: z.array(baseRoomSchema.merge(selectedRoomSchema)), }), lang: z.nativeEnum(Lang), }) export const myStayRoomAvailabilityInputSchema = z.object({ booking: baseBookingSchema.extend({ room: baseRoomSchema.merge(selectedRoomSchema), }), lang: z.nativeEnum(Lang), }) export const roomFeaturesInputSchema = z.object({ adults: z.number(), childrenInRoom: childrenInRoomSchema, endDate: z.string(), hotelId: z.string(), lang: z.nativeEnum(Lang), roomFeatureCodes: z .array(z.nativeEnum({ ...BreakfastPackageEnum, ...RoomPackageCodeEnum })) .optional(), startDate: z.string(), }) export type RoomFeaturesInput = z.input export const hotelInputSchema = z.object({ hotelId: z.string(), isCardOnlyPayment: z.boolean(), language: z.nativeEnum(Lang), }) export const getHotelsByCSFilterInput = z.object({ locationFilter: z .object({ city: z.string().nullable(), country: z.nativeEnum(Country).nullable(), excluded: z.array(z.string()), }) .nullable(), hotelsToInclude: z.array(z.string()), }) export interface GetHotelsByCSFilterInput extends z.infer {} export const nearbyHotelIdsInput = z.object({ hotelId: z.string(), }) export const getDestinationsMapDataInput = z .object({ lang: z.nativeEnum(Lang), warmup: z.boolean().optional(), }) .optional() export const breakfastPackageInputSchema = z.object({ adults: z.number().min(1, { message: "at least one adult is required" }), fromDate: z .string() .min(1, { message: "fromDate is required" }) .pipe(z.coerce.date()), hotelId: z.string().min(1, { message: "hotelId is required" }), toDate: z .string() .min(1, { message: "toDate is required" }) .pipe(z.coerce.date()), }) export const ancillaryPackageInputSchema = z.object({ fromDate: z .string() .min(1, { message: "fromDate is required" }) .pipe(z.coerce.date()), hotelId: z.string().min(1, { message: "hotelId is required" }), toDate: z.string().pipe(z.coerce.date()).optional(), }) export const roomPackagesInputSchema = z.object({ adults: z.number(), children: z.number().optional().default(0), endDate: z.string(), hotelId: z.string(), lang: z.nativeEnum(Lang), packageCodes: z.array(z.string()).optional().default([]), startDate: z.string(), }) export const cityCoordinatesInputSchema = z.object({ city: z.string(), hotel: z.object({ address: z.string().optional(), }), }) export const getMeetingRoomsInputSchema = z.object({ hotelId: z.string(), language: z.string(), }) export const getAdditionalDataInputSchema = z.object({ hotelId: z.string(), language: z.string(), }) export const getHotelsByCountryInput = z.object({ country: z.nativeEnum(Country), }) export const getHotelsByCityIdentifierInput = z.object({ cityIdentifier: z.string(), }) export const getLocationsInput = z.object({ lang: z.nativeEnum(Lang), }) export const getLocationsUrlsInput = z.object({ lang: z.nativeEnum(Lang), })