import React, { useCallback, useEffect, useState } from "react"; import { Copy, Download, Plus, Tag, X } from "lucide-react"; import { useAuth } from "../../contexts/AuthContext"; import { badgeBatchesApi, type BadgeBatchRecord } from "../../../services/api/badgeBatches"; function formatRequestedAt(createdAt?: string): string { if (!createdAt) return ""; const d = new Date(createdAt); if (Number.isNaN(d.getTime())) return ""; return d.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" }); } function statusLabel(status: BadgeBatchRecord["status"]): string { if (status === "ready") return "Ready"; if (status === "processing") return "Processing"; if (status === "failed") return "Failed"; return "Pending"; } export function EventBadgesPanel({ eventId, eventName, onClose, onAddBadge, onDuplicateBadge, }: { eventId: string; eventName?: string; onClose: () => void; onAddBadge: () => void; onDuplicateBadge: (batchId: string) => void; }) { const { user } = useAuth(); const canManage = Boolean(user && ["super_admin", "admin", "moderator"].includes(user.role)); const [badges, setBadges] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [downloadingId, setDownloadingId] = useState(null); const loadBadges = useCallback(async () => { setLoading(true); setError(""); try { const res = await badgeBatchesApi.list({ event: eventId, limit: 100 }); if (res.error) { setError(typeof res.error === "string" ? res.error : "Failed to load badges."); setBadges([]); } else { setBadges(res.data?.batches ?? []); } } catch { setError("Failed to load badges."); setBadges([]); } finally { setLoading(false); } }, [eventId]); useEffect(() => { void loadBadges(); }, [loadBadges]); return ( <>

Tag & Badge Configuration

{eventName ? `Badges · ${eventName}` : "Badges"}

{canManage ? ( ) : null}
{loading ? (

Loading badges…

) : null} {error ? (

{error}

) : null} {!loading && !error && badges.length === 0 ? (

No badges yet

Create a badge export to design attendee and speaker badges for this event.

{canManage ? ( ) : null}
) : null} {!loading && !error && badges.length > 0 ? (
{badges.map((b) => (

{b.name}

Status: {statusLabel(b.status)} {b.itemCount != null ? ` · ${b.itemCount} badge${b.itemCount !== 1 ? "s" : ""}` : ""} {b.lastError && b.status === "failed" ? ( {b.lastError} ) : null}
{canManage ? ( ) : null} {b.status === "ready" && b.zipUrl ? ( ) : ( )}
{b.createdAt ? ( Requested {formatRequestedAt(b.createdAt)} ) : null}
))}
) : null}
); }