Files
dticket.tootaio.com/app/components/QrCodeSvg.vue
xiaomai 6194c96ead 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
2026-04-12 22:48:26 +08:00

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>