Add ticket system with QR scanner and PDF generation
- Add ticket validation and check-in API endpoints - Add PDF ticket generation with QR codes (pdfkit) - Add admin QR scanner page with camera support - Add admin site settings page - Update email templates with PDF ticket download link - Add checked_in_by_admin_id field for audit tracking - Update booking success page with ticket download - Various UI improvements to events and booking pages
This commit is contained in:
@@ -120,7 +120,10 @@ export default function EventDetailClient({ eventId, initialEvent }: EventDetail
|
||||
<span className="w-6 h-6 flex items-center justify-center text-primary-yellow text-xl">⏰</span>
|
||||
<div>
|
||||
<p className="font-medium">{t('events.details.time')}</p>
|
||||
<p className="text-gray-600" suppressHydrationWarning>{formatTime(event.startDatetime)}</p>
|
||||
<p className="text-gray-600" suppressHydrationWarning>
|
||||
{formatTime(event.startDatetime)}
|
||||
{event.endDatetime && ` - ${formatTime(event.endDatetime)}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -142,15 +145,17 @@ export default function EventDetailClient({ eventId, initialEvent }: EventDetail
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-3">
|
||||
<UserGroupIcon className="w-6 h-6 text-primary-yellow flex-shrink-0" />
|
||||
<div>
|
||||
<p className="font-medium">{t('events.details.capacity')}</p>
|
||||
<p className="text-gray-600">
|
||||
{event.availableSeats} / {event.capacity} {t('events.details.spotsLeft')}
|
||||
</p>
|
||||
{!event.externalBookingEnabled && (
|
||||
<div className="flex items-start gap-3">
|
||||
<UserGroupIcon className="w-6 h-6 text-primary-yellow flex-shrink-0" />
|
||||
<div>
|
||||
<p className="font-medium">{t('events.details.capacity')}</p>
|
||||
<p className="text-gray-600">
|
||||
{event.availableSeats} / {event.capacity} {t('events.details.spotsLeft')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-8 pt-8 border-t border-secondary-light-gray">
|
||||
@@ -213,9 +218,11 @@ export default function EventDetailClient({ eventId, initialEvent }: EventDetail
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<p className="mt-4 text-center text-sm text-gray-500">
|
||||
{event.availableSeats} {t('events.details.spotsLeft')}
|
||||
</p>
|
||||
{!event.externalBookingEnabled && (
|
||||
<p className="mt-4 text-center text-sm text-gray-500">
|
||||
{event.availableSeats} {t('events.details.spotsLeft')}
|
||||
</p>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user