@burdenoff/microfe-eventfullymanaged 2026.703.2 → 2026.704.1

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.
Files changed (74) hide show
  1. package/dist/eventfullymanaged/EventfullyManagedRoutes.js +154 -66
  2. package/dist/eventfullymanaged/EventfullyManagedRoutes.js.map +1 -1
  3. package/dist/eventfullymanaged/api/eventApi.js +546 -67
  4. package/dist/eventfullymanaged/api/eventApi.js.map +1 -1
  5. package/dist/eventfullymanaged/components/ActionMenu.js +113 -0
  6. package/dist/eventfullymanaged/components/ActionMenu.js.map +1 -0
  7. package/dist/eventfullymanaged/components/EntityFormShell.js +51 -0
  8. package/dist/eventfullymanaged/components/EntityFormShell.js.map +1 -0
  9. package/dist/eventfullymanaged/components/EntityTagsField.js +146 -0
  10. package/dist/eventfullymanaged/components/EntityTagsField.js.map +1 -0
  11. package/dist/eventfullymanaged/components/Pagination.js +84 -0
  12. package/dist/eventfullymanaged/components/Pagination.js.map +1 -0
  13. package/dist/eventfullymanaged/components/SafeLink.js +32 -0
  14. package/dist/eventfullymanaged/components/SafeLink.js.map +1 -0
  15. package/dist/eventfullymanaged/components/index.js +7 -0
  16. package/dist/eventfullymanaged/pages/events/EventDetailPage.js +458 -0
  17. package/dist/eventfullymanaged/pages/events/EventDetailPage.js.map +1 -0
  18. package/dist/eventfullymanaged/pages/events/EventFormPage.js +267 -0
  19. package/dist/eventfullymanaged/pages/events/EventFormPage.js.map +1 -0
  20. package/dist/eventfullymanaged/pages/events/SessionFormPage.js +308 -0
  21. package/dist/eventfullymanaged/pages/events/SessionFormPage.js.map +1 -0
  22. package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js +214 -0
  23. package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js.map +1 -0
  24. package/dist/eventfullymanaged/pages/events/eventFormUtils.js +128 -0
  25. package/dist/eventfullymanaged/pages/events/eventFormUtils.js.map +1 -0
  26. package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js +233 -0
  27. package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js.map +1 -0
  28. package/dist/eventfullymanaged/pages/exhibitors/ExhibitorsPage.js +165 -0
  29. package/dist/eventfullymanaged/pages/exhibitors/ExhibitorsPage.js.map +1 -0
  30. package/dist/eventfullymanaged/pages/leads/LeadCaptureDialog.js +141 -0
  31. package/dist/eventfullymanaged/pages/leads/LeadCaptureDialog.js.map +1 -0
  32. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js +178 -45
  33. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
  34. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js +240 -70
  35. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js.map +1 -1
  36. package/dist/eventfullymanaged/pages/modules/EventsPage.js +133 -97
  37. package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
  38. package/dist/eventfullymanaged/pages/modules/KioskPage.js +746 -36
  39. package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
  40. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +210 -69
  41. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
  42. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +289 -77
  43. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
  44. package/dist/eventfullymanaged/pages/modules/RoadmapPanel.js +95 -0
  45. package/dist/eventfullymanaged/pages/modules/RoadmapPanel.js.map +1 -0
  46. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +77 -56
  47. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
  48. package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js +70 -36
  49. package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js.map +1 -1
  50. package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js +343 -0
  51. package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js.map +1 -0
  52. package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js +236 -0
  53. package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js.map +1 -0
  54. package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js +181 -0
  55. package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js.map +1 -0
  56. package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js +262 -0
  57. package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js.map +1 -0
  58. package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js +414 -0
  59. package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js.map +1 -0
  60. package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js +224 -0
  61. package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js.map +1 -0
  62. package/dist/eventfullymanaged/pages/speakers/SpeakersPage.js +96 -0
  63. package/dist/eventfullymanaged/pages/speakers/SpeakersPage.js.map +1 -0
  64. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +149 -140
  65. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
  66. package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js +97 -67
  67. package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js.map +1 -1
  68. package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js +93 -72
  69. package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
  70. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +91 -89
  71. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
  72. package/dist/eventfullymanaged/pages/venues/VenueListPage.js +83 -53
  73. package/dist/eventfullymanaged/pages/venues/VenueListPage.js.map +1 -1
  74. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"KioskPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/KioskPage.tsx"],"sourcesContent":["import { EmphasisPanel, GradientText, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo } from 'react';\n\nimport { useCheckInRecordsQuery, useCheckInStationsQuery } from '../../api/eventApi';\nimport { EntityListSection } from './EntityListSection';\n\ntype StationRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function KioskPage() {\n const stationsQuery = useCheckInStationsQuery({ limit: 100, offset: 0 });\n const recordsQuery = useCheckInRecordsQuery({ limit: 100, offset: 0 });\n const stations = useMemo(\n () => (stationsQuery.data?.checkInStations.items ?? []) as StationRow[],\n [stationsQuery.data]\n );\n const records = useMemo(() => recordsQuery.data?.checkInRecords.items ?? [], [recordsQuery.data]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Kiosks are the front desk of your event. Each check-in station is a device or counter where attendees scan in,\n and check-in records are the live log of who arrived and when. Use this page to confirm your stations are online\n before doors open and to watch arrivals flow in on the day.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Kiosk</GradientText> &amp; Check-In\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">View configured check-in stations and station status.</p>\n </EmphasisPanel>\n\n <EntityListSection\n heading={stationsQuery.loading ? 'Loading check-in stations...' : `Stations (${stations.length})`}\n emptyLabel=\"No check-in stations configured yet.\"\n rows={stations.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Station ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={recordsQuery.loading ? 'Loading check-in records...' : `Check-In Records (${records.length})`}\n emptyLabel=\"No check-in records found.\"\n rows={records.map((row) => ({\n id: row.id,\n title: row.attendeeId ? `Attendee ${row.attendeeId}` : `Record ${row.id}`,\n subtitle: `${row.method} • ${row.direction}`,\n status: row.status,\n }))}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;AAaA,SAAwB,IAAY;CAClC,IAAM,IAAgB,EAAwB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAClE,IAAe,EAAuB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAChE,IAAW,QACR,EAAc,MAAM,gBAAgB,SAAS,EAAE,EACtD,CAAC,EAAc,KAAK,CACrB,EACK,IAAU,QAAc,EAAa,MAAM,eAAe,SAAS,EAAE,EAAE,CAAC,EAAa,KAAK,CAAC;AAEjG,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UAAa,+RAIC,CAAA;GAEd,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,MAAD;IAAI,WAAU;cAAd,CACE,kBAAC,GAAD,EAAA,UAAc,SAAoB,CAAA,EAAA,cAC/B;OACL,kBAAC,KAAD;IAAG,WAAU;cAAmC;IAAyD,CAAA,CAC3F,EAAA,CAAA;GAEhB,kBAAC,GAAD;IACE,SAAS,EAAc,UAAU,iCAAiC,aAAa,EAAS,OAAO;IAC/F,YAAW;IACX,MAAM,EAAS,KAAK,OAAS;KAC3B,IAAI,EAAI;KACR,OAAO,EAAI,QAAQ,EAAI,SAAS,WAAW,EAAI;KAC/C,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,SAAS,EAAa,UAAU,gCAAgC,qBAAqB,EAAQ,OAAO;IACpG,YAAW;IACX,MAAM,EAAQ,KAAK,OAAS;KAC1B,IAAI,EAAI;KACR,OAAO,EAAI,aAAa,YAAY,EAAI,eAAe,UAAU,EAAI;KACrE,UAAU,GAAG,EAAI,OAAO,KAAK,EAAI;KACjC,QAAQ,EAAI;KACb,EAAE;IACH,CAAA;GACE"}
