feat(bookings): allow editing and soft-deleting bookings

Add edit modal to update guest details, ticket selection, and quantity
Implement soft delete functionality to archive bookings
This commit is contained in:
2026-05-08 15:57:32 +08:00
parent 1318e766d5
commit e05c238495
7 changed files with 754 additions and 14 deletions

View File

@@ -43,6 +43,38 @@ export function parseCreateBookingInput(body: {
}
}
export function parseUpdateBookingDetailsInput(body: {
customerName?: string
customerPhone?: string
bookingMode?: BookingMode | string | null
quantity?: number
ticketType?: TicketType
remark?: string | null
}) {
const customerName = normalizeFullName(body.customerName || '')
const customerPhone = normalizePhoneNumber(body.customerPhone || '')
const bookingMode = typeof body.bookingMode === 'string' ? body.bookingMode.trim().toLowerCase() : body.bookingMode
const ticketType = typeof body.ticketType === 'string' ? body.ticketType.trim().toLowerCase() : body.ticketType
const quantity = Number(body.quantity)
const remark = typeof body.remark === 'string' ? body.remark.trim() : ''
assertBadRequest(hasValidFullName(customerName), 'Guest or organizer name must be at least 2 characters')
assertBadRequest(isValidPhoneNumber(customerPhone), 'Phone number must include a country code, e.g. +60123456789')
assertBadRequest(typeof bookingMode === 'string' && bookingMode.length > 0, 'Booking mode is required')
assertBadRequest(Number.isInteger(quantity) && quantity >= 1, 'Quantity must be a whole number of at least 1')
assertBadRequest(typeof ticketType === 'string' && ticketType.trim().length > 0, 'Ticket category is required')
assertBadRequest(remark.length <= 1000, 'Remark must be 1,000 characters or fewer')
return {
customerName,
customerPhone,
bookingMode,
quantity,
ticketType,
remark: remark || null
}
}
export function parseBookingRemarkInput(body: {
remark?: string | null
}) {