Add receipt tokens and booking_seats table to track individual tickets Create receipt and seat view pages with QR code generation
70 lines
1.5 KiB
Vue
70 lines
1.5 KiB
Vue
<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>
|