1
+ {"version":3,"file":"KioskPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/KioskPage.tsx"],"sourcesContent":["import {\n Badge,\n Button,\n EmphasisPanel,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n Input,\n Label,\n PagePurpose,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n} from '@burdenoff/fe-libs/ui';\nimport { LogIn, MonitorSmartphone, Plus, ScanLine } from 'lucide-react';\nimport { useMemo, useState } from 'react';\n\nimport {\n useAttendeesQuery,\n useCheckInRecordsQuery,\n useCheckInStationsQuery,\n useCreateCheckInRecordMutation,\n useCreateCheckInStationMutation,\n useDeleteCheckInRecordMutation,\n useDeleteCheckInStationMutation,\n useEventSessionsQuery,\n useEventsQuery,\n useUpdateCheckInRecordMutation,\n useUpdateCheckInStationMutation,\n} from '../../api/eventApi';\nimport { ActionMenu, Pagination, usePagination } from '../../components';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\n// ---------------------------------------------------------------------------\n// Shared types\n// ---------------------------------------------------------------------------\n\ntype StationRow = {\n id: string;\n eventId?: string | null;\n name?: string | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype RecordRow = {\n id: string;\n eventId: string;\n stationId?: string | null;\n attendeeId?: string | null;\n registrationId?: string | null;\n method: string;\n status: string;\n direction: string;\n recordedAt: string;\n metadata?: Record<string, unknown> | null;\n};\n\nconst STATION_TYPES = ['DESK', 'GATE', 'SELF_SERVICE', 'MOBILE'] as const;\nconst CHECKIN_METHODS = ['QR', 'MANUAL'] as const;\nconst CHECKIN_DIRECTIONS = ['IN', 'OUT'] as const;\n\n/**\n * The stations list resolver projects a CheckInStation onto the generic\n * SimpleEntity shape (id/name/metadata) — it does NOT expose the `code`,\n * `location` or `isActive` columns. To keep create → list → edit lossless we\n * mirror those attributes into `metadata` on every write, so an edit opened from\n * a list row can rebuild the full required input without a by-id resolver.\n */\ntype StationMeta = {\n code?: string;\n location?: string;\n type?: string;\n isActive?: boolean;\n};\n\nfunction readStationMeta(metadata: Record<string, unknown> | null | undefined): StationMeta {\n if (!metadata || typeof metadata !== 'object') {\n return {};\n }\n const m = metadata as Record<string, unknown>;\n return {\n code: typeof m.code === 'string' ? m.code : undefined,\n location: typeof m.location === 'string' ? m.location : undefined,\n type: typeof m.type === 'string' ? m.type : undefined,\n isActive: typeof m.isActive === 'boolean' ? m.isActive : undefined,\n };\n}\n\nfunction slugCode(name: string): string {\n return (\n name\n .trim()\n .toUpperCase()\n .replace(/[^A-Z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 24) || 'STATION'\n );\n}\n\n// ===========================================================================\n// Station create / edit dialog\n// ===========================================================================\n\ntype StationFormState = {\n name: string;\n code: string;\n location: string;\n type: string;\n isActive: boolean;\n};\n\ninterface StationDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n eventId: string;\n eventName: string;\n /** Present when editing an existing station. */\n station?: StationRow;\n}\n\nfunction StationDialog({ open, onOpenChange, eventId, eventName, station }: StationDialogProps) {\n const isEdit = Boolean(station);\n const [createStation, { loading: creating }] = useCreateCheckInStationMutation();\n const [updateStation, { loading: updating }] = useUpdateCheckInStationMutation();\n\n const initial = useMemo<StationFormState>(() => {\n if (!station) {\n return { name: '', code: '', location: '', type: 'DESK', isActive: true };\n }\n const meta = readStationMeta(station.metadata);\n return {\n name: station.name ?? '',\n code: meta.code ?? slugCode(station.name ?? ''),\n location: meta.location ?? '',\n type: meta.type ?? 'DESK',\n isActive: meta.isActive ?? true,\n };\n }, [station]);\n\n const [form, setForm] = useState<StationFormState>(initial);\n // Reset the form to the active station whenever the dialog is (re)opened.\n const [seededFor, setSeededFor] = useState<string | null>(null);\n const seedKey = `${open ? 'open' : 'closed'}:${station?.id ?? 'new'}`;\n if (open && seededFor !== seedKey) {\n setSeededFor(seedKey);\n setForm(initial);\n }\n if (!open && seededFor !== null) {\n setSeededFor(null);\n }\n\n const onChange = <K extends keyof StationFormState>(field: K, value: StationFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const saving = creating || updating;\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const code = form.code.trim() || slugCode(form.name);\n const input = {\n eventId,\n name: form.name.trim(),\n code,\n location: form.location.trim() || null,\n isActive: form.isActive,\n kioskConfig: { type: form.type },\n // Mirror the write-only columns so the SimpleEntity list can rebuild them.\n metadata: { code, location: form.location.trim(), type: form.type, isActive: form.isActive },\n };\n\n try {\n if (isEdit && station) {\n const res = await updateStation({ variables: { id: station.id, input } });\n if (!mutationSucceeded(res, res.data?.updateCheckInStation?.id, 'Could not update station')) {\n return;\n }\n notify.success('Station updated', `“${input.name}” is now ${form.isActive ? 'active' : 'disabled'}.`);\n } else {\n const res = await createStation({ variables: { input } });\n if (!mutationSucceeded(res, res.data?.createCheckInStation?.id, 'Could not create station')) {\n return;\n }\n notify.success('Station created', `“${input.name}” is ready at ${eventName}.`);\n }\n onOpenChange(false);\n } catch (error) {\n notify.error('Could not save station', describeError(error));\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>{isEdit ? 'Edit check-in station' : 'New check-in station'}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n A station is a desk, gate or device where attendees scan in at {eventName}.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <form id=\"station-form\" onSubmit={onSubmit} className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Name</span>\n <Input\n value={form.name}\n onChange={(e) => onChange('name', e.target.value)}\n placeholder=\"Main entrance\"\n required\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Code</span>\n <Input\n value={form.code}\n onChange={(e) => onChange('code', e.target.value)}\n placeholder=\"Auto from name\"\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Location</span>\n <Input\n value={form.location}\n onChange={(e) => onChange('location', e.target.value)}\n placeholder=\"North lobby\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Type</span>\n <Select value={form.type} onValueChange={(value) => onChange('type', value)}>\n <SelectTrigger aria-label=\"Station type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATION_TYPES.map((type) => (\n <SelectItem key={type} value={type}>\n {type.replace('_', ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <div className=\"flex items-center justify-between rounded-card border border-border-seam bg-bg-surface p-3\">\n <div>\n <Label htmlFor=\"station-active\" className=\"text-text-primary\">\n Active\n </Label>\n <p className=\"text-xs text-text-secondary\">Disabled stations stay configured but cannot accept scans.</p>\n </div>\n <Switch\n id=\"station-active\"\n checked={form.isActive}\n onCheckedChange={(checked) => onChange('isActive', checked)}\n aria-label=\"Station active\"\n />\n </div>\n </form>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)} disabled={saving}>\n Cancel\n </Button>\n <Button type=\"submit\" form=\"station-form\" disabled={saving}>\n {saving ? 'Saving…' : isEdit ? 'Save station' : 'Create station'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ===========================================================================\n// Check-in record edit dialog\n// ===========================================================================\n\ntype RecordFormState = {\n method: string;\n direction: string;\n status: string;\n stationId: string;\n attendeeId: string;\n};\n\ninterface RecordDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n record: RecordRow | null;\n stations: StationRow[];\n}\n\nfunction RecordDialog({ open, onOpenChange, record, stations }: RecordDialogProps) {\n const [updateRecord, { loading }] = useUpdateCheckInRecordMutation();\n\n const initial = useMemo<RecordFormState>(\n () => ({\n method: record?.method ?? 'MANUAL',\n direction: record?.direction ?? 'IN',\n status: record?.status ?? 'checked_in',\n stationId: record?.stationId ?? '',\n attendeeId: record?.attendeeId ?? '',\n }),\n [record]\n );\n const [form, setForm] = useState<RecordFormState>(initial);\n const [seededFor, setSeededFor] = useState<string | null>(null);\n const seedKey = `${open ? 'open' : 'closed'}:${record?.id ?? 'none'}`;\n if (open && seededFor !== seedKey) {\n setSeededFor(seedKey);\n setForm(initial);\n }\n if (!open && seededFor !== null) {\n setSeededFor(null);\n }\n\n const onChange = <K extends keyof RecordFormState>(field: K, value: RecordFormState[K]) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n if (!record) {\n return;\n }\n const input = {\n eventId: record.eventId,\n attendeeId: form.attendeeId.trim() || null,\n registrationId: record.registrationId ?? null,\n stationId: form.stationId || null,\n method: form.method,\n direction: form.direction,\n status: form.status.trim() || 'checked_in',\n metadata: record.metadata ?? {},\n };\n try {\n const res = await updateRecord({ variables: { id: record.id, input } });\n if (!mutationSucceeded(res, res.data?.updateCheckInRecord?.id, 'Could not update record')) {\n return;\n }\n notify.success('Check-in updated');\n onOpenChange(false);\n } catch (error) {\n notify.error('Could not update record', describeError(error));\n }\n };\n\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent className=\"max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Edit check-in record</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>Correct the direction, method or station for this scan.</ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <form id=\"record-form\" onSubmit={onSubmit} className=\"space-y-4\">\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Attendee ID</span>\n <Input value={form.attendeeId} onChange={(e) => onChange('attendeeId', e.target.value)} />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Method</span>\n <Select value={form.method} onValueChange={(value) => onChange('method', value)}>\n <SelectTrigger aria-label=\"Method\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CHECKIN_METHODS.map((method) => (\n <SelectItem key={method} value={method}>\n {method}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Direction</span>\n <Select value={form.direction} onValueChange={(value) => onChange('direction', value)}>\n <SelectTrigger aria-label=\"Direction\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CHECKIN_DIRECTIONS.map((direction) => (\n <SelectItem key={direction} value={direction}>\n {direction}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Status</span>\n <Input value={form.status} onChange={(e) => onChange('status', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Station</span>\n <Select\n value={form.stationId || 'none'}\n onValueChange={(value) => onChange('stationId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Station\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No station</SelectItem>\n {stations.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name ?? s.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n </form>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"submit\" form=\"record-form\" disabled={loading}>\n {loading ? 'Saving…' : 'Save record'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\n// ===========================================================================\n// Check-in action panel (the hero workflow)\n// ===========================================================================\n\ninterface CheckInPanelProps {\n eventId: string;\n stations: StationRow[];\n onCheckedIn: () => void;\n}\n\nfunction CheckInPanel({ eventId, stations, onCheckedIn }: CheckInPanelProps) {\n const [scanValue, setScanValue] = useState('');\n const [method, setMethod] = useState<string>('QR');\n const [direction, setDirection] = useState<string>('IN');\n const [stationId, setStationId] = useState('');\n const [sessionId, setSessionId] = useState('');\n\n const [createRecord, { loading }] = useCreateCheckInRecordMutation();\n const attendeesQuery = useAttendeesQuery({ eventId, limit: 100, offset: 0 });\n const sessionsQuery = useEventSessionsQuery({ eventId, limit: 100, offset: 0 });\n\n const attendees = attendeesQuery.data?.attendees.items ?? [];\n const sessions = sessionsQuery.data?.eventSessions.items ?? [];\n\n const resolveAttendee = (raw: string): { attendeeId: string | null; label: string } => {\n const value = raw.trim();\n if (!value) {\n return { attendeeId: null, label: 'attendee' };\n }\n if (value.includes('@')) {\n const match = attendees.find((a) => a.email?.toLowerCase() === value.toLowerCase());\n return { attendeeId: match?.id ?? null, label: match?.fullName ?? value };\n }\n const byId = attendees.find((a) => a.id === value);\n return { attendeeId: value, label: byId?.fullName ?? `attendee ${value}` };\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const { attendeeId, label } = resolveAttendee(scanValue);\n if (scanValue.trim().includes('@') && !attendeeId) {\n notify.error('Attendee not found', `No attendee at this event matches “${scanValue.trim()}”.`);\n return;\n }\n const input = {\n eventId,\n attendeeId,\n stationId: stationId || null,\n method,\n direction,\n status: 'checked_in',\n recordedAt: new Date().toISOString(),\n metadata: sessionId ? { sessionId } : {},\n };\n try {\n const res = await createRecord({ variables: { input } });\n if (!mutationSucceeded(res, res.data?.createCheckInRecord?.id, 'Could not record check-in')) {\n return;\n }\n notify.success(\n `${label} checked ${direction === 'OUT' ? 'out' : 'in'}`,\n `Recorded via ${method}${stationId ? '' : ' • no station'}.`\n );\n setScanValue('');\n onCheckedIn();\n } catch (error) {\n notify.error('Could not record check-in', describeError(error));\n }\n };\n\n return (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <div className=\"flex items-center gap-2\">\n <ScanLine className=\"h-5 w-5 text-text-secondary\" aria-hidden=\"true\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">Check in an attendee</h2>\n </div>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Scan a QR badge or type an attendee ID or email, then record the arrival.\n </p>\n\n <form onSubmit={onSubmit} className=\"mt-4 space-y-4\">\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Attendee ID / email / QR</span>\n <Input\n value={scanValue}\n onChange={(e) => setScanValue(e.target.value)}\n placeholder=\"Scan badge or paste attendee ID / email\"\n autoComplete=\"off\"\n />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Method</span>\n <Select value={method} onValueChange={setMethod}>\n <SelectTrigger aria-label=\"Check-in method\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CHECKIN_METHODS.map((m) => (\n <SelectItem key={m} value={m}>\n {m}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Direction</span>\n <Select value={direction} onValueChange={setDirection}>\n <SelectTrigger aria-label=\"Direction\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CHECKIN_DIRECTIONS.map((d) => (\n <SelectItem key={d} value={d}>\n {d}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Station</span>\n <Select value={stationId || 'none'} onValueChange={(value) => setStationId(value === 'none' ? '' : value)}>\n <SelectTrigger aria-label=\"Station\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No station</SelectItem>\n {stations.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.name ?? s.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Session</span>\n <Select value={sessionId || 'none'} onValueChange={(value) => setSessionId(value === 'none' ? '' : value)}>\n <SelectTrigger aria-label=\"Session\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">Whole event</SelectItem>\n {sessions.map((s) => (\n <SelectItem key={s.id} value={s.id}>\n {s.title}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <div className=\"flex justify-end\">\n <Button type=\"submit\" disabled={loading || !scanValue.trim()}>\n <LogIn className=\"h-4 w-4\" />\n {loading ? 'Recording…' : 'Record check-in'}\n </Button>\n </div>\n </form>\n </GlassCard>\n );\n}\n\n// ===========================================================================\n// Page\n// ===========================================================================\n\nconst PAGE_SIZE = 10;\n\nexport default function KioskPage() {\n const eventsQuery = useEventsQuery({ limit: 100, offset: 0 });\n const events = eventsQuery.data?.events.items ?? [];\n const [selectedEventId, setSelectedEventId] = useState('');\n const scopeEventId = selectedEventId || undefined;\n const selectedEvent = events.find((e) => e.id === selectedEventId);\n\n const stationsPagination = usePagination({ pageSize: PAGE_SIZE, resetKey: selectedEventId });\n const recordsPagination = usePagination({ pageSize: PAGE_SIZE, resetKey: selectedEventId });\n\n const stationsQuery = useCheckInStationsQuery({\n eventId: scopeEventId,\n limit: stationsPagination.limit,\n offset: stationsPagination.offset,\n });\n const recordsQuery = useCheckInRecordsQuery({\n eventId: scopeEventId,\n limit: recordsPagination.limit,\n offset: recordsPagination.offset,\n });\n\n const stations = (stationsQuery.data?.checkInStations.items ?? []) as StationRow[];\n const stationsTotal = stationsQuery.data?.checkInStations.total ?? 0;\n const records = (recordsQuery.data?.checkInRecords.items ?? []) as RecordRow[];\n const recordsTotal = recordsQuery.data?.checkInRecords.total ?? 0;\n\n const [deleteStation] = useDeleteCheckInStationMutation();\n const [deleteRecord] = useDeleteCheckInRecordMutation();\n\n const [stationDialogOpen, setStationDialogOpen] = useState(false);\n const [editingStation, setEditingStation] = useState<StationRow | undefined>(undefined);\n const [recordDialogOpen, setRecordDialogOpen] = useState(false);\n const [editingRecord, setEditingRecord] = useState<RecordRow | null>(null);\n\n const openNewStation = () => {\n setEditingStation(undefined);\n setStationDialogOpen(true);\n };\n const openEditStation = (station: StationRow) => {\n setEditingStation(station);\n setStationDialogOpen(true);\n };\n const openEditRecord = (record: RecordRow) => {\n setEditingRecord(record);\n setRecordDialogOpen(true);\n };\n\n const onDeleteStation = async (station: StationRow) => {\n const res = await deleteStation({ variables: { id: station.id } });\n if (!mutationSucceeded(res, res.data?.deleteCheckInStation ? station.id : null, 'Could not delete station')) {\n return;\n }\n notify.success('Station deleted', `“${station.name ?? station.id}” was removed.`);\n };\n\n const onDeleteRecord = async (record: RecordRow) => {\n const res = await deleteRecord({ variables: { id: record.id } });\n if (!mutationSucceeded(res, res.data?.deleteCheckInRecord ? record.id : null, 'Could not delete record')) {\n return;\n }\n notify.success('Check-in record deleted');\n };\n\n const hasEvent = Boolean(selectedEventId);\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Kiosks are the front desk of your event. Each check-in station is a device or counter where attendees scan in,\n and check-in records are the live log of who arrived and when. Configure your stations before doors open, then\n check attendees in from this page and watch arrivals flow in on the day.\n </PagePurpose>\n\n <EmphasisPanel>\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Kiosk</GradientText> &amp; Check-In\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Manage check-in stations and record attendee arrivals against a live backend.\n </p>\n </div>\n <div className=\"flex flex-wrap items-end gap-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Event</span>\n <Select value={selectedEventId || 'all'} onValueChange={(v) => setSelectedEventId(v === 'all' ? '' : v)}>\n <SelectTrigger aria-label=\"Event\" className=\"min-w-52\">\n <SelectValue placeholder=\"All events\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"all\">All events</SelectItem>\n {events.map((event) => (\n <SelectItem key={event.id} value={event.id}>\n {event.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n <Button type=\"button\" onClick={openNewStation} disabled={!hasEvent}>\n <Plus className=\"h-4 w-4\" />\n New station\n </Button>\n </div>\n </div>\n </EmphasisPanel>\n\n {hasEvent ? (\n <CheckInPanel\n eventId={selectedEventId}\n stations={stations}\n onCheckedIn={() => {\n recordsPagination.reset();\n void recordsQuery.refetch();\n }}\n />\n ) : (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"Select an event to check attendees in\"\n description=\"Check-in stations and records belong to a specific event. Pick one above to configure stations and record arrivals.\"\n className=\"py-8\"\n />\n </GlassCard>\n )}\n\n {/* Stations */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <div className=\"flex items-center gap-2\">\n <MonitorSmartphone className=\"h-5 w-5 text-text-secondary\" aria-hidden=\"true\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {stationsQuery.loading ? 'Loading stations…' : `Stations (${stationsTotal})`}\n </h2>\n </div>\n <div className=\"mt-4\">\n {stations.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No check-in stations yet\"\n description={hasEvent ? 'Create a station to start scanning attendees in.' : 'No stations configured.'}\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {stations.map((station) => {\n const meta = readStationMeta(station.metadata);\n const active = meta.isActive ?? true;\n const subtitle = [meta.type?.replace('_', ' '), meta.location, meta.code]\n .filter(Boolean)\n .join(' • ');\n return (\n <li\n key={station.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\">{station.name ?? station.id}</p>\n {subtitle ? <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{subtitle}</p> : null}\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant={active ? 'success' : 'warning'} className=\"shrink-0 uppercase\">\n {active ? 'active' : 'disabled'}\n </Badge>\n <ActionMenu\n ariaLabel={`Station ${station.name ?? station.id} actions`}\n entityName={station.name ?? undefined}\n onEdit={() => openEditStation(station)}\n onDelete={() => onDeleteStation(station)}\n />\n </div>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n <Pagination\n offset={stationsPagination.offset}\n limit={stationsPagination.limit}\n loadedCount={stations.length}\n total={stationsTotal}\n onPrev={stationsPagination.prevPage}\n onNext={stationsPagination.nextPage}\n itemLabel=\"stations\"\n loading={stationsQuery.loading}\n />\n </GlassCard>\n\n {/* Records */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {recordsQuery.loading ? 'Loading check-in records…' : `Check-In Records (${recordsTotal})`}\n </h2>\n <div className=\"mt-4\">\n {records.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No check-in records yet\"\n description=\"Arrivals recorded from this page show up here, newest first.\"\n className=\"py-8\"\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {records.map((record) => (\n <li\n key={record.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\">\n {record.attendeeId ? `Attendee ${record.attendeeId}` : `Record ${record.id}`}\n </p>\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">\n {record.method} • {record.direction} • {new Date(record.recordedAt).toLocaleString()}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"secondary\" className=\"shrink-0 uppercase\">\n {record.status}\n </Badge>\n <ActionMenu\n ariaLabel={`Check-in record ${record.id} actions`}\n onEdit={() => openEditRecord(record)}\n onDelete={() => onDeleteRecord(record)}\n />\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <Pagination\n offset={recordsPagination.offset}\n limit={recordsPagination.limit}\n loadedCount={records.length}\n total={recordsTotal}\n onPrev={recordsPagination.prevPage}\n onNext={recordsPagination.nextPage}\n itemLabel=\"records\"\n loading={recordsQuery.loading}\n />\n </GlassCard>\n\n {selectedEventId ? (\n <StationDialog\n open={stationDialogOpen}\n onOpenChange={setStationDialogOpen}\n eventId={selectedEventId}\n eventName={selectedEvent?.name ?? 'this event'}\n station={editingStation}\n />\n ) : null}\n\n <RecordDialog\n open={recordDialogOpen}\n onOpenChange={setRecordDialogOpen}\n record={editingRecord}\n stations={stations}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,84 +1,225 @@
1
1
  import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
2
- import { useMeetingsQuery as t, useNetworkingMatchesQuery as n, useNetworkingProfilesQuery as r } from "../../api/eventApi.js";
3
- import { EntityListSection as i } from "./EntityListSection.js";
4
- import { useMemo as a } from "react";
5
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
6
- import { CalendarDays as c, Megaphone as l, Users as u } from "lucide-react";
7
- import { EmphasisPanel as d, GradientText as f, NextSteps as p, PagePurpose as m } from "@burdenoff/fe-libs/ui";
8
- import { ContextConversationWidget as h } from "@burdenoff/fe-libs/shared";
9
- import { useRegisterPageConversationContext as g } from "@burdenoff/fe-libs/shared/providers/shell";
2
+ import { notify as t } from "../../lib/toast.js";
3
+ import { useAttendeesQuery as n, useDeleteMeetingMutation as r, useMeetingsQuery as i, useNetworkingMatchesQuery as a, useNetworkingProfilesQuery 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 { describeError as u, mutationSucceeded as d } from "../../lib/mutationResult.js";
7
+ import { useMemo as f } from "react";
8
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
9
+ import { CalendarDays as h, CalendarPlus as g, Megaphone as _, UserPlus as v, Users as y } from "lucide-react";
10
+ import { Badge as b, Button as x, EmphasisPanel as S, GlassCard as C, GradientText as w, IllustratedEmptyState as T, NextSteps as E, PagePurpose as D } from "@burdenoff/fe-libs/ui";
11
+ import { ContextConversationWidget as O } from "@burdenoff/fe-libs/shared";
12
+ import { useRegisterPageConversationContext as k } from "@burdenoff/fe-libs/shared/providers/shell";
10
13
  //#region src/eventfullymanaged/pages/modules/NetworkingPage.tsx
11
- function _() {
12
- return g({
14
+ function A(e) {
15
+ let t = e.toLowerCase();
16
+ return [
17
+ "active",
18
+ "published",
19
+ "live",
20
+ "confirmed",
21
+ "completed",
22
+ "approved",
23
+ "public"
24
+ ].includes(t) ? "success" : [
25
+ "inactive",
26
+ "cancelled",
27
+ "archived",
28
+ "closed",
29
+ "expired",
30
+ "private"
31
+ ].includes(t) ? "warning" : [
32
+ "draft",
33
+ "created",
34
+ "pending",
35
+ "scheduled"
36
+ ].includes(t) ? "info" : "secondary";
37
+ }
38
+ function j({ heading: e, loading: t, rows: n, total: r, emptyLabel: i, itemLabel: a, pagination: o, renderActions: s }) {
39
+ return /* @__PURE__ */ m(C, {
40
+ treatment: "plain",
41
+ className: "border-border-seam p-5",
42
+ children: [
43
+ /* @__PURE__ */ p("h2", {
44
+ className: "text-lg font-semibold text-text-primary",
45
+ children: t ? `${e}…` : `${e} (${r})`
46
+ }),
47
+ /* @__PURE__ */ p("div", {
48
+ className: "mt-4",
49
+ children: n.length === 0 ? /* @__PURE__ */ p(T, {
50
+ illustration: "empty-people",
51
+ title: i,
52
+ className: "py-8"
53
+ }) : /* @__PURE__ */ p("ul", {
54
+ className: "space-y-2.5",
55
+ children: n.map((e) => /* @__PURE__ */ p("li", {
56
+ 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",
57
+ children: /* @__PURE__ */ m("div", {
58
+ className: "flex items-center justify-between gap-3",
59
+ children: [/* @__PURE__ */ m("div", {
60
+ className: "min-w-0",
61
+ children: [/* @__PURE__ */ p("p", {
62
+ className: "truncate font-medium text-text-primary",
63
+ children: e.title
64
+ }), e.subtitle ? /* @__PURE__ */ p("p", {
65
+ className: "mt-0.5 truncate text-sm text-text-secondary",
66
+ children: e.subtitle
67
+ }) : null]
68
+ }), /* @__PURE__ */ m("div", {
69
+ className: "flex shrink-0 items-center gap-2",
70
+ children: [e.status ? /* @__PURE__ */ p(b, {
71
+ variant: A(e.status),
72
+ className: "uppercase",
73
+ children: e.status
74
+ }) : null, s?.(e)]
75
+ })]
76
+ })
77
+ }, e.id))
78
+ })
79
+ }),
80
+ /* @__PURE__ */ p(c, {
81
+ offset: o.offset,
82
+ limit: o.limit,
83
+ loadedCount: n.length,
84
+ total: r,
85
+ onPrev: o.prevPage,
86
+ onNext: o.nextPage,
87
+ itemLabel: a,
88
+ loading: t
89
+ })
90
+ ]
91
+ });
92
+ }
93
+ function M() {
94
+ return k({
13
95
  entityType: "EVENTFULLYMANAGED_NETWORKING_LOUNGE",
14
96
  entityId: "general",
15
97
  contextTitle: "Networking Lounge"
16
- }), /* @__PURE__ */ o(h, { widgetKey: "networking-lounge" });
98
+ }), /* @__PURE__ */ p(O, { widgetKey: "networking-lounge" });
17
99
  }
18
- function v() {
19
- let { navigate: h } = e(), g = r({
20
- limit: 100,
21
- offset: 0
22
- }), v = n({
100
+ function N() {
101
+ let { navigate: c } = e(), b = l(), C = l(), T = l(), O = o({
102
+ limit: b.limit,
103
+ offset: b.offset
104
+ }), k = a({
105
+ limit: C.limit,
106
+ offset: C.offset
107
+ }), A = i({
108
+ limit: T.limit,
109
+ offset: T.offset
110
+ }), { data: N } = n({
23
111
  limit: 100,
24
112
  offset: 0
25
- }), y = t({
26
- limit: 100,
27
- offset: 0
28
- }), b = a(() => g.data?.networkingProfiles.items ?? [], [g.data]), x = a(() => v.data?.networkingMatches.items ?? [], [v.data]), S = a(() => y.data?.meetings.items ?? [], [y.data]);
29
- return /* @__PURE__ */ s("div", {
113
+ }), [P] = r(), F = f(() => {
114
+ let e = /* @__PURE__ */ new Map();
115
+ for (let t of N?.attendees?.items ?? []) e.set(t.id, t.fullName);
116
+ return e;
117
+ }, [N]), I = f(() => O.data?.networkingProfiles.items ?? [], [O.data]), L = f(() => k.data?.networkingMatches.items ?? [], [k.data]), R = f(() => A.data?.meetings.items ?? [], [A.data]), z = I.map((e) => ({
118
+ id: e.id,
119
+ title: F.get(e.attendeeId) ?? (e.attendeeId ? `Attendee ${e.attendeeId}` : `Profile ${e.id}`),
120
+ subtitle: [e.role, e.industry].filter(Boolean).join(" • ") || void 0,
121
+ status: e.visibility
122
+ })), B = L.map((e) => ({
123
+ id: e.id,
124
+ title: e.name ?? e.title ?? `Match ${e.id}`,
125
+ subtitle: "Suggested by networking engine",
126
+ status: e.status ?? void 0
127
+ })), V = R.map((e) => ({
128
+ id: e.id,
129
+ title: e.title ?? e.name ?? `Meeting ${e.id}`,
130
+ status: e.status ?? void 0
131
+ })), H = async (e) => {
132
+ try {
133
+ let n = await P({ variables: { id: e.id } });
134
+ if (!d(n, n.data?.deleteMeeting === !0 ? e.id : void 0, "Could not delete meeting")) return;
135
+ t.success("Meeting removed", `${e.title} was deleted.`), await A.refetch();
136
+ } catch (e) {
137
+ t.error("Could not delete meeting", u(e));
138
+ }
139
+ };
140
+ return /* @__PURE__ */ m("div", {
30
141
  className: "space-y-6 p-6",
31
142
  children: [
32
- /* @__PURE__ */ o(m, { children: "Networking turns attendees into connections. Profiles describe who each attendee is and what they are looking for, matches are the suggestions the engine makes between them, and meetings are the 1:1s they book. Use this page to spot strong matches and make sure scheduled meetings are running smoothly." }),
33
- /* @__PURE__ */ s(d, { children: [/* @__PURE__ */ o("h1", {
34
- className: "text-2xl font-bold text-text-primary",
35
- children: /* @__PURE__ */ o(f, { children: "Networking" })
36
- }), /* @__PURE__ */ o("p", {
37
- className: "mt-1 text-sm text-text-secondary",
38
- children: "Manage networking matches and meeting schedules from live backend data."
39
- })] }),
40
- /* @__PURE__ */ o(i, {
41
- heading: g.loading ? "Loading networking profiles..." : `Profiles (${b.length})`,
42
- emptyLabel: "No networking profiles available.",
43
- emptyIllustration: "empty-people",
44
- rows: b.map((e) => ({
45
- id: e.id,
46
- title: e.attendeeId ? `Attendee ${e.attendeeId}` : `Profile ${e.id}`,
47
- subtitle: [e.role, e.industry].filter(Boolean).join(" • "),
48
- status: e.visibility
49
- }))
143
+ /* @__PURE__ */ p(D, { children: "Networking turns attendees into connections. Profiles describe who each attendee is and what they are looking for, matches are the suggestions the engine makes between them, and meetings are the 1:1s they book. Opt an attendee in, review strong matches, and book meetings that mirror straight into the calendar." }),
144
+ /* @__PURE__ */ m(S, {
145
+ className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
146
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
147
+ className: "text-2xl font-bold text-text-primary",
148
+ children: /* @__PURE__ */ p(w, { children: "Networking" })
149
+ }), /* @__PURE__ */ p("p", {
150
+ className: "mt-1 text-sm text-text-secondary",
151
+ children: "Manage profiles, matches and meeting schedules from live backend data."
152
+ })] }), /* @__PURE__ */ m("div", {
153
+ className: "flex flex-wrap gap-2",
154
+ children: [/* @__PURE__ */ m(x, {
155
+ type: "button",
156
+ variant: "outline",
157
+ onClick: () => c("/networking/profiles/create"),
158
+ children: [/* @__PURE__ */ p(v, { className: "h-4 w-4" }), "Opt in a profile"]
159
+ }), /* @__PURE__ */ m(x, {
160
+ type: "button",
161
+ onClick: () => c("/networking/meetings/create"),
162
+ children: [/* @__PURE__ */ p(g, { className: "h-4 w-4" }), "Book a meeting"]
163
+ })]
164
+ })]
165
+ }),
166
+ /* @__PURE__ */ p(j, {
167
+ heading: "Profiles",
168
+ loading: O.loading,
169
+ rows: z,
170
+ total: O.data?.networkingProfiles.total ?? 0,
171
+ emptyLabel: "No networking profiles yet. Opt an attendee in to get started.",
172
+ itemLabel: "profiles",
173
+ pagination: b,
174
+ renderActions: (e) => /* @__PURE__ */ p(s, {
175
+ ariaLabel: `${e.title} actions`,
176
+ onEdit: () => c(`/networking/profiles/${e.id}/edit`)
177
+ })
50
178
  }),
51
- /* @__PURE__ */ o(i, {
52
- heading: v.loading ? "Loading networking matches..." : `Matches (${x.length})`,
53
- emptyLabel: "No networking matches available.",
54
- emptyIllustration: "empty-people",
55
- rows: x.map((e) => ({
56
- id: e.id,
57
- title: e.name ?? e.title ?? `Match ${e.id}`,
58
- subtitle: "Suggested by networking engine",
59
- status: e.status ?? void 0
60
- }))
179
+ /* @__PURE__ */ p(j, {
180
+ heading: "Matches",
181
+ loading: k.loading,
182
+ rows: B,
183
+ total: k.data?.networkingMatches.total ?? 0,
184
+ emptyLabel: "No networking matches yet.",
185
+ itemLabel: "matches",
186
+ pagination: C,
187
+ renderActions: (e) => /* @__PURE__ */ p(s, {
188
+ ariaLabel: `${e.title} actions`,
189
+ extraItems: [{
190
+ key: "book",
191
+ label: "Book meeting",
192
+ icon: g,
193
+ onSelect: () => c("/networking/meetings/create")
194
+ }]
195
+ })
61
196
  }),
62
- /* @__PURE__ */ o(i, {
63
- heading: y.loading ? "Loading meetings..." : `Meetings (${S.length})`,
64
- emptyLabel: "No meetings scheduled.",
65
- rows: S.map((e) => ({
66
- id: e.id,
67
- title: e.title ?? e.name ?? `Meeting ${e.id}`,
68
- status: e.status ?? void 0
69
- }))
197
+ /* @__PURE__ */ p(j, {
198
+ heading: "Meetings",
199
+ loading: A.loading,
200
+ rows: V,
201
+ total: A.data?.meetings.total ?? 0,
202
+ emptyLabel: "No meetings scheduled yet.",
203
+ itemLabel: "meetings",
204
+ pagination: T,
205
+ renderActions: (e) => /* @__PURE__ */ p(s, {
206
+ ariaLabel: `${e.title} actions`,
207
+ entityName: e.title,
208
+ onEdit: () => c(`/networking/meetings/${e.id}/edit`),
209
+ onDelete: () => H(e)
210
+ })
70
211
  }),
71
- /* @__PURE__ */ s("div", {
212
+ /* @__PURE__ */ m("div", {
72
213
  className: "space-y-3",
73
- children: [/* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("h2", {
214
+ children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h2", {
74
215
  className: "text-lg font-semibold text-text-primary",
75
216
  children: "Networking chat"
76
- }), /* @__PURE__ */ o("p", {
217
+ }), /* @__PURE__ */ p("p", {
77
218
  className: "mt-1 text-sm text-text-secondary",
78
219
  children: "A shared space for attendees and organizers to connect, backed by the conversations service."
79
- })] }), /* @__PURE__ */ o(_, {})]
220
+ })] }), /* @__PURE__ */ p(M, {})]
80
221
  }),
81
- /* @__PURE__ */ o(p, {
222
+ /* @__PURE__ */ p(E, {
82
223
  storageKey: "eventfullymanaged-networking",
83
224
  title: "Make networking land",
84
225
  steps: [
@@ -86,22 +227,22 @@ function v() {
86
227
  id: "grow-attendees",
87
228
  label: "Bring in more attendees",
88
229
  description: "More registered attendees means richer matches and meetings.",
89
- icon: /* @__PURE__ */ o(u, { className: "h-4 w-4" }),
90
- onClick: () => h("/registration")
230
+ icon: /* @__PURE__ */ p(y, { className: "h-4 w-4" }),
231
+ onClick: () => c("/registration")
91
232
  },
92
233
  {
93
234
  id: "announce-networking",
94
235
  label: "Announce networking sessions",
95
236
  description: "Let attendees know how and when to connect.",
96
- icon: /* @__PURE__ */ o(l, { className: "h-4 w-4" }),
97
- onClick: () => h("/communication")
237
+ icon: /* @__PURE__ */ p(_, { className: "h-4 w-4" }),
238
+ onClick: () => c("/communication")
98
239
  },
99
240
  {
100
241
  id: "review-event",
101
242
  label: "Review the event schedule",
102
243
  description: "Make sure networking slots fit around your sessions.",
103
- icon: /* @__PURE__ */ o(c, { className: "h-4 w-4" }),
104
- onClick: () => h("/events")
244
+ icon: /* @__PURE__ */ p(h, { className: "h-4 w-4" }),
245
+ onClick: () => c("/events")
105
246
  }
106
247
  ]
107
248
  })
@@ -109,6 +250,6 @@ function v() {
109
250
  });
110
251
  }
111
252
  //#endregion
112
- export { v as default };
253
+ export { N as default };
113
254
 
114
255
  //# sourceMappingURL=NetworkingPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NetworkingPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/NetworkingPage.tsx"],"sourcesContent":["import { CalendarDays, Megaphone, Users } from 'lucide-react';\nimport { ContextConversationWidget } from '@burdenoff/fe-libs/shared';\nimport { useRegisterPageConversationContext } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { EmphasisPanel, GradientText, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo } from 'react';\n\nimport { useMeetingsQuery, useNetworkingMatchesQuery, useNetworkingProfilesQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { EntityListSection } from './EntityListSection';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\n/**\n * Shared networking lounge chat, backed by wspace-conversations-svc. Scoped by a\n * stable networking entity so every organizer/attendee on this workspace lands in\n * the same thread.\n */\nfunction NetworkingLounge() {\n useRegisterPageConversationContext({\n entityType: 'EVENTFULLYMANAGED_NETWORKING_LOUNGE',\n entityId: 'general',\n contextTitle: 'Networking Lounge',\n });\n return <ContextConversationWidget widgetKey=\"networking-lounge\" />;\n}\n\nexport default function NetworkingPage() {\n const { navigate } = useEventfullyManaged();\n const profilesQuery = useNetworkingProfilesQuery({ limit: 100, offset: 0 });\n const matchesQuery = useNetworkingMatchesQuery({ limit: 100, offset: 0 });\n const meetingsQuery = useMeetingsQuery({ limit: 100, offset: 0 });\n\n const profiles = useMemo(() => profilesQuery.data?.networkingProfiles.items ?? [], [profilesQuery.data]);\n const matches = useMemo(() => (matchesQuery.data?.networkingMatches.items ?? []) as SimpleRow[], [matchesQuery.data]);\n const meetings = useMemo(() => (meetingsQuery.data?.meetings.items ?? []) as SimpleRow[], [meetingsQuery.data]);\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Networking turns attendees into connections. Profiles describe who each attendee is and what they are looking\n for, matches are the suggestions the engine makes between them, and meetings are the 1:1s they book. Use this\n page to spot strong matches and make sure scheduled meetings are running smoothly.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Networking</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Manage networking matches and meeting schedules from live backend data.\n </p>\n </EmphasisPanel>\n\n <EntityListSection\n heading={profilesQuery.loading ? 'Loading networking profiles...' : `Profiles (${profiles.length})`}\n emptyLabel=\"No networking profiles available.\"\n emptyIllustration=\"empty-people\"\n rows={profiles.map((row) => ({\n id: row.id,\n title: row.attendeeId ? `Attendee ${row.attendeeId}` : `Profile ${row.id}`,\n subtitle: [row.role, row.industry].filter(Boolean).join(' • '),\n status: row.visibility,\n }))}\n />\n\n <EntityListSection\n heading={matchesQuery.loading ? 'Loading networking matches...' : `Matches (${matches.length})`}\n emptyLabel=\"No networking matches available.\"\n emptyIllustration=\"empty-people\"\n rows={matches.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Match ${row.id}`,\n subtitle: 'Suggested by networking engine',\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={meetingsQuery.loading ? 'Loading meetings...' : `Meetings (${meetings.length})`}\n emptyLabel=\"No meetings scheduled.\"\n rows={meetings.map((row) => ({\n id: row.id,\n title: row.title ?? row.name ?? `Meeting ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <div className=\"space-y-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Networking chat</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n A shared space for attendees and organizers to connect, backed by the conversations service.\n </p>\n </div>\n <NetworkingLounge />\n </div>\n\n <NextSteps\n storageKey=\"eventfullymanaged-networking\"\n title=\"Make networking land\"\n steps={[\n {\n id: 'grow-attendees',\n label: 'Bring in more attendees',\n description: 'More registered attendees means richer matches and meetings.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('/registration'),\n },\n {\n id: 'announce-networking',\n label: 'Announce networking sessions',\n description: 'Let attendees know how and when to connect.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n {\n id: 'review-event',\n label: 'Review the event schedule',\n description: 'Make sure networking slots fit around your sessions.',\n icon: <CalendarDays className=\"h-4 w-4\" />,\n onClick: () => navigate('/events'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"NetworkingPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/NetworkingPage.tsx"],"sourcesContent":["import { CalendarDays, CalendarPlus, Megaphone, UserPlus, Users } from 'lucide-react';\nimport { ContextConversationWidget } from '@burdenoff/fe-libs/shared';\nimport { useRegisterPageConversationContext } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n Badge,\n Button,\n EmphasisPanel,\n GlassCard,\n GradientText,\n IllustratedEmptyState,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, type ReactNode } from 'react';\n\nimport {\n useAttendeesQuery,\n useDeleteMeetingMutation,\n useMeetingsQuery,\n useNetworkingMatchesQuery,\n useNetworkingProfilesQuery,\n} from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { Pagination, usePagination, type UsePaginationResult } from '../../components/Pagination';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\ntype ListRow = {\n id: string;\n title: string;\n subtitle?: string;\n status?: string;\n};\n\nfunction statusVariant(status: string): 'success' | 'warning' | 'secondary' | 'info' {\n const value = status.toLowerCase();\n if (['active', 'published', 'live', 'confirmed', 'completed', 'approved', 'public'].includes(value)) {\n return 'success';\n }\n if (['inactive', 'cancelled', 'archived', 'closed', 'expired', 'private'].includes(value)) {\n return 'warning';\n }\n if (['draft', 'created', 'pending', 'scheduled'].includes(value)) {\n return 'info';\n }\n return 'secondary';\n}\n\ninterface NetworkingListProps {\n heading: string;\n loading: boolean;\n rows: ListRow[];\n total: number;\n emptyLabel: string;\n itemLabel: string;\n pagination: UsePaginationResult;\n renderActions?: (row: ListRow) => ReactNode;\n}\n\nfunction NetworkingList({\n heading,\n loading,\n rows,\n total,\n emptyLabel,\n itemLabel,\n pagination,\n renderActions,\n}: NetworkingListProps) {\n return (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{loading ? `${heading}…` : `${heading} (${total})`}</h2>\n <div className=\"mt-4\">\n {rows.length === 0 ? (\n <IllustratedEmptyState illustration=\"empty-people\" title={emptyLabel} className=\"py-8\" />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((row) => (\n <li\n key={row.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\">{row.title}</p>\n {row.subtitle ? (\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{row.subtitle}</p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n {row.status ? (\n <Badge variant={statusVariant(row.status)} className=\"uppercase\">\n {row.status}\n </Badge>\n ) : null}\n {renderActions?.(row)}\n </div>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\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={itemLabel}\n loading={loading}\n />\n </GlassCard>\n );\n}\n\n/**\n * Shared networking lounge chat, backed by wspace-conversations-svc. Scoped by a\n * stable networking entity so every organizer/attendee on this workspace lands in\n * the same thread.\n */\nfunction NetworkingLounge() {\n useRegisterPageConversationContext({\n entityType: 'EVENTFULLYMANAGED_NETWORKING_LOUNGE',\n entityId: 'general',\n contextTitle: 'Networking Lounge',\n });\n return <ContextConversationWidget widgetKey=\"networking-lounge\" />;\n}\n\nexport default function NetworkingPage() {\n const { navigate } = useEventfullyManaged();\n\n const profilesPagination = usePagination();\n const matchesPagination = usePagination();\n const meetingsPagination = usePagination();\n\n const profilesQuery = useNetworkingProfilesQuery({\n limit: profilesPagination.limit,\n offset: profilesPagination.offset,\n });\n const matchesQuery = useNetworkingMatchesQuery({\n limit: matchesPagination.limit,\n offset: matchesPagination.offset,\n });\n const meetingsQuery = useMeetingsQuery({\n limit: meetingsPagination.limit,\n offset: meetingsPagination.offset,\n });\n const { data: attendeesData } = useAttendeesQuery({ limit: 100, offset: 0 });\n\n const [deleteMeeting] = useDeleteMeetingMutation();\n\n const attendeeNames = useMemo(() => {\n const map = new Map<string, string>();\n for (const attendee of attendeesData?.attendees?.items ?? []) {\n map.set(attendee.id, attendee.fullName);\n }\n return map;\n }, [attendeesData]);\n\n const profiles = useMemo(() => profilesQuery.data?.networkingProfiles.items ?? [], [profilesQuery.data]);\n const matches = useMemo(() => (matchesQuery.data?.networkingMatches.items ?? []) as SimpleRow[], [matchesQuery.data]);\n const meetings = useMemo(() => (meetingsQuery.data?.meetings.items ?? []) as SimpleRow[], [meetingsQuery.data]);\n\n const profileRows: ListRow[] = profiles.map((row) => ({\n id: row.id,\n title: attendeeNames.get(row.attendeeId) ?? (row.attendeeId ? `Attendee ${row.attendeeId}` : `Profile ${row.id}`),\n subtitle: [row.role, row.industry].filter(Boolean).join(' • ') || undefined,\n status: row.visibility,\n }));\n\n const matchRows: ListRow[] = matches.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Match ${row.id}`,\n subtitle: 'Suggested by networking engine',\n status: row.status ?? undefined,\n }));\n\n const meetingRows: ListRow[] = meetings.map((row) => ({\n id: row.id,\n title: row.title ?? row.name ?? `Meeting ${row.id}`,\n status: row.status ?? undefined,\n }));\n\n const onDeleteMeeting = async (row: ListRow) => {\n try {\n const response = await deleteMeeting({ variables: { id: row.id } });\n const deleted = response.data?.deleteMeeting === true;\n if (!mutationSucceeded(response, deleted ? row.id : undefined, 'Could not delete meeting')) {\n return;\n }\n notify.success('Meeting removed', `${row.title} was deleted.`);\n await meetingsQuery.refetch();\n } catch (error) {\n notify.error('Could not delete meeting', describeError(error));\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Networking turns attendees into connections. Profiles describe who each attendee is and what they are looking\n for, matches are the suggestions the engine makes between them, and meetings are the 1:1s they book. Opt an\n attendee in, review strong matches, and book meetings that mirror straight into the calendar.\n </PagePurpose>\n\n <EmphasisPanel className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Networking</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Manage profiles, matches and meeting schedules from live backend data.\n </p>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('/networking/profiles/create')}>\n <UserPlus className=\"h-4 w-4\" />\n Opt in a profile\n </Button>\n <Button type=\"button\" onClick={() => navigate('/networking/meetings/create')}>\n <CalendarPlus className=\"h-4 w-4\" />\n Book a meeting\n </Button>\n </div>\n </EmphasisPanel>\n\n <NetworkingList\n heading=\"Profiles\"\n loading={profilesQuery.loading}\n rows={profileRows}\n total={profilesQuery.data?.networkingProfiles.total ?? 0}\n emptyLabel=\"No networking profiles yet. Opt an attendee in to get started.\"\n itemLabel=\"profiles\"\n pagination={profilesPagination}\n renderActions={(row) => (\n <ActionMenu\n ariaLabel={`${row.title} actions`}\n onEdit={() => navigate(`/networking/profiles/${row.id}/edit`)}\n />\n )}\n />\n\n <NetworkingList\n heading=\"Matches\"\n loading={matchesQuery.loading}\n rows={matchRows}\n total={matchesQuery.data?.networkingMatches.total ?? 0}\n emptyLabel=\"No networking matches yet.\"\n itemLabel=\"matches\"\n pagination={matchesPagination}\n renderActions={(row) => (\n <ActionMenu\n ariaLabel={`${row.title} actions`}\n extraItems={[\n {\n key: 'book',\n label: 'Book meeting',\n icon: CalendarPlus,\n onSelect: () => navigate('/networking/meetings/create'),\n },\n ]}\n />\n )}\n />\n\n <NetworkingList\n heading=\"Meetings\"\n loading={meetingsQuery.loading}\n rows={meetingRows}\n total={meetingsQuery.data?.meetings.total ?? 0}\n emptyLabel=\"No meetings scheduled yet.\"\n itemLabel=\"meetings\"\n pagination={meetingsPagination}\n renderActions={(row) => (\n <ActionMenu\n ariaLabel={`${row.title} actions`}\n entityName={row.title}\n onEdit={() => navigate(`/networking/meetings/${row.id}/edit`)}\n onDelete={() => onDeleteMeeting(row)}\n />\n )}\n />\n\n <div className=\"space-y-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Networking chat</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n A shared space for attendees and organizers to connect, backed by the conversations service.\n </p>\n </div>\n <NetworkingLounge />\n </div>\n\n <NextSteps\n storageKey=\"eventfullymanaged-networking\"\n title=\"Make networking land\"\n steps={[\n {\n id: 'grow-attendees',\n label: 'Bring in more attendees',\n description: 'More registered attendees means richer matches and meetings.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('/registration'),\n },\n {\n id: 'announce-networking',\n label: 'Announce networking sessions',\n description: 'Let attendees know how and when to connect.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n {\n id: 'review-event',\n label: 'Review the event schedule',\n description: 'Make sure networking slots fit around your sessions.',\n icon: <CalendarDays className=\"h-4 w-4\" />,\n onClick: () => navigate('/events'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":"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"}