@burdenoff/microfe-eventfullymanaged 2026.704.4 → 2026.704.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventDetailPage.tsx"],"sourcesContent":["import { ArrowLeft, CalendarClock, Edit, MapPin, Plus, Ticket as TicketIcon, Users } from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n IllustratedEmptyState,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useDeleteTicketTypeMutation,\n useEventQuery,\n useEventSessionsQuery,\n useSpeakersQuery,\n useTicketTypesQuery,\n type TicketTypeGql,\n} from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { Pagination, usePagination } from '../../components/Pagination';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { notify } from '../../lib/toast';\nimport { formatDateTime } from './eventFormUtils';\n\nfunction statusVariant(status: string): 'success' | 'warning' | 'secondary' | 'info' {\n const value = status.toLowerCase();\n if (['active', 'published', 'live', 'confirmed', 'completed', 'approved'].includes(value)) {\n return 'success';\n }\n if (['inactive', 'cancelled', 'archived', 'closed', 'expired'].includes(value)) {\n return 'warning';\n }\n if (['draft', 'created', 'pending', 'scheduled'].includes(value)) {\n return 'info';\n }\n return 'secondary';\n}\n\n// ---------------------------------------------------------------------------\n\ntype SessionRow = {\n id: string;\n title: string;\n sessionType: string;\n track?: string | null;\n startsAt: string;\n endsAt: string;\n status: string;\n};\n\nfunction SessionsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading } = useEventSessionsQuery({ eventId, limit: pagination.limit, offset: pagination.offset });\n\n const total = data?.eventSessions?.total ?? 0;\n const rows = (data?.eventSessions?.items ?? []) as unknown as SessionRow[];\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Agenda &amp; Sessions</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/sessions/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Session\n </Button>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading sessions…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No sessions yet.\"\n description=\"Build the agenda by adding your first session.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((session) => (\n <li\n key={session.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{session.title}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {[session.track, session.startsAt ? formatDateTime(session.startsAt) : undefined]\n .filter(Boolean)\n .join(' • ')}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <Badge variant={statusVariant(session.status)} className=\"uppercase\">\n {session.status}\n </Badge>\n <ActionMenu\n ariaLabel={`Session actions for ${session.title}`}\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n />\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sessions\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\ntype SpeakerRow = { id: string; fullName: string; title?: string | null; organization?: string | null };\n\nfunction SpeakersTab() {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading } = useSpeakersQuery({ limit: pagination.limit, offset: pagination.offset });\n\n const total = data?.speakers?.total ?? 0;\n const rows = (data?.speakers?.items ?? []) as unknown as SpeakerRow[];\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Speakers</h2>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate('/speakers')}>\n Manage speakers\n </Button>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate('/speakers/create')}>\n <Plus className=\"h-4 w-4\" />\n New Speaker\n </Button>\n </div>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading speakers…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No speakers yet.\"\n description=\"Add speakers so you can assign them to sessions.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((speaker) => (\n <li\n key={speaker.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{speaker.fullName}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {[speaker.title, speaker.organization].filter(Boolean).join(' • ') || 'Speaker'}\n </p>\n </div>\n <ActionMenu\n ariaLabel={`Speaker actions for ${speaker.fullName}`}\n onEdit={() => navigate(`/speakers/${speaker.id}/edit`)}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"speakers\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nfunction TicketsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useTicketTypesQuery({\n eventId,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteTicketType] = useDeleteTicketTypeMutation();\n\n const total = data?.ticketTypes?.total ?? 0;\n const rows = (data?.ticketTypes?.items ?? []) as TicketTypeGql[];\n\n const onDelete = async (ticket: TicketTypeGql) => {\n const response = await deleteTicketType({ variables: { id: ticket.id } });\n if (response.error) {\n notify.error('Could not delete ticket type', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteTicketType) {\n notify.error('Could not delete ticket type', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Ticket type deleted');\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket Types</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/tickets/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Ticket Type\n </Button>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading ticket types…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No ticket types yet.\"\n description=\"Add a ticket type so attendees can register.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((ticket) => (\n <li\n key={ticket.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{ticket.name}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {ticket.price} {ticket.currency} • Sold {ticket.soldCount}\n {ticket.capacity != null ? ` / ${ticket.capacity}` : ''}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <Badge variant={ticket.isActive ? 'success' : 'warning'} className=\"uppercase\">\n {ticket.isActive ? 'Active' : 'Inactive'}\n </Badge>\n <ActionMenu\n ariaLabel={`Ticket actions for ${ticket.name}`}\n entityName={ticket.name}\n deleteLabel=\"Delete ticket type\"\n onEdit={() => navigate(`/events/${eventId}/tickets/${ticket.id}/edit`)}\n onDelete={() => onDelete(ticket)}\n />\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"ticket types\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nexport default function EventDetailPage() {\n const { id = '' } = useParams<{ id: string }>();\n const { navigate } = useEventfullyManaged();\n const { data, loading } = useEventQuery(id);\n const [tab, setTab] = useState('overview');\n\n const event = data?.event ?? null;\n const venueId = useMemo(() => {\n const metadata = (event?.metadata ?? {}) as Record<string, unknown>;\n return typeof metadata.venueId === 'string' ? (metadata.venueId as string) : '';\n }, [event]);\n\n if (loading) {\n return <div className=\"p-6 text-sm text-text-secondary\">Loading event…</div>;\n }\n\n if (!event) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/events')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Events\n </Button>\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Event not found.\"\n description=\"This event may have been removed or is outside your current scope.\"\n />\n </GlassCard>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-3\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/events')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Events\n </Button>\n <div>\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-2xl font-bold text-text-primary\">{event.name}</h1>\n <Badge variant={statusVariant(event.status)} className=\"uppercase\">\n {event.status}\n </Badge>\n </div>\n <p className=\"mt-1 flex items-center gap-2 text-sm text-text-secondary\">\n <CalendarClock className=\"h-4 w-4\" />\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </p>\n </div>\n </div>\n <Button type=\"button\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit Event\n </Button>\n </div>\n\n <Tabs value={tab} onValueChange={setTab}>\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"sessions\">Sessions</TabsTrigger>\n <TabsTrigger value=\"speakers\">Speakers</TabsTrigger>\n <TabsTrigger value=\"tickets\">Tickets</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"mt-4\">\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <TicketIcon className=\"h-4 w-4 text-action-primary-bg\" />\n Type\n </div>\n <p className=\"text-sm uppercase text-text-secondary\">{event.type}</p>\n </GlassCard>\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <Users className=\"h-4 w-4 text-action-primary-bg\" />\n Capacity\n </div>\n <p className=\"text-sm tabular-nums text-text-secondary\">{event.capacity ?? 0} attendees</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <MapPin className=\"h-4 w-4 text-action-primary-bg\" />\n Timezone\n </div>\n <p className=\"text-sm text-text-secondary\">{event.timezone}</p>\n </GlassCard>\n </div>\n\n <GlassCard treatment=\"plain\" className=\"mt-4 border-border-seam p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">About</h2>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {event.description?.trim() ? event.description : 'No description provided.'}\n </p>\n <dl className=\"mt-4 grid grid-cols-1 gap-3 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-text-muted\">Visibility</dt>\n <dd className=\"capitalize text-text-primary\">{event.visibility}</dd>\n </div>\n <div>\n <dt className=\"text-text-muted\">Venue</dt>\n <dd className=\"text-text-primary\">\n {venueId ? (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n className=\"h-auto p-0\"\n onClick={() => navigate(`/venues/${venueId}`)}\n >\n View venue\n </Button>\n ) : (\n 'No venue assigned'\n )}\n </dd>\n </div>\n </dl>\n <div className=\"mt-4\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit event details\n </Button>\n </div>\n </GlassCard>\n </TabsContent>\n\n <TabsContent value=\"sessions\" className=\"mt-4\">\n <SessionsTab eventId={id} />\n </TabsContent>\n\n <TabsContent value=\"speakers\" className=\"mt-4\">\n <SpeakersTab />\n </TabsContent>\n\n <TabsContent value=\"tickets\" className=\"mt-4\">\n <TicketsTab eventId={id} />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventDetailPage.tsx"],"sourcesContent":["import { ArrowLeft, CalendarClock, Edit, MapPin, Plus, Ticket as TicketIcon, Users } from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n IllustratedEmptyState,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useDeleteEventSessionMutation,\n useDeleteSpeakerMutation,\n useDeleteTicketTypeMutation,\n useEventQuery,\n useEventSessionsQuery,\n useSpeakersQuery,\n useTicketTypesQuery,\n type TicketTypeGql,\n} from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { Pagination, usePagination } from '../../components/Pagination';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { notify } from '../../lib/toast';\nimport { formatDateTime } from './eventFormUtils';\n\nfunction statusVariant(status: string): 'success' | 'warning' | 'secondary' | 'info' {\n const value = status.toLowerCase();\n if (['active', 'published', 'live', 'confirmed', 'completed', 'approved'].includes(value)) {\n return 'success';\n }\n if (['inactive', 'cancelled', 'archived', 'closed', 'expired'].includes(value)) {\n return 'warning';\n }\n if (['draft', 'created', 'pending', 'scheduled'].includes(value)) {\n return 'info';\n }\n return 'secondary';\n}\n\n// ---------------------------------------------------------------------------\n\ntype SessionRow = {\n id: string;\n title: string;\n sessionType: string;\n track?: string | null;\n startsAt: string;\n endsAt: string;\n status: string;\n};\n\nfunction SessionsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useEventSessionsQuery({\n eventId,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteEventSession] = useDeleteEventSessionMutation();\n\n const total = data?.eventSessions?.total ?? 0;\n const rows = (data?.eventSessions?.items ?? []) as unknown as SessionRow[];\n\n const onDelete = async (session: SessionRow) => {\n const response = await deleteEventSession({ variables: { id: session.id } });\n if (response.error) {\n notify.error('Could not delete session', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteEventSession) {\n notify.error('Could not delete session', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Session deleted', session.title);\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Agenda &amp; Sessions</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/sessions/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Session\n </Button>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading sessions…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No sessions yet.\"\n description=\"Build the agenda by adding your first session.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((session) => (\n <li\n key={session.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{session.title}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {[session.track, session.startsAt ? formatDateTime(session.startsAt) : undefined]\n .filter(Boolean)\n .join(' • ')}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <Badge variant={statusVariant(session.status)} className=\"uppercase\">\n {session.status}\n </Badge>\n <ActionMenu\n ariaLabel={`Session actions for ${session.title}`}\n entityName={session.title}\n deleteLabel=\"Delete session\"\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n onDelete={() => onDelete(session)}\n />\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sessions\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\ntype SpeakerRow = { id: string; fullName: string; title?: string | null; organization?: string | null };\n\nfunction SpeakersTab() {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useSpeakersQuery({ limit: pagination.limit, offset: pagination.offset });\n const [deleteSpeaker] = useDeleteSpeakerMutation();\n\n const total = data?.speakers?.total ?? 0;\n const rows = (data?.speakers?.items ?? []) as unknown as SpeakerRow[];\n\n const onDelete = async (speaker: SpeakerRow) => {\n const response = await deleteSpeaker({ variables: { id: speaker.id } });\n if (response.error) {\n notify.error('Could not delete speaker', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteSpeaker) {\n notify.error('Could not delete speaker', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Speaker deleted', speaker.fullName);\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Speakers</h2>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate('/speakers')}>\n Manage speakers\n </Button>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate('/speakers/create')}>\n <Plus className=\"h-4 w-4\" />\n New Speaker\n </Button>\n </div>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading speakers…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-people\"\n title=\"No speakers yet.\"\n description=\"Add speakers so you can assign them to sessions.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((speaker) => (\n <li\n key={speaker.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{speaker.fullName}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {[speaker.title, speaker.organization].filter(Boolean).join(' • ') || 'Speaker'}\n </p>\n </div>\n <ActionMenu\n ariaLabel={`Speaker actions for ${speaker.fullName}`}\n entityName={speaker.fullName}\n deleteLabel=\"Delete speaker\"\n onEdit={() => navigate(`/speakers/${speaker.id}/edit`)}\n onDelete={() => onDelete(speaker)}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"speakers\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nfunction TicketsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useTicketTypesQuery({\n eventId,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteTicketType] = useDeleteTicketTypeMutation();\n\n const total = data?.ticketTypes?.total ?? 0;\n const rows = (data?.ticketTypes?.items ?? []) as TicketTypeGql[];\n\n const onDelete = async (ticket: TicketTypeGql) => {\n const response = await deleteTicketType({ variables: { id: ticket.id } });\n if (response.error) {\n notify.error('Could not delete ticket type', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteTicketType) {\n notify.error('Could not delete ticket type', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Ticket type deleted');\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket Types</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/tickets/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Ticket Type\n </Button>\n </div>\n\n {loading ? (\n <p className=\"text-sm text-text-secondary\">Loading ticket types…</p>\n ) : rows.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No ticket types yet.\"\n description=\"Add a ticket type so attendees can register.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((ticket) => (\n <li\n key={ticket.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{ticket.name}</p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {ticket.price} {ticket.currency} • Sold {ticket.soldCount}\n {ticket.capacity != null ? ` / ${ticket.capacity}` : ''}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <Badge variant={ticket.isActive ? 'success' : 'warning'} className=\"uppercase\">\n {ticket.isActive ? 'Active' : 'Inactive'}\n </Badge>\n <ActionMenu\n ariaLabel={`Ticket actions for ${ticket.name}`}\n entityName={ticket.name}\n deleteLabel=\"Delete ticket type\"\n onEdit={() => navigate(`/events/${eventId}/tickets/${ticket.id}/edit`)}\n onDelete={() => onDelete(ticket)}\n />\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"ticket types\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nexport default function EventDetailPage() {\n const { id = '' } = useParams<{ id: string }>();\n const { navigate } = useEventfullyManaged();\n const { data, loading } = useEventQuery(id);\n const [tab, setTab] = useState('overview');\n\n const event = data?.event ?? null;\n const venueId = useMemo(() => {\n const metadata = (event?.metadata ?? {}) as Record<string, unknown>;\n return typeof metadata.venueId === 'string' ? (metadata.venueId as string) : '';\n }, [event]);\n\n if (loading) {\n return <div className=\"p-6 text-sm text-text-secondary\">Loading event…</div>;\n }\n\n if (!event) {\n return (\n <div className=\"space-y-4 p-6\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/events')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Events\n </Button>\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"Event not found.\"\n description=\"This event may have been removed or is outside your current scope.\"\n />\n </GlassCard>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"space-y-3\">\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/events')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Events\n </Button>\n <div>\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-2xl font-bold text-text-primary\">{event.name}</h1>\n <Badge variant={statusVariant(event.status)} className=\"uppercase\">\n {event.status}\n </Badge>\n </div>\n <p className=\"mt-1 flex items-center gap-2 text-sm text-text-secondary\">\n <CalendarClock className=\"h-4 w-4\" />\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </p>\n </div>\n </div>\n <Button type=\"button\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit Event\n </Button>\n </div>\n\n <Tabs value={tab} onValueChange={setTab}>\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n <TabsTrigger value=\"sessions\">Sessions</TabsTrigger>\n <TabsTrigger value=\"speakers\">Speakers</TabsTrigger>\n <TabsTrigger value=\"tickets\">Tickets</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"mt-4\">\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <TicketIcon className=\"h-4 w-4 text-action-primary-bg\" />\n Type\n </div>\n <p className=\"text-sm uppercase text-text-secondary\">{event.type}</p>\n </GlassCard>\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <Users className=\"h-4 w-4 text-action-primary-bg\" />\n Capacity\n </div>\n <p className=\"text-sm tabular-nums text-text-secondary\">{event.capacity ?? 0} attendees</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <div className=\"mb-2 flex items-center gap-2 text-sm font-medium text-text-primary\">\n <MapPin className=\"h-4 w-4 text-action-primary-bg\" />\n Timezone\n </div>\n <p className=\"text-sm text-text-secondary\">{event.timezone}</p>\n </GlassCard>\n </div>\n\n <GlassCard treatment=\"plain\" className=\"mt-4 border-border-seam p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">About</h2>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {event.description?.trim() ? event.description : 'No description provided.'}\n </p>\n <dl className=\"mt-4 grid grid-cols-1 gap-3 text-sm sm:grid-cols-2\">\n <div>\n <dt className=\"text-text-muted\">Visibility</dt>\n <dd className=\"capitalize text-text-primary\">{event.visibility}</dd>\n </div>\n <div>\n <dt className=\"text-text-muted\">Venue</dt>\n <dd className=\"text-text-primary\">\n {venueId ? (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n className=\"h-auto p-0\"\n onClick={() => navigate(`/venues/${venueId}`)}\n >\n View venue\n </Button>\n ) : (\n 'No venue assigned'\n )}\n </dd>\n </div>\n </dl>\n <div className=\"mt-4\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit event details\n </Button>\n </div>\n </GlassCard>\n </TabsContent>\n\n <TabsContent value=\"sessions\" className=\"mt-4\">\n <SessionsTab eventId={id} />\n </TabsContent>\n\n <TabsContent value=\"speakers\" className=\"mt-4\">\n <SpeakersTab />\n </TabsContent>\n\n <TabsContent value=\"tickets\" className=\"mt-4\">\n <TicketsTab eventId={id} />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,22 +1,22 @@
1
1
  import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
