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:
@@ -1,3 +1,5 @@
|
||||
import type { AppLocale } from './i18n'
|
||||
|
||||
export type BookingMode = string
|
||||
export type TicketType = string
|
||||
export type BookingStatus = 'pending' | 'confirmed'
|
||||
@@ -41,6 +43,7 @@ export interface PublicBooking {
|
||||
event: DinnerEvent
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
locale: AppLocale
|
||||
bookingModeId: string | null
|
||||
bookingMode: BookingMode
|
||||
bookingModeLabel: string
|
||||
@@ -68,6 +71,7 @@ export interface ReceiptBooking {
|
||||
event: DinnerEvent
|
||||
customerName: string
|
||||
customerPhone: string
|
||||
locale: AppLocale
|
||||
bookingModeId: string | null
|
||||
bookingMode: BookingMode
|
||||
bookingModeLabel: string
|
||||
@@ -158,11 +162,15 @@ export function isBookingStatus(value: string | null | undefined): value is Book
|
||||
return value === 'pending' || value === 'confirmed'
|
||||
}
|
||||
|
||||
export function getBookingStatusLabel(value: BookingStatus | string, label?: string | null) {
|
||||
if (label) {
|
||||
export function getBookingStatusLabel(value: BookingStatus | string, label?: string | null, locale: AppLocale = 'en') {
|
||||
if (label && locale !== 'zh') {
|
||||
return label
|
||||
}
|
||||
|
||||
if (locale === 'zh') {
|
||||
return value === 'confirmed' ? '已确认' : '等待负责人确认'
|
||||
}
|
||||
|
||||
return value === 'confirmed' ? 'Confirmed' : 'Pending PIC confirmation'
|
||||
}
|
||||
|
||||
@@ -178,8 +186,8 @@ export function getBookingTicketLabel(booking: Pick<PublicBooking | ReceiptBooki
|
||||
return booking.ticketLabel || booking.ticketType.toUpperCase()
|
||||
}
|
||||
|
||||
export function formatBookingCurrency(value: number) {
|
||||
return new Intl.NumberFormat('en-MY', {
|
||||
export function formatBookingCurrency(value: number, locale: AppLocale = 'en') {
|
||||
return new Intl.NumberFormat(locale === 'zh' ? 'zh-MY' : 'en-MY', {
|
||||
style: 'currency',
|
||||
currency: 'MYR',
|
||||
minimumFractionDigits: 0,
|
||||
@@ -187,8 +195,8 @@ export function formatBookingCurrency(value: number) {
|
||||
}).format(value)
|
||||
}
|
||||
|
||||
export function getSeatLabel(seatNumber: number) {
|
||||
return `Seat ${seatNumber}`
|
||||
export function getSeatLabel(seatNumber: number, locale: AppLocale = 'en') {
|
||||
return locale === 'zh' ? `座位 ${seatNumber}` : `Seat ${seatNumber}`
|
||||
}
|
||||
|
||||
export function calculateBookingInventorySummary(
|
||||
|
||||
Reference in New Issue
Block a user