Implement useLocale composable and shared translation dictionaries Translate public pages, booking flow, and receipt views Store booking locale to send localized WhatsApp notifications
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import type { BookingMode, CreateBookingResponse, TicketType } from '~~/shared/booking'
|
|
|
|
import { getSeatCount } from '~~/shared/booking'
|
|
|
|
import { buildAppUrl } from '../../utils/app-url'
|
|
import {
|
|
createBooking,
|
|
getActiveBookingModeOptionByCode,
|
|
getActiveTicketCatalogItemByCode
|
|
} from '../../utils/booking-repository'
|
|
import { buildBookingMessage, parseCreateBookingInput } from '../../utils/bookings'
|
|
import { assertBadRequest } from '../../utils/http'
|
|
import { getPublicContactById } from '../../utils/user-repository'
|
|
import { buildWhatsAppDeepLink } from '../../utils/whatsapp'
|
|
|
|
export default defineEventHandler(async (event): Promise<CreateBookingResponse> => {
|
|
const body = await readBody<{
|
|
customerName?: string
|
|
customerPhone?: string
|
|
bookingMode?: BookingMode | string | null
|
|
quantity?: number
|
|
ticketType?: TicketType
|
|
personInChargeId?: string
|
|
locale?: string | null
|
|
}>(event)
|
|
|
|
const input = parseCreateBookingInput(body)
|
|
const [personInCharge, bookingMode, ticket] = await Promise.all([
|
|
getPublicContactById(input.personInChargeId),
|
|
getActiveBookingModeOptionByCode(input.bookingMode),
|
|
getActiveTicketCatalogItemByCode(input.ticketType)
|
|
])
|
|
|
|
assertBadRequest(personInCharge, 'Selected person in charge is not available')
|
|
assertBadRequest(bookingMode, 'Booking mode is invalid')
|
|
assertBadRequest(ticket, 'Ticket category is invalid')
|
|
assertBadRequest(bookingMode.eventId === ticket.eventId, 'Booking mode and ticket category must belong to the same event')
|
|
|
|
const seatCount = getSeatCount(bookingMode, input.quantity)
|
|
const totalPrice = seatCount * ticket.price
|
|
|
|
const { booking, confirmationToken } = await createBooking({
|
|
eventId: bookingMode.eventId,
|
|
customerName: input.customerName,
|
|
customerPhone: input.customerPhone,
|
|
locale: input.locale,
|
|
bookingModeId: bookingMode.id,
|
|
bookingMode: bookingMode.value,
|
|
quantity: input.quantity,
|
|
seatCount,
|
|
ticketTypeId: ticket.id,
|
|
ticketType: ticket.value,
|
|
unitPrice: ticket.price,
|
|
totalPrice,
|
|
personInChargeId: personInCharge.id
|
|
})
|
|
|
|
const confirmationUrl = buildAppUrl(event, `/confirmation/${confirmationToken}`)
|
|
const whatsappMessage = buildBookingMessage(booking, confirmationUrl)
|
|
const whatsappUrl = buildWhatsAppDeepLink(booking.personInChargePhoneNumber, whatsappMessage)
|
|
|
|
return {
|
|
booking,
|
|
confirmationUrl,
|
|
whatsappUrl
|
|
}
|
|
})
|