2
2
  import { notify as t } from "../../lib/toast.js";
3
- import { useAttendeesQuery as n, useDeletePromoCodeMutation as r, usePromoCodesQuery as i, useRegistrationsQuery as a, useUpdateRegistrationMutation as o } from "../../api/eventApi.js";
4
- import { ActionMenu as s } from "../../components/ActionMenu.js";
5
- import { Pagination as c, usePagination as l } from "../../components/Pagination.js";
6
- import { mutationSucceeded as u } from "../../lib/mutationResult.js";
7
- import { useMemo as d } from "react";
8
- import { jsx as f, jsxs as p } from "react/jsx-runtime";
9
- import { Megaphone as m, Tag as h, TicketPlus as g, UserPlus as _, Users as v } from "lucide-react";
10
- import { Badge as y, Button as b, EmphasisPanel as x, GlassCard as S, GradientText as C, IllustratedEmptyState as w, NextSteps as T, PagePurpose as E } from "@burdenoff/fe-libs/ui";
3
+ import { useAttendeesQuery as n, useDeleteAttendeeMutation as r, useDeletePromoCodeMutation as i, useDeleteRegistrationMutation as a, usePromoCodesQuery as o, useRegistrationsQuery as s, useUpdateRegistrationMutation as c } from "../../api/eventApi.js";
4
+ import { ActionMenu as l } from "../../components/ActionMenu.js";
5
+ import { Pagination as u, usePagination as d } from "../../components/Pagination.js";
6
+ import { mutationSucceeded as f } from "../../lib/mutationResult.js";
7
+ import { useMemo as p } from "react";
8
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
9
+ import { Megaphone as g, Tag as _, TicketPlus as v, UserPlus as y, Users as b } from "lucide-react";
10
+ import { Badge as x, Button as S, EmphasisPanel as C, GlassCard as w, GradientText as T, IllustratedEmptyState as E, NextSteps as D, PagePurpose as O } from "@burdenoff/fe-libs/ui";
11
11
  //#region src/eventfullymanaged/pages/modules/RegistrationPage.tsx
