feat(bookings): implement ticket receipts and seat sharing system

Add receipt tokens and booking_seats table to track individual tickets
Create receipt and seat view pages with QR code generation
This commit is contained in:
2026-04-12 22:48:26 +08:00
parent 7f582b530c
commit 6194c96ead
15 changed files with 1663 additions and 61 deletions

View File

@@ -0,0 +1,69 @@
<script lang="ts" setup>
import QRCode from 'qrcode'
const props = withDefaults(defineProps<{
value: string
size?: number
}>(), {
size: 220
})
const markup = ref('')
const renderError = ref('')
async function renderQrCode() {
if (!props.value) {
markup.value = ''
renderError.value = ''
return
}
try {
markup.value = await QRCode.toString(props.value, {
type: 'svg',
errorCorrectionLevel: 'M',
margin: 1,
width: props.size
})
renderError.value = ''
} catch (error: any) {
markup.value = ''
renderError.value = error?.message || 'Unable to generate QR code.'
}
}
watch(
() => [props.value, props.size],
() => {
void renderQrCode()
},
{ immediate: true }
)
</script>
<template>
<div class="inline-flex flex-col items-center gap-2">
<div
v-if="markup"
class="overflow-hidden rounded-2xl border border-default bg-default p-4 shadow-sm"
>
<div
class="[&>svg]:block [&>svg]:h-auto [&>svg]:w-full"
:style="{ width: `${size}px` }"
v-html="markup"
/>
</div>
<div
v-else
class="flex items-center justify-center rounded-2xl border border-dashed border-muted bg-elevated p-4 text-center text-sm text-muted"
:style="{ width: `${size}px`, minHeight: `${size}px` }"
>
QR code unavailable
</div>
<p v-if="renderError" class="text-center text-xs text-error">
{{ renderError }}
</p>
</div>
</template>