"use client" import { useState, useEffect } from "react" import { useParams } from "next/navigation" import { Card, CardContent } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Dialog, DialogHeader, DialogTitle } from "@/components/ui/dialog" import { formatPence } from "@/lib/utils" import { Plus, Download, QrCode, ExternalLink, Copy, Check, Loader2, ArrowLeft } from "lucide-react" import Link from "next/link" import { QRCodeCanvas } from "@/components/qr-code" interface QrSourceInfo { id: string label: string code: string volunteerName: string | null tableName: string | null scanCount: number pledgeCount: number totalPledged: number } export default function EventQRPage() { const params = useParams() const eventId = params.id as string const [qrSources, setQrSources] = useState([]) const [loading, setLoading] = useState(true) const [showCreate, setShowCreate] = useState(false) const [copiedCode, setCopiedCode] = useState(null) const [form, setForm] = useState({ label: "", volunteerName: "", tableName: "" }) const [creating, setCreating] = useState(false) const baseUrl = typeof window !== "undefined" ? window.location.origin : "" useEffect(() => { fetch(`/api/events/${eventId}/qr`) .then((r) => r.json()) .then((data) => { if (Array.isArray(data)) setQrSources(data) }) .catch(() => {}) .finally(() => setLoading(false)) }, [eventId]) const copyLink = async (code: string) => { await navigator.clipboard.writeText(`${baseUrl}/p/${code}`) setCopiedCode(code) setTimeout(() => setCopiedCode(null), 2000) } const handleCreate = async () => { setCreating(true) try { const res = await fetch(`/api/events/${eventId}/qr`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(form), }) if (res.ok) { const qr = await res.json() setQrSources((prev) => [{ ...qr, scanCount: 0, pledgeCount: 0, totalPledged: 0 }, ...prev]) setShowCreate(false) setForm({ label: "", volunteerName: "", tableName: "" }) } } catch {} setCreating(false) } // Auto-generate label useEffect(() => { if (form.volunteerName || form.tableName) { const parts = [form.tableName, form.volunteerName].filter(Boolean) setForm((f) => ({ ...f, label: parts.join(" - ") })) } }, [form.volunteerName, form.tableName]) if (loading) { return (
) } const totalScans = qrSources.reduce((s, q) => s + q.scanCount, 0) const totalPledges = qrSources.reduce((s, q) => s + q.pledgeCount, 0) const totalAmount = qrSources.reduce((s, q) => s + q.totalPledged, 0) return (
Back to Events

QR Codes

{qrSources.length} QR code{qrSources.length !== 1 ? "s" : ""} · {totalScans} scans · {totalPledges} pledges · {formatPence(totalAmount)}

{/* QR Grid */} {qrSources.length === 0 ? (

No QR codes yet. Create one to start collecting pledges!

) : (
{qrSources.map((qr) => ( {/* QR Code */}

{qr.label}

{qr.volunteerName && (

Volunteer: {qr.volunteerName}

)}
{/* Stats */}

{qr.scanCount}

Scans

{qr.pledgeCount}

Pledges

{formatPence(qr.totalPledged)}

Total

{/* Conversion rate */} {qr.scanCount > 0 && (
Conversion: {Math.round((qr.pledgeCount / qr.scanCount) * 100)}%
)} {/* Actions */}
))}
)} {/* Create dialog */} Create QR Code
setForm((f) => ({ ...f, tableName: e.target.value }))} />
setForm((f) => ({ ...f, volunteerName: e.target.value }))} />
setForm((f) => ({ ...f, label: e.target.value }))} />

Auto-generated from table + volunteer, or enter custom

) }