12
- var D = [
12
+ var k = [
13
13
  "PENDING",
14
14
  "CONFIRMED",
15
15
  "WAITLISTED",
16
16
  "CANCELLED",
17
17
  "CHECKED_IN"
18
18
  ];
19
- function O(e) {
19
+ function A(e) {
20
20
  switch ((e ?? "").toUpperCase()) {
21
21
  case "CONFIRMED":
22
22
  case "CHECKED_IN": return "default";
@@ -25,19 +25,19 @@ function O(e) {
25
25
  default: return "secondary";
26
26
  }
27
27
  }
28
- function k() {
29
- let e = l({ pageSize: 10 }), { data: r, loading: i } = a({
28
+ function j() {
29
+ let e = d({ pageSize: 10 }), { data: r, loading: i } = s({
30
30
  limit: e.limit,
31
31
  offset: e.offset
32
- }), [m] = o(), { data: h } = n({
32
+ }), [o] = c(), [g] = a(), { data: _ } = n({
33
33
  limit: 200,
34
34
  offset: 0
35
- }), g = d(() => {
35
+ }), v = p(() => {
36
36
  let e = /* @__PURE__ */ new Map();
37
- for (let t of h?.attendees.items ?? []) t.id && t.fullName && e.set(t.id, t.fullName);
37
+ for (let t of _?.attendees.items ?? []) t.id && t.fullName && e.set(t.id, t.fullName);
38
38
  return e;
39
- }, [h]), _ = (e) => e ? g.get(e) ?? `Attendee ${e.slice(0, 8)}…` : null, v = d(() => r?.registrations.items ?? [], [r]), b = r?.registrations.total ?? 0, x = async (e, n) => {
40
- let r = await m({ variables: {
39
+ }, [_]), y = (e) => e ? v.get(e) ?? `Attendee ${e.slice(0, 8)}…` : null, b = p(() => r?.registrations.items ?? [], [r]), S = r?.registrations.total ?? 0, C = async (e, n) => {
40
+ let r = await o({ variables: {
41
41
  id: e.id,
42
42
  input: {
43
43
  eventId: e.eventId,
@@ -49,59 +49,67 @@ function k() {
49
49
  status: n
50
50
  }
51
51
  } });
52
- u(r, r.data?.updateRegistration?.id, "Could not update registration") && t.success("Registration updated", `Status set to ${n}`);
52
+ f(r, r.data?.updateRegistration?.id, "Could not update registration") && t.success("Registration updated", `Status set to ${n}`);
53
+ }, T = async (e, n) => {
54
+ let r = await g({ variables: { id: e.id } });
55
+ if (r.error) throw t.error("Could not delete registration", r.error.message), r.error;
56
+ if (!r.data?.deleteRegistration) throw t.error("Could not delete registration", "The server did not confirm the change."), Error("delete-unconfirmed");
57
+ t.success("Registration deleted", n);
53
58
  };
54
- return /* @__PURE__ */ p(S, {
59
+ return /* @__PURE__ */ h(w, {
55
60
  treatment: "plain",
56
61
  className: "border-border-seam p-5",
57
62
  children: [
58
- /* @__PURE__ */ f("h2", {
63
+ /* @__PURE__ */ m("h2", {
59
64
  className: "text-lg font-semibold text-text-primary",
60
- children: i ? "Loading registrations…" : `Registrations (${b})`
65
+ children: i ? "Loading registrations…" : `Registrations (${S})`
61
66
  }),
62
- v.length === 0 && !i ? /* @__PURE__ */ f(w, {
67
+ b.length === 0 && !i ? /* @__PURE__ */ m(E, {
63
68
  illustration: "empty-data",
64
69
  title: "No registrations yet.",
65
70
  description: "Register your first attendee to start tracking sign-ups.",
66
71
  className: "mt-4"
67
- }) : /* @__PURE__ */ f("ul", {
72
+ }) : /* @__PURE__ */ m("ul", {
68
73
  className: "mt-4 space-y-2",
69
- children: v.map((e) => {
70
- let t = D.filter((t) => t !== (e.status ?? "").toUpperCase()).map((t, n) => ({
74
+ children: b.map((e) => {
75
+ let t = y(e.attendeeId) ?? `Registration ${e.id}`, n = k.filter((t) => t !== (e.status ?? "").toUpperCase()).map((t, n) => ({
71
76
  key: t,
72
77
  label: `Set ${t.replace("_", " ").toLowerCase()}`,
73
- onSelect: () => void x(e, t),
78
+ onSelect: () => void C(e, t),
74
79
  separatorBefore: n === 0
75
80
  }));
76
- return /* @__PURE__ */ p("li", {
81
+ return /* @__PURE__ */ h("li", {
77
82
  className: "flex items-center justify-between gap-3 rounded-input border border-border-seam bg-bg-surface px-3 py-2",
78
- children: [/* @__PURE__ */ p("div", {
83
+ children: [/* @__PURE__ */ h("div", {
79
84
  className: "min-w-0",
80
- children: [/* @__PURE__ */ f("p", {
85
+ children: [/* @__PURE__ */ m("p", {
81
86
  className: "truncate text-sm font-medium text-text-primary",
82
- children: _(e.attendeeId) ?? `Registration ${e.id}`
83
- }), /* @__PURE__ */ f("p", {
87
+ children: t
88
+ }), /* @__PURE__ */ m("p", {
84
89
  className: "truncate text-xs text-text-secondary",
85
90
  children: [`Qty ${e.quantity}`, e.totalAmount ? `${e.totalAmount} ${e.currency}` : void 0].filter(Boolean).join(" • ")
86
91
  })]
87
- }), /* @__PURE__ */ p("div", {
92
+ }), /* @__PURE__ */ h("div", {
88
93
  className: "flex shrink-0 items-center gap-2",
89
- children: [/* @__PURE__ */ f(y, {
90
- variant: O(e.status),
94
+ children: [/* @__PURE__ */ m(x, {
95
+ variant: A(e.status),
91
96
  children: e.status ?? "UNKNOWN"
92
- }), /* @__PURE__ */ f(s, {
97
+ }), /* @__PURE__ */ m(l, {
93
98
  ariaLabel: "Registration actions",
94
- extraItems: t
99
+ entityName: t,
100
+ deleteLabel: "Delete registration",
101
+ extraItems: n,
102
+ onDelete: () => T(e, t)
95
103
  })]
96
104
  })]
97
105
  }, e.id);
98
106
  })
99
107
  }),
100
- /* @__PURE__ */ f(c, {
108
+ /* @__PURE__ */ m(u, {
101
109
  offset: e.offset,
102
110
  limit: e.limit,
103
- loadedCount: v.length,
104
- total: b,
111
+ loadedCount: b.length,
112
+ total: S,
105
113
  onPrev: e.prevPage,
106
114
  onNext: e.nextPage,
107
115
  itemLabel: "registrations",
@@ -110,43 +118,48 @@ function k() {
110
118
  ]
111
119
  });
112
120
  }
113
- function A() {
114
- let { navigate: t } = e(), r = l({ pageSize: 10 }), { data: i, loading: a } = n({
115
- limit: r.limit,
116
- offset: r.offset
117
- }), o = d(() => i?.attendees.items ?? [], [i]), u = i?.attendees.total ?? 0;
118
- return /* @__PURE__ */ p(S, {
121
+ function M() {
122
+ let { navigate: i } = e(), a = d({ pageSize: 10 }), { data: o, loading: s } = n({
123
+ limit: a.limit,
124
+ offset: a.offset
125
+ }), [c] = r(), f = p(() => o?.attendees.items ?? [], [o]), g = o?.attendees.total ?? 0, _ = async (e) => {
126
+ let n = await c({ variables: { id: e.id } });
127
+ if (n.error) throw t.error("Could not delete attendee", n.error.message), n.error;
128
+ if (!n.data?.deleteAttendee) throw t.error("Could not delete attendee", "The server did not confirm the change."), Error("delete-unconfirmed");
129
+ t.success("Attendee deleted", e.fullName);
130
+ };
131
+ return /* @__PURE__ */ h(w, {
119
132
  treatment: "plain",
120
133
  className: "border-border-seam p-5",
121
134
  children: [
122
- /* @__PURE__ */ p("div", {
135
+ /* @__PURE__ */ h("div", {
123
136
  className: "flex items-center justify-between gap-3",
124
- children: [/* @__PURE__ */ f("h2", {
137
+ children: [/* @__PURE__ */ m("h2", {
125
138
  className: "text-lg font-semibold text-text-primary",
126
- children: a ? "Loading attendees…" : `Attendees (${u})`
127
- }), /* @__PURE__ */ p(b, {
139
+ children: s ? "Loading attendees…" : `Attendees (${g})`
140
+ }), /* @__PURE__ */ h(S, {
128
141
  type: "button",
129
142
  size: "sm",
130
143
  variant: "outline",
131
- onClick: () => t("/registration/attendees/create"),
132
- children: [/* @__PURE__ */ f(_, { className: "h-4 w-4" }), "Add attendee"]
144
+ onClick: () => i("/registration/attendees/create"),
145
+ children: [/* @__PURE__ */ m(y, { className: "h-4 w-4" }), "Add attendee"]
133
146
  })]
134
147
  }),
135
- o.length === 0 && !a ? /* @__PURE__ */ f(w, {
148
+ f.length === 0 && !s ? /* @__PURE__ */ m(E, {
136
149
  illustration: "empty-people",
137
150
  title: "No attendees yet.",
138
151
  description: "Add attendees or register one to build your guest list.",
139
152
  className: "mt-4"
140
- }) : /* @__PURE__ */ f("ul", {
153
+ }) : /* @__PURE__ */ m("ul", {
141
154
  className: "mt-4 space-y-2",
142
- children: o.map((e) => /* @__PURE__ */ p("li", {
155
+ children: f.map((e) => /* @__PURE__ */ h("li", {
143
156
  className: "flex items-center justify-between gap-3 rounded-input border border-border-seam bg-bg-surface px-3 py-2",
144
- children: [/* @__PURE__ */ p("div", {
157
+ children: [/* @__PURE__ */ h("div", {
145
158
  className: "min-w-0",
146
- children: [/* @__PURE__ */ f("p", {
159
+ children: [/* @__PURE__ */ m("p", {
147
160
  className: "truncate text-sm font-medium text-text-primary",
148
161
  children: e.fullName
149
- }), /* @__PURE__ */ f("p", {
162
+ }), /* @__PURE__ */ m("p", {
150
163
  className: "truncate text-xs text-text-secondary",
151
164
  children: [
152
165
  e.email,
@@ -154,138 +167,141 @@ function A() {
154
167
  e.role
155
168
  ].filter(Boolean).join(" • ")
156
169
  })]
157
- }), /* @__PURE__ */ f(s, {
170
+ }), /* @__PURE__ */ m(l, {
158
171
  ariaLabel: `Actions for ${e.fullName}`,
159
- onView: () => t(`/attendees/${e.id}/profile`),
160
- onEdit: () => t(`/registration/attendees/${e.id}/edit`)
172
+ entityName: e.fullName,
173
+ deleteLabel: "Delete attendee",
174
+ onView: () => i(`/attendees/${e.id}/profile`),
175
+ onEdit: () => i(`/registration/attendees/${e.id}/edit`),
176
+ onDelete: () => _(e)
161
177
  })]
162
178
  }, e.id))
163
179
  }),
164
- /* @__PURE__ */ f(c, {
165
- offset: r.offset,
166
- limit: r.limit,
167
- loadedCount: o.length,
168
- total: u,
169
- onPrev: r.prevPage,
170
- onNext: r.nextPage,
180
+ /* @__PURE__ */ m(u, {
181
+ offset: a.offset,
182
+ limit: a.limit,
183
+ loadedCount: f.length,
184
+ total: g,
185
+ onPrev: a.prevPage,
186
+ onNext: a.nextPage,
171
187
  itemLabel: "attendees",
172
- loading: a
188
+ loading: s
173
189
  })
174
190
  ]
175
191
  });
176
192
  }
177
- function j() {
178
- let { navigate: n } = e(), a = l({ pageSize: 10 }), { data: o, loading: u } = i({
179
- limit: a.limit,
180
- offset: a.offset
181
- }), [m] = r(), h = d(() => o?.promoCodes.items ?? [], [o]), _ = o?.promoCodes.total ?? 0, v = async (e) => {
182
- let n = await m({ variables: { id: e.id } });
193
+ function N() {
194
+ let { navigate: n } = e(), r = d({ pageSize: 10 }), { data: a, loading: s } = o({
195
+ limit: r.limit,
196
+ offset: r.offset
197
+ }), [c] = i(), f = p(() => a?.promoCodes.items ?? [], [a]), g = a?.promoCodes.total ?? 0, _ = async (e) => {
198
+ let n = await c({ variables: { id: e.id } });
183
199
  if (n.error) throw t.error("Could not delete promo code", n.error.message), n.error;
184
200
  t.success("Promo code deleted", e.code);
185
201
  };
186
- return /* @__PURE__ */ p(S, {
202
+ return /* @__PURE__ */ h(w, {
187
203
  treatment: "plain",
188
204
  className: "border-border-seam p-5",
189
205
  children: [
190
- /* @__PURE__ */ p("div", {
206
+ /* @__PURE__ */ h("div", {
191
207
  className: "flex items-center justify-between gap-3",
192
- children: [/* @__PURE__ */ f("h2", {
208
+ children: [/* @__PURE__ */ m("h2", {
193
209
  className: "text-lg font-semibold text-text-primary",
194
- children: u ? "Loading promo codes…" : `Promo Codes (${_})`
195
- }), /* @__PURE__ */ p(b, {
210
+ children: s ? "Loading promo codes…" : `Promo Codes (${g})`
211
+ }), /* @__PURE__ */ h(S, {
196
212
  type: "button",
197
213
  size: "sm",
198
214
  variant: "outline",
199
215
  onClick: () => n("/registration/promo-codes/create"),
200
- children: [/* @__PURE__ */ f(g, { className: "h-4 w-4" }), "New promo code"]
216
+ children: [/* @__PURE__ */ m(v, { className: "h-4 w-4" }), "New promo code"]
201
217
  })]
202
218
  }),
203
- h.length === 0 && !u ? /* @__PURE__ */ f(w, {
219
+ f.length === 0 && !s ? /* @__PURE__ */ m(E, {
204
220
  illustration: "empty-data",
205
221
  title: "No promo codes yet.",
206
222
  description: "Create a code to offer discounts and drive registrations.",
207
223
  className: "mt-4"
208
- }) : /* @__PURE__ */ f("ul", {
224
+ }) : /* @__PURE__ */ m("ul", {
209
225
  className: "mt-4 space-y-2",
210
- children: h.map((e) => /* @__PURE__ */ p("li", {
226
+ children: f.map((e) => /* @__PURE__ */ h("li", {
211
227
  className: "flex items-center justify-between gap-3 rounded-input border border-border-seam bg-bg-surface px-3 py-2",
212
- children: [/* @__PURE__ */ p("div", {
228
+ children: [/* @__PURE__ */ h("div", {
213
229
  className: "min-w-0",
214
- children: [/* @__PURE__ */ f("p", {
230
+ children: [/* @__PURE__ */ m("p", {
215
231
  className: "truncate text-sm font-medium text-text-primary",
216
232
  children: e.code
217
- }), /* @__PURE__ */ p("p", {
233
+ }), /* @__PURE__ */ h("p", {
218
234
  className: "truncate text-xs text-text-secondary",
219
235
  children: [e.discountType === "PERCENT" ? `${e.discountValue}% off` : `${e.discountValue} off`, e.maxUses == null ? ` • ${e.usedCount} used` : ` • ${e.usedCount}/${e.maxUses} used`]
220
236
  })]
221
- }), /* @__PURE__ */ p("div", {
237
+ }), /* @__PURE__ */ h("div", {
222
238
  className: "flex shrink-0 items-center gap-2",
223
- children: [/* @__PURE__ */ f(y, {
239
+ children: [/* @__PURE__ */ m(x, {
224
240
  variant: e.isActive ? "default" : "secondary",
225
241
  children: e.isActive ? "Active" : "Inactive"
226
- }), /* @__PURE__ */ f(s, {
242
+ }), /* @__PURE__ */ m(l, {
227
243
  ariaLabel: `Actions for ${e.code}`,
228
244
  onEdit: () => n(`/registration/promo-codes/${e.id}/edit`),
229
- onDelete: () => v(e),
245
+ onDelete: () => _(e),
230
246
  entityName: e.code
231
247
  })]
232
248
  })]
233
249
  }, e.id))
234
250
  }),
235
- /* @__PURE__ */ f(c, {
236
- offset: a.offset,
237
- limit: a.limit,
238
- loadedCount: h.length,
239
- total: _,
240
- onPrev: a.prevPage,
241
- onNext: a.nextPage,
251
+ /* @__PURE__ */ m(u, {
252
+ offset: r.offset,
253
+ limit: r.limit,
254
+ loadedCount: f.length,
255
+ total: g,
256
+ onPrev: r.prevPage,
257
+ onNext: r.nextPage,
242
258
  itemLabel: "promo codes",
243
- loading: u
259
+ loading: s
244
260
  })
245
261
  ]
246
262
  });
247
263
  }
248
- function M() {
264
+ function P() {
249
265
  let { navigate: t } = e();
250
- return /* @__PURE__ */ p("div", {
266
+ return /* @__PURE__ */ h("div", {
251
267
  className: "space-y-6 p-6",
252
268
  children: [
253
- /* @__PURE__ */ f(E, { children: "This is where you see who is coming. Registrations are the paid or confirmed sign-ups, attendees are the people behind them, and promo codes let you offer discounts. Register attendees, edit their details, change a registration's status, and manage discount codes — all backed by live GraphQL APIs." }),
254
- /* @__PURE__ */ f(x, { children: /* @__PURE__ */ p("div", {
269
+ /* @__PURE__ */ m(O, { children: "This is where you see who is coming. Registrations are the paid or confirmed sign-ups, attendees are the people behind them, and promo codes let you offer discounts. Register attendees, edit their details, change a registration's status, and manage discount codes — all backed by live GraphQL APIs." }),
270
+ /* @__PURE__ */ m(C, { children: /* @__PURE__ */ h("div", {
255
271
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
256
- children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h1", {
272
+ children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
257
273
  className: "text-2xl font-bold text-text-primary",
258
- children: /* @__PURE__ */ f(C, { children: "Registration" })
259
- }), /* @__PURE__ */ f("p", {
274
+ children: /* @__PURE__ */ m(T, { children: "Registration" })
275
+ }), /* @__PURE__ */ m("p", {
260
276
  className: "mt-1 text-sm text-text-secondary",
261
277
  children: "Track registrations, attendees, and promo codes with backend persistence."
262
- })] }), /* @__PURE__ */ p("div", {
278
+ })] }), /* @__PURE__ */ h("div", {
263
279
  className: "flex flex-wrap gap-2",
264
280
  children: [
265
- /* @__PURE__ */ p(b, {
281
+ /* @__PURE__ */ h(S, {
266
282
  type: "button",
267
283
  onClick: () => t("/registration/register"),
268
- children: [/* @__PURE__ */ f(g, { className: "h-4 w-4" }), "Register attendee"]
284
+ children: [/* @__PURE__ */ m(v, { className: "h-4 w-4" }), "Register attendee"]
269
285
  }),
270
- /* @__PURE__ */ p(b, {
286
+ /* @__PURE__ */ h(S, {
271
287
  type: "button",
272
288
  variant: "outline",
273
289
  onClick: () => t("/registration/attendees/create"),
274
- children: [/* @__PURE__ */ f(_, { className: "h-4 w-4" }), "Add attendee"]
290
+ children: [/* @__PURE__ */ m(y, { className: "h-4 w-4" }), "Add attendee"]
275
291
  }),
276
- /* @__PURE__ */ p(b, {
292
+ /* @__PURE__ */ h(S, {
277
293
  type: "button",
278
294
  variant: "outline",
279
295
  onClick: () => t("/registration/promo-codes/create"),
280
- children: [/* @__PURE__ */ f(h, { className: "h-4 w-4" }), "New promo code"]
296
+ children: [/* @__PURE__ */ m(_, { className: "h-4 w-4" }), "New promo code"]
281
297
  })
282
298
  ]
283
299
  })]
284
300
  }) }),
285
- /* @__PURE__ */ f(k, {}),
286
- /* @__PURE__ */ f(A, {}),
287
- /* @__PURE__ */ f(j, {}),
288
- /* @__PURE__ */ f(T, {
301
+ /* @__PURE__ */ m(j, {}),
302
+ /* @__PURE__ */ m(M, {}),
303
+ /* @__PURE__ */ m(N, {}),
304
+ /* @__PURE__ */ m(D, {
289
305
  storageKey: "eventfullymanaged-registration",
290
306
  title: "Grow your registrations",
291
307
  steps: [
@@ -293,21 +309,21 @@ function M() {
293
309
  id: "view-networking",
294
310
  label: "Set up attendee networking",
295
311
  description: "Turn registered attendees into connections with matchmaking.",
296
- icon: /* @__PURE__ */ f(v, { className: "h-4 w-4" }),
312
+ icon: /* @__PURE__ */ m(b, { className: "h-4 w-4" }),
297
313
  onClick: () => t("/networking")
298
314
  },
299
315
  {
300
316
  id: "promote",
301
317
  label: "Promote with a campaign",
302
318
  description: "Send reminders and offers to drive more sign-ups.",
303
- icon: /* @__PURE__ */ f(m, { className: "h-4 w-4" }),
319
+ icon: /* @__PURE__ */ m(g, { className: "h-4 w-4" }),
304
320
  onClick: () => t("/communication")
305
321
  },
306
322
  {
307
323
  id: "analyze",
308
324
  label: "Snapshot your numbers",
309
325
  description: "Capture an analytics snapshot to track registration trends.",
310
- icon: /* @__PURE__ */ f(h, { className: "h-4 w-4" }),
326
+ icon: /* @__PURE__ */ m(_, { className: "h-4 w-4" }),
311
327
  onClick: () => t("/analytics")
312
328
  }
313
329
  ]
@@ -316,6 +332,6 @@ function M() {
316
332
  });
317
333
  }
318
334
  //#endregion
319
- export { M as default };
335
+ export { P as default };
320
336
 
321
337
  //# sourceMappingURL=RegistrationPage.js.map