New booking dashboard

This commit is contained in:
Jose Selesan
2026-04-09 14:54:13 -03:00
parent 11dd12682c
commit aa2fe41ecc
16 changed files with 1292 additions and 42 deletions

View File

@@ -0,0 +1,67 @@
import { z } from 'zod'
const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
const BOOKING_CODE_REGEX = /^[A-Z0-9]{6,8}$/
export const bookingStatusSchema = z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED'])
export const adminBookingSportSchema = z.object({
id: z.uuid(),
name: z.string(),
slug: z.string(),
})
export const adminBookingSchema = z.object({
id: z.uuid(),
bookingCode: z.string().regex(BOOKING_CODE_REGEX),
complexId: z.uuid(),
complexName: z.string(),
courtId: z.uuid(),
courtName: z.string(),
sport: adminBookingSportSchema,
date: z.string().regex(ISO_DATE_REGEX),
startTime: z.string().regex(TIME_REGEX),
endTime: z.string().regex(TIME_REGEX),
customerName: z.string(),
customerPhone: z.string(),
status: bookingStatusSchema,
createdAt: z.string().datetime(),
updatedAt: z.string().datetime(),
})
export const listAdminBookingsQuerySchema = z.object({
fromDate: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'),
})
export const listAdminBookingsResponseSchema = z.object({
bookings: z.array(adminBookingSchema),
})
export const createAdminBookingSchema = z.object({
date: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'),
courtId: z.uuid('El courtId debe ser un UUID valido.'),
startTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.'),
customerName: z
.string()
.trim()
.min(2, 'El nombre debe tener al menos 2 caracteres.')
.max(120, 'El nombre no puede superar los 120 caracteres.'),
customerPhone: z
.string()
.trim()
.min(6, 'El telefono debe tener al menos 6 caracteres.')
.max(30, 'El telefono no puede superar los 30 caracteres.'),
})
export const updateAdminBookingStatusSchema = z.object({
status: z.enum(['CANCELLED', 'COMPLETED']),
})
export type BookingStatus = z.infer<typeof bookingStatusSchema>
export type AdminBookingSport = z.infer<typeof adminBookingSportSchema>
export type AdminBooking = z.infer<typeof adminBookingSchema>
export type ListAdminBookingsQuery = z.infer<typeof listAdminBookingsQuerySchema>
export type ListAdminBookingsResponse = z.infer<typeof listAdminBookingsResponseSchema>
export type CreateAdminBookingInput = z.infer<typeof createAdminBookingSchema>
export type UpdateAdminBookingStatusInput = z.infer<typeof updateAdminBookingStatusSchema>

View File

@@ -55,6 +55,24 @@ export type {
CreateCourtInput,
UpdateCourtInput,
} from './court'
export {
adminBookingSchema,
adminBookingSportSchema,
bookingStatusSchema,
createAdminBookingSchema,
listAdminBookingsQuerySchema,
listAdminBookingsResponseSchema,
updateAdminBookingStatusSchema,
} from './admin-booking'
export type {
AdminBooking,
AdminBookingSport,
BookingStatus,
CreateAdminBookingInput,
ListAdminBookingsQuery,
ListAdminBookingsResponse,
UpdateAdminBookingStatusInput,
} from './admin-booking'
export {
createPublicBookingSchema,
publicAvailabilityCourtSchema,

View File

@@ -71,7 +71,7 @@ export const publicBookingSchema = z.object({
endTime: z.string().regex(TIME_REGEX),
customerName: z.string(),
customerPhone: z.string(),
status: z.enum(['CONFIRMED', 'CANCELLED']),
status: z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED']),
createdAt: z.string().datetime(),
})
@@ -84,7 +84,7 @@ export const publicBookingConfirmationSchema = z.object({
endTime: z.string().regex(TIME_REGEX),
courtName: z.string(),
sport: publicBookingSportSchema,
status: z.enum(['CONFIRMED', 'CANCELLED']),
status: z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED']),
createdAt: z.string().datetime(),
})