'use client'; import { useEffect } from 'react'; import { QRCodeSVG } from 'qrcode.react'; import toast from 'react-hot-toast'; import { XMarkIcon, ArrowDownTrayIcon, CalendarDaysIcon, CalendarIcon, MapPinIcon, ClockIcon, UserPlusIcon, } from '@heroicons/react/24/outline'; import Button from '@/components/ui/Button'; import type { UserTicket } from '@/lib/api'; import { formatDateLong, formatTime } from '@/lib/utils'; import { ticketScanUrl, ticketPdfUrl, googleCalendarUrl, shareTicket, } from './helpers'; /** * Full-screen, scannable QR view for the door. Handles single tickets and * multi-ticket bookings (one QR per ticket, with "Share with a guest" on the * spares so guests can be let in with their own code). */ export default function QrTicketModal({ tickets, locale, onClose, }: { tickets: UserTicket[]; locale: string; onClose: () => void; }) { useEffect(() => { const onKey = (e: KeyboardEvent) => e.key === 'Escape' && onClose(); document.addEventListener('keydown', onKey); document.body.style.overflow = 'hidden'; return () => { document.removeEventListener('keydown', onKey); document.body.style.overflow = ''; }; }, [onClose]); if (tickets.length === 0) return null; const first = tickets[0]; const event = first.event; const eventTitle = (locale === 'es' && event?.titleEs ? event.titleEs : event?.title) || 'Event'; const isMulti = tickets.length > 1; const handleShare = async (ticketId: string) => { const result = await shareTicket(ticketId, eventTitle, locale); if (result === 'copied') { toast.success(locale === 'es' ? 'Enlace copiado' : 'Link copied'); } else if (result === 'failed') { toast.error(locale === 'es' ? 'No se pudo compartir' : 'Could not share'); } }; return (
{/* Top bar */}
{isMulti ? locale === 'es' ? `${tickets.length} entradas` : `${tickets.length} tickets` : locale === 'es' ? 'Tu entrada' : 'Your ticket'}
{/* Event details */}

{eventTitle}

{event && (

{formatDateLong(event.startDatetime, locale as 'en' | 'es')}

{formatTime(event.startDatetime, locale as 'en' | 'es')}

{event.location}

)}
{/* One QR per ticket */}
{tickets.map((ticket, idx) => { const attendee = [ticket.attendeeFirstName, ticket.attendeeLastName] .filter(Boolean) .join(' '); const isSpare = isMulti && idx > 0; return (
{isMulti && (

{locale === 'es' ? 'Entrada' : 'Ticket'} {idx + 1} {attendee ? ` • ${attendee}` : ''} {isSpare ? ` • ${locale === 'es' ? 'Invitado' : 'Guest'}` : ''}

)}

{ticket.qrCode}

{isSpare && ( )}
); })}
{/* Download + calendar */}
{event && ( )}
); }