Files
web/server/routers/booking/input.ts
Bianca Widstam 541b91e34c Merged in feat/SW-1281-ancillaries-add-flow (pull request #1399)
Feat/SW-1281 ancillaries add flow

* feat(SW-1546): update design

* feat(SW-1546): show points only if logged in

* feat(SW-1546): always show points

* feat(SW-1281): ancillary add flow initial

* feat(SW-1546): add api call

* feat(SW-1281): refactor naming and break out components

* feat(SW-1281): handle back button

* feat(SW-1281): make mobile cards clickable

* feat(SW-1281): refactor spread ancillaries

* feat(SW-1281): add deliverytimes

* feat(SW-1281): rebase master

* feat(SW-1281): add design for logged in or not

* feat(SW-1281): add design

* feat(SW-1281): add mobile design

* feat(SW-1281): fix carousel

* feat(SW-1281): show deliverytime only if ancillary has not been added

* feat(SW-1281): add design

* feat(SW-1281): add translations

* feat(SW-1281): add translations

* feat(SW-1281): add translations

* feat(SW-1281): base dates on check in date only

* feat(SW-1281): fix show correct toast when no valid data

* feat(SW-1281): hande logic if deliverytime is not required

* feat(SW-1281): fix max width for mobile

* feat(SW-1281): refactor after pr comment


Approved-by: Niclas Edenvin
Approved-by: Linus Flood
2025-02-26 07:20:45 +00:00

119 lines
2.9 KiB
TypeScript

import { z } from "zod"
import { ChildBedTypeEnum } from "@/constants/booking"
import { Lang, langToApiLang } from "@/constants/languages"
const signupSchema = z.discriminatedUnion("becomeMember", [
z.object({
dateOfBirth: z.string(),
postalCode: z.string(),
becomeMember: z.literal<boolean>(true),
}),
z.object({ becomeMember: z.literal<boolean>(false) }),
])
const roomsSchema = z.array(
z.object({
adults: z.number().int().nonnegative(),
childrenAges: z
.array(
z.object({
age: z.number().int().nonnegative(),
bedType: z.nativeEnum(ChildBedTypeEnum),
})
)
.default([]),
rateCode: z.string(),
roomTypeCode: z.coerce.string(),
guest: z.intersection(
z.object({
firstName: z.string(),
lastName: z.string(),
email: z.string().email(),
phoneNumber: z.string(),
countryCode: z.string(),
membershipNumber: z.string().optional(),
}),
signupSchema
),
smsConfirmationRequested: z.boolean(),
packages: z.object({
breakfast: z.boolean(),
allergyFriendly: z.boolean(),
petFriendly: z.boolean(),
accessibility: z.boolean(),
}),
roomPrice: z.object({
publicPrice: z.number().or(z.string().transform((val) => Number(val))),
memberPrice: z
.number()
.or(z.string().transform((val) => Number(val)))
.optional(),
}),
})
)
const paymentSchema = z.object({
paymentMethod: z.string(),
card: z
.object({
alias: z.string(),
expiryDate: z.string(),
cardType: z.string(),
})
.optional(),
cardHolder: z
.object({
email: z.string().email(),
name: z.string(),
phoneCountryCode: z.string(),
phoneSubscriber: z.string(),
})
.optional(),
success: z.string(),
error: z.string(),
cancel: z.string(),
})
// Mutation
export const createBookingInput = z.object({
hotelId: z.string(),
checkInDate: z.string(),
checkOutDate: z.string(),
rooms: roomsSchema,
payment: paymentSchema,
language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]),
})
export const addPackageInput = z.object({
confirmationNumber: z.string(),
ancillaryComment: z.string(),
ancillaryDeliveryTime: z.string().optional(),
packages: z.array(
z.object({
code: z.string(),
quantity: z.number(),
comment: z.string().optional(),
})
),
language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]),
})
export const priceChangeInput = z.object({
confirmationNumber: z.string(),
})
export const cancelBookingInput = z.object({
confirmationNumber: z.string(),
language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]),
})
// Query
const confirmationNumberInput = z.object({
confirmationNumber: z.string(),
})
export const bookingConfirmationInput = confirmationNumberInput
export const getBookingStatusInput = confirmationNumberInput