feat(i18n): add multi-language support (en/zh) across app and server
Implement useLocale composable and shared translation dictionaries Translate public pages, booking flow, and receipt views Store booking locale to send localized WhatsApp notifications
This commit is contained in:
@@ -14,8 +14,10 @@ import type {
|
||||
TicketCatalogItem,
|
||||
TicketType
|
||||
} from '~~/shared/booking'
|
||||
import type { AppLocale } from '~~/shared/i18n'
|
||||
|
||||
import { calculateBookingInventorySummary, getBookingStatusLabel, isBookingStatus } from '~~/shared/booking'
|
||||
import { resolveLocale } from '~~/shared/i18n'
|
||||
|
||||
import { randomToken, toIsoString } from './base64url'
|
||||
import { ensureDatabaseReady } from './db-init'
|
||||
@@ -32,6 +34,7 @@ type DbBookingRow = {
|
||||
event_venue: string
|
||||
customer_name: string
|
||||
customer_phone: string
|
||||
locale: AppLocale | string | null
|
||||
booking_mode_id: string | null
|
||||
booking_mode: string
|
||||
booking_mode_label: string | null
|
||||
@@ -125,6 +128,7 @@ function bookingSelectColumns(sql: any) {
|
||||
dinner_events.venue as event_venue,
|
||||
bookings.customer_name,
|
||||
bookings.customer_phone,
|
||||
bookings.locale,
|
||||
bookings.booking_mode_id,
|
||||
coalesce(booking_modes.code, bookings.booking_mode) as booking_mode,
|
||||
booking_modes.label as booking_mode_label,
|
||||
@@ -219,6 +223,7 @@ function mapBooking(row: DbBookingRow): PublicBooking {
|
||||
event: mapDinnerEventFromBooking(row),
|
||||
customerName: row.customer_name,
|
||||
customerPhone: row.customer_phone,
|
||||
locale: resolveLocale(row.locale),
|
||||
bookingModeId: row.booking_mode_id,
|
||||
bookingMode,
|
||||
bookingModeLabel: row.booking_mode_label || bookingMode,
|
||||
@@ -253,6 +258,7 @@ function mapReceiptBooking(row: DbBookingRow | DbBookingSeatWithBookingRow): Rec
|
||||
event: mapDinnerEventFromBooking(row),
|
||||
customerName: row.customer_name,
|
||||
customerPhone: row.customer_phone,
|
||||
locale: resolveLocale(row.locale),
|
||||
bookingModeId: row.booking_mode_id,
|
||||
bookingMode,
|
||||
bookingModeLabel: row.booking_mode_label || bookingMode,
|
||||
@@ -278,6 +284,7 @@ function mapPublicBookingToReceiptBooking(booking: PublicBooking): ReceiptBookin
|
||||
event: booking.event,
|
||||
customerName: booking.customerName,
|
||||
customerPhone: booking.customerPhone,
|
||||
locale: booking.locale,
|
||||
bookingModeId: booking.bookingModeId,
|
||||
bookingMode: booking.bookingMode,
|
||||
bookingModeLabel: booking.bookingModeLabel,
|
||||
@@ -461,6 +468,7 @@ export async function createBooking(input: {
|
||||
eventId: string
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
locale: AppLocale
|
||||
bookingModeId: string
|
||||
bookingMode: BookingMode
|
||||
quantity: number
|
||||
@@ -487,6 +495,7 @@ export async function createBooking(input: {
|
||||
event_id,
|
||||
customer_name,
|
||||
customer_phone,
|
||||
locale,
|
||||
booking_mode_id,
|
||||
booking_mode,
|
||||
quantity,
|
||||
@@ -506,6 +515,7 @@ export async function createBooking(input: {
|
||||
${input.eventId},
|
||||
${input.customerName},
|
||||
${input.customerPhone},
|
||||
${input.locale},
|
||||
${input.bookingModeId},
|
||||
${input.bookingMode},
|
||||
${input.quantity},
|
||||
@@ -748,6 +758,7 @@ export async function getSeatReceiptBySeatToken(seatToken: string): Promise<{
|
||||
dinner_events.venue as event_venue,
|
||||
bookings.customer_name,
|
||||
bookings.customer_phone,
|
||||
bookings.locale,
|
||||
bookings.booking_mode_id,
|
||||
coalesce(booking_modes.code, bookings.booking_mode) as booking_mode,
|
||||
booking_modes.label as booking_mode_label,
|
||||
|
||||
Reference in New Issue
Block a user