@burdenoff/microfe-eventfullymanaged 2026.704.1 → 2026.704.3

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 (26) hide show
  1. package/dist/eventfullymanaged/EventfullyManagedRoutes.js +0 -4
  2. package/dist/eventfullymanaged/EventfullyManagedRoutes.js.map +1 -1
  3. package/dist/eventfullymanaged/components/EntityTagsField.js.map +1 -1
  4. package/dist/eventfullymanaged/pages/events/EventDetailPage.js.map +1 -1
  5. package/dist/eventfullymanaged/pages/events/EventFormPage.js.map +1 -1
  6. package/dist/eventfullymanaged/pages/events/SessionFormPage.js.map +1 -1
  7. package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js.map +1 -1
  8. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
  9. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js +2 -2
  10. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js.map +1 -1
  11. package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
  12. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +13 -12
  13. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
  14. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +18 -11
  15. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
  16. package/dist/eventfullymanaged/pages/modules/RoadmapPanel.js.map +1 -1
  17. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +2 -2
  18. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
  19. package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js.map +1 -1
  20. package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js.map +1 -1
  21. package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js.map +1 -1
  22. package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js.map +1 -1
  23. package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js +2 -1
  24. package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js.map +1 -1
  25. package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js.map +1 -1
  26. package/package.json +1 -1
@@ -165,10 +165,6 @@ function V() {
165
165
  path: "networking/meetings/:id/edit",
166
166
  element: /* @__PURE__ */ a(k, {})
167
167
  }),
168
- /* @__PURE__ */ a(r, {
169
- path: "networking/*",
170
- element: /* @__PURE__ */ a(D, {})
171
- }),
172
168
  /* @__PURE__ */ a(r, {
173
169
  path: "attendees/:id/profile",
174
170
  element: /* @__PURE__ */ a(z, {})
@@ -1 +1 @@
1
- {"version":3,"file":"EventfullyManagedRoutes.js","names":[],"sources":["../../src/eventfullymanaged/EventfullyManagedRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\n\nconst DashboardPage = lazy(() => import('./pages/dashboard/DashboardPage'));\nconst VenueListPage = lazy(() => import('./pages/venues/VenueListPage'));\nconst VenueFormPage = lazy(() => import('./pages/venues/VenueFormPage'));\nconst VenueDetailPage = lazy(() => import('./pages/venues/VenueDetailPage'));\nconst FloorPlansPage = lazy(() => import('./pages/venues/FloorPlansPage'));\nconst SponsorsListPage = lazy(() => import('./pages/sponsors/SponsorsListPage'));\nconst SponsorFormPage = lazy(() => import('./pages/sponsors/SponsorFormPage'));\nconst EventsPage = lazy(() => import('./pages/modules/EventsPage'));\nconst EventDetailPage = lazy(() => import('./pages/events/EventDetailPage'));\nconst EventFormPage = lazy(() => import('./pages/events/EventFormPage'));\nconst SessionFormPage = lazy(() => import('./pages/events/SessionFormPage'));\nconst TicketTypeFormPage = lazy(() => import('./pages/events/TicketTypeFormPage'));\nconst SpeakersPage = lazy(() => import('./pages/speakers/SpeakersPage'));\nconst SpeakerFormPage = lazy(() => import('./pages/speakers/SpeakerFormPage'));\nconst RegistrationPage = lazy(() => import('./pages/modules/RegistrationPage'));\nconst RegisterAttendeePage = lazy(() => import('./pages/registration/RegisterAttendeePage'));\nconst AttendeeFormPage = lazy(() => import('./pages/registration/AttendeeFormPage'));\nconst PromoCodeFormPage = lazy(() => import('./pages/registration/PromoCodeFormPage'));\nconst CommunicationPage = lazy(() => import('./pages/modules/CommunicationPage'));\nconst AnalyticsPage = lazy(() => import('./pages/modules/AnalyticsPage'));\nconst NetworkingPage = lazy(() => import('./pages/modules/NetworkingPage'));\nconst NetworkingProfileFormPage = lazy(() => import('./pages/networking/NetworkingProfileFormPage'));\nconst MeetingFormPage = lazy(() => import('./pages/networking/MeetingFormPage'));\nconst ExhibitorsPage = lazy(() => import('./pages/exhibitors/ExhibitorsPage'));\nconst ExhibitorFormPage = lazy(() => import('./pages/exhibitors/ExhibitorFormPage'));\nconst WorkflowsPage = lazy(() => import('./pages/modules/WorkflowsPage'));\nconst KioskPage = lazy(() => import('./pages/modules/KioskPage'));\nconst OperationsHubPage = lazy(() => import('./pages/modules/OperationsHubPage'));\nconst RoadmapPanel = lazy(() => import('./pages/modules/RoadmapPanel'));\nconst VenueResourcesPage = lazy(() => import('./pages/modules/VenueResourcesPage'));\nconst SponsorDetailsPage = lazy(() => import('./pages/modules/SponsorDetailsPage'));\nconst SponsorLeadsPage = lazy(() => import('./pages/modules/SponsorLeadsPage'));\nconst AttendeeProfilePage = lazy(() => import('./pages/modules/AttendeeProfilePage'));\n\nfunction PageLoader() {\n return (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-2 border-border-default border-t-text-primary\" />\n </div>\n );\n}\n\nexport function EventfullyManagedRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<DashboardPage />} />\n\n <Route path=\"venues\" element={<VenueListPage />} />\n <Route path=\"venues/create\" element={<VenueFormPage />} />\n <Route path=\"venues/:id\" element={<VenueDetailPage />} />\n <Route path=\"venues/:id/edit\" element={<VenueFormPage />} />\n <Route path=\"venues/:id/floor-plans\" element={<FloorPlansPage />} />\n <Route path=\"venues/:id/resources\" element={<VenueResourcesPage />} />\n\n <Route path=\"sponsors\" element={<SponsorsListPage />} />\n <Route path=\"sponsors/create\" element={<SponsorFormPage />} />\n <Route path=\"sponsors/:id\" element={<SponsorDetailsPage />} />\n <Route path=\"sponsors/:id/edit\" element={<SponsorFormPage />} />\n <Route path=\"sponsors/:id/leads\" element={<SponsorLeadsPage />} />\n\n <Route path=\"events\" element={<EventsPage />} />\n <Route path=\"events/create\" element={<EventFormPage />} />\n <Route path=\"events/:id\" element={<EventDetailPage />} />\n <Route path=\"events/:id/edit\" element={<EventFormPage />} />\n <Route path=\"events/:id/sessions/create\" element={<SessionFormPage />} />\n <Route path=\"events/:id/sessions/:sid/edit\" element={<SessionFormPage />} />\n <Route path=\"events/:id/tickets/create\" element={<TicketTypeFormPage />} />\n <Route path=\"events/:id/tickets/:tid/edit\" element={<TicketTypeFormPage />} />\n\n <Route path=\"speakers\" element={<SpeakersPage />} />\n <Route path=\"speakers/create\" element={<SpeakerFormPage />} />\n <Route path=\"speakers/:id/edit\" element={<SpeakerFormPage />} />\n\n <Route path=\"registration\" element={<RegistrationPage />} />\n <Route path=\"registration/register\" element={<RegisterAttendeePage />} />\n <Route path=\"registration/attendees/create\" element={<AttendeeFormPage />} />\n <Route path=\"registration/attendees/:id/edit\" element={<AttendeeFormPage />} />\n <Route path=\"registration/promo-codes/create\" element={<PromoCodeFormPage />} />\n <Route path=\"registration/promo-codes/:id/edit\" element={<PromoCodeFormPage />} />\n\n <Route path=\"communication\" element={<CommunicationPage />} />\n <Route path=\"communication/*\" element={<CommunicationPage />} />\n <Route path=\"analytics\" element={<AnalyticsPage />} />\n <Route path=\"analytics/*\" element={<AnalyticsPage />} />\n\n <Route path=\"networking\" element={<NetworkingPage />} />\n <Route path=\"networking/profiles/create\" element={<NetworkingProfileFormPage />} />\n <Route path=\"networking/profiles/:id/edit\" element={<NetworkingProfileFormPage />} />\n <Route path=\"networking/meetings/create\" element={<MeetingFormPage />} />\n <Route path=\"networking/meetings/:id/edit\" element={<MeetingFormPage />} />\n <Route path=\"networking/*\" element={<NetworkingPage />} />\n\n <Route path=\"attendees/:id/profile\" element={<AttendeeProfilePage />} />\n\n <Route path=\"exhibitors\" element={<ExhibitorsPage />} />\n <Route path=\"exhibitors/create\" element={<ExhibitorFormPage />} />\n <Route path=\"exhibitors/:id/edit\" element={<ExhibitorFormPage />} />\n\n <Route\n path=\"exhibition/*\"\n element={\n <OperationsHubPage\n title=\"Exhibition\"\n description=\"Exhibition layout and on-site flow based on venue, check-in, and exhibitor activity.\"\n sectionKeys={['venues', 'checkInRecords', 'exhibitors']}\n />\n }\n />\n <Route\n path=\"hr\"\n element={\n <OperationsHubPage\n title=\"HR\"\n description=\"Event staffing metrics and delegated workforce operations summary.\"\n sectionKeys={['templates', 'rules', 'registrations']}\n />\n }\n />\n <Route\n path=\"hr/*\"\n element={\n <OperationsHubPage\n title=\"HR\"\n description=\"Event staffing metrics and delegated workforce operations summary.\"\n sectionKeys={['templates', 'rules', 'registrations']}\n />\n }\n />\n <Route\n path=\"finance\"\n element={\n <OperationsHubPage\n title=\"Finance\"\n description=\"Financial KPI overview from registrations, sponsor portfolio, and analytics snapshots.\"\n sectionKeys={['registrations', 'ticketTypes', 'promoCodes']}\n />\n }\n />\n <Route\n path=\"finance/*\"\n element={\n <OperationsHubPage\n title=\"Finance\"\n description=\"Financial KPI overview from registrations, sponsor portfolio, and analytics snapshots.\"\n sectionKeys={['registrations', 'ticketTypes', 'promoCodes']}\n />\n }\n />\n <Route path=\"workflows\" element={<WorkflowsPage />} />\n <Route path=\"workflows/*\" element={<WorkflowsPage />} />\n <Route path=\"automations\" element={<WorkflowsPage />} />\n <Route\n path=\"api/*\"\n element={\n <RoadmapPanel\n title=\"API Access\"\n summary=\"Programmatic API access for EventfullyManaged is not available yet.\"\n purpose=\"This area will expose a public API and developer credentials for EventfullyManaged. It is not built yet — rather than show unrelated workflow records, this page honestly states what is planned.\"\n items={[\n { id: 'keys', title: 'API keys & tokens', description: 'Issue and rotate scoped API credentials for your workspace.', stage: 'planned' },\n { id: 'rest', title: 'REST & GraphQL endpoints', description: 'Read and manage events, venues, sponsors and registrations programmatically.', stage: 'exploring' },\n { id: 'docs', title: 'Reference documentation', description: 'Interactive schema and code samples for every operation.', stage: 'exploring' },\n ]}\n />\n }\n />\n <Route\n path=\"integrations/*\"\n element={\n <RoadmapPanel\n title=\"Integrations\"\n summary=\"Third-party integrations for EventfullyManaged are not available yet.\"\n purpose=\"This area will connect EventfullyManaged to external tools (calendars, CRMs, marketing and payment providers). It is not built yet — this page states the roadmap instead of surfacing unrelated automation records.\"\n items={[\n { id: 'webhooks', title: 'Outbound webhooks', description: 'Notify external systems on registrations, check-ins and campaign events.', stage: 'planned' },\n { id: 'calendar', title: 'Calendar sync', description: 'Push sessions and event schedules to Google/Outlook calendars.', stage: 'exploring' },\n { id: 'crm', title: 'CRM & marketing connectors', description: 'Sync attendees and leads to your CRM and marketing platform.', stage: 'exploring' },\n ]}\n />\n }\n />\n <Route\n path=\"settings\"\n element={\n <OperationsHubPage\n title=\"Settings\"\n description=\"Module-level configuration visibility from live operational entities.\"\n sectionKeys={['templates', 'campaigns', 'snapshots']}\n />\n }\n />\n <Route\n path=\"settings/*\"\n element={\n <OperationsHubPage\n title=\"Settings\"\n description=\"Module-level configuration visibility from live operational entities.\"\n sectionKeys={['templates', 'campaigns', 'snapshots']}\n />\n }\n />\n <Route\n path=\"admin\"\n element={\n <OperationsHubPage\n title=\"Administration\"\n description=\"Administrative controls and policy telemetry via workflow and communication records.\"\n sectionKeys={['announcements', 'templates', 'rules']}\n />\n }\n />\n <Route\n path=\"admin/*\"\n element={\n <OperationsHubPage\n title=\"Administration\"\n description=\"Administrative controls and policy telemetry via workflow and communication records.\"\n sectionKeys={['announcements', 'templates', 'rules']}\n />\n }\n />\n <Route path=\"kiosk\" element={<KioskPage />} />\n <Route path=\"kiosk/*\" element={<KioskPage />} />\n\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventfullyManagedRoutes.js","names":[],"sources":["../../src/eventfullymanaged/EventfullyManagedRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\n\nconst DashboardPage = lazy(() => import('./pages/dashboard/DashboardPage'));\nconst VenueListPage = lazy(() => import('./pages/venues/VenueListPage'));\nconst VenueFormPage = lazy(() => import('./pages/venues/VenueFormPage'));\nconst VenueDetailPage = lazy(() => import('./pages/venues/VenueDetailPage'));\nconst FloorPlansPage = lazy(() => import('./pages/venues/FloorPlansPage'));\nconst SponsorsListPage = lazy(() => import('./pages/sponsors/SponsorsListPage'));\nconst SponsorFormPage = lazy(() => import('./pages/sponsors/SponsorFormPage'));\nconst EventsPage = lazy(() => import('./pages/modules/EventsPage'));\nconst EventDetailPage = lazy(() => import('./pages/events/EventDetailPage'));\nconst EventFormPage = lazy(() => import('./pages/events/EventFormPage'));\nconst SessionFormPage = lazy(() => import('./pages/events/SessionFormPage'));\nconst TicketTypeFormPage = lazy(() => import('./pages/events/TicketTypeFormPage'));\nconst SpeakersPage = lazy(() => import('./pages/speakers/SpeakersPage'));\nconst SpeakerFormPage = lazy(() => import('./pages/speakers/SpeakerFormPage'));\nconst RegistrationPage = lazy(() => import('./pages/modules/RegistrationPage'));\nconst RegisterAttendeePage = lazy(() => import('./pages/registration/RegisterAttendeePage'));\nconst AttendeeFormPage = lazy(() => import('./pages/registration/AttendeeFormPage'));\nconst PromoCodeFormPage = lazy(() => import('./pages/registration/PromoCodeFormPage'));\nconst CommunicationPage = lazy(() => import('./pages/modules/CommunicationPage'));\nconst AnalyticsPage = lazy(() => import('./pages/modules/AnalyticsPage'));\nconst NetworkingPage = lazy(() => import('./pages/modules/NetworkingPage'));\nconst NetworkingProfileFormPage = lazy(() => import('./pages/networking/NetworkingProfileFormPage'));\nconst MeetingFormPage = lazy(() => import('./pages/networking/MeetingFormPage'));\nconst ExhibitorsPage = lazy(() => import('./pages/exhibitors/ExhibitorsPage'));\nconst ExhibitorFormPage = lazy(() => import('./pages/exhibitors/ExhibitorFormPage'));\nconst WorkflowsPage = lazy(() => import('./pages/modules/WorkflowsPage'));\nconst KioskPage = lazy(() => import('./pages/modules/KioskPage'));\nconst OperationsHubPage = lazy(() => import('./pages/modules/OperationsHubPage'));\nconst RoadmapPanel = lazy(() => import('./pages/modules/RoadmapPanel'));\nconst VenueResourcesPage = lazy(() => import('./pages/modules/VenueResourcesPage'));\nconst SponsorDetailsPage = lazy(() => import('./pages/modules/SponsorDetailsPage'));\nconst SponsorLeadsPage = lazy(() => import('./pages/modules/SponsorLeadsPage'));\nconst AttendeeProfilePage = lazy(() => import('./pages/modules/AttendeeProfilePage'));\n\nfunction PageLoader() {\n return (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-2 border-border-default border-t-text-primary\" />\n </div>\n );\n}\n\nexport function EventfullyManagedRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<DashboardPage />} />\n\n <Route path=\"venues\" element={<VenueListPage />} />\n <Route path=\"venues/create\" element={<VenueFormPage />} />\n <Route path=\"venues/:id\" element={<VenueDetailPage />} />\n <Route path=\"venues/:id/edit\" element={<VenueFormPage />} />\n <Route path=\"venues/:id/floor-plans\" element={<FloorPlansPage />} />\n <Route path=\"venues/:id/resources\" element={<VenueResourcesPage />} />\n\n <Route path=\"sponsors\" element={<SponsorsListPage />} />\n <Route path=\"sponsors/create\" element={<SponsorFormPage />} />\n <Route path=\"sponsors/:id\" element={<SponsorDetailsPage />} />\n <Route path=\"sponsors/:id/edit\" element={<SponsorFormPage />} />\n <Route path=\"sponsors/:id/leads\" element={<SponsorLeadsPage />} />\n\n <Route path=\"events\" element={<EventsPage />} />\n <Route path=\"events/create\" element={<EventFormPage />} />\n <Route path=\"events/:id\" element={<EventDetailPage />} />\n <Route path=\"events/:id/edit\" element={<EventFormPage />} />\n <Route path=\"events/:id/sessions/create\" element={<SessionFormPage />} />\n <Route path=\"events/:id/sessions/:sid/edit\" element={<SessionFormPage />} />\n <Route path=\"events/:id/tickets/create\" element={<TicketTypeFormPage />} />\n <Route path=\"events/:id/tickets/:tid/edit\" element={<TicketTypeFormPage />} />\n\n <Route path=\"speakers\" element={<SpeakersPage />} />\n <Route path=\"speakers/create\" element={<SpeakerFormPage />} />\n <Route path=\"speakers/:id/edit\" element={<SpeakerFormPage />} />\n\n <Route path=\"registration\" element={<RegistrationPage />} />\n <Route path=\"registration/register\" element={<RegisterAttendeePage />} />\n <Route path=\"registration/attendees/create\" element={<AttendeeFormPage />} />\n <Route path=\"registration/attendees/:id/edit\" element={<AttendeeFormPage />} />\n <Route path=\"registration/promo-codes/create\" element={<PromoCodeFormPage />} />\n <Route path=\"registration/promo-codes/:id/edit\" element={<PromoCodeFormPage />} />\n\n <Route path=\"communication\" element={<CommunicationPage />} />\n <Route path=\"communication/*\" element={<CommunicationPage />} />\n <Route path=\"analytics\" element={<AnalyticsPage />} />\n <Route path=\"analytics/*\" element={<AnalyticsPage />} />\n\n <Route path=\"networking\" element={<NetworkingPage />} />\n <Route path=\"networking/profiles/create\" element={<NetworkingProfileFormPage />} />\n <Route path=\"networking/profiles/:id/edit\" element={<NetworkingProfileFormPage />} />\n <Route path=\"networking/meetings/create\" element={<MeetingFormPage />} />\n <Route path=\"networking/meetings/:id/edit\" element={<MeetingFormPage />} />\n\n <Route path=\"attendees/:id/profile\" element={<AttendeeProfilePage />} />\n\n <Route path=\"exhibitors\" element={<ExhibitorsPage />} />\n <Route path=\"exhibitors/create\" element={<ExhibitorFormPage />} />\n <Route path=\"exhibitors/:id/edit\" element={<ExhibitorFormPage />} />\n\n <Route\n path=\"exhibition/*\"\n element={\n <OperationsHubPage\n title=\"Exhibition\"\n description=\"Exhibition layout and on-site flow based on venue, check-in, and exhibitor activity.\"\n sectionKeys={['venues', 'checkInRecords', 'exhibitors']}\n />\n }\n />\n <Route\n path=\"hr\"\n element={\n <OperationsHubPage\n title=\"HR\"\n description=\"Event staffing metrics and delegated workforce operations summary.\"\n sectionKeys={['templates', 'rules', 'registrations']}\n />\n }\n />\n <Route\n path=\"hr/*\"\n element={\n <OperationsHubPage\n title=\"HR\"\n description=\"Event staffing metrics and delegated workforce operations summary.\"\n sectionKeys={['templates', 'rules', 'registrations']}\n />\n }\n />\n <Route\n path=\"finance\"\n element={\n <OperationsHubPage\n title=\"Finance\"\n description=\"Financial KPI overview from registrations, sponsor portfolio, and analytics snapshots.\"\n sectionKeys={['registrations', 'ticketTypes', 'promoCodes']}\n />\n }\n />\n <Route\n path=\"finance/*\"\n element={\n <OperationsHubPage\n title=\"Finance\"\n description=\"Financial KPI overview from registrations, sponsor portfolio, and analytics snapshots.\"\n sectionKeys={['registrations', 'ticketTypes', 'promoCodes']}\n />\n }\n />\n <Route path=\"workflows\" element={<WorkflowsPage />} />\n <Route path=\"workflows/*\" element={<WorkflowsPage />} />\n <Route path=\"automations\" element={<WorkflowsPage />} />\n <Route\n path=\"api/*\"\n element={\n <RoadmapPanel\n title=\"API Access\"\n summary=\"Programmatic API access for EventfullyManaged is not available yet.\"\n purpose=\"This area will expose a public API and developer credentials for EventfullyManaged. It is not built yet — rather than show unrelated workflow records, this page honestly states what is planned.\"\n items={[\n {\n id: 'keys',\n title: 'API keys & tokens',\n description: 'Issue and rotate scoped API credentials for your workspace.',\n stage: 'planned',\n },\n {\n id: 'rest',\n title: 'REST & GraphQL endpoints',\n description: 'Read and manage events, venues, sponsors and registrations programmatically.',\n stage: 'exploring',\n },\n {\n id: 'docs',\n title: 'Reference documentation',\n description: 'Interactive schema and code samples for every operation.',\n stage: 'exploring',\n },\n ]}\n />\n }\n />\n <Route\n path=\"integrations/*\"\n element={\n <RoadmapPanel\n title=\"Integrations\"\n summary=\"Third-party integrations for EventfullyManaged are not available yet.\"\n purpose=\"This area will connect EventfullyManaged to external tools (calendars, CRMs, marketing and payment providers). It is not built yet — this page states the roadmap instead of surfacing unrelated automation records.\"\n items={[\n {\n id: 'webhooks',\n title: 'Outbound webhooks',\n description: 'Notify external systems on registrations, check-ins and campaign events.',\n stage: 'planned',\n },\n {\n id: 'calendar',\n title: 'Calendar sync',\n description: 'Push sessions and event schedules to Google/Outlook calendars.',\n stage: 'exploring',\n },\n {\n id: 'crm',\n title: 'CRM & marketing connectors',\n description: 'Sync attendees and leads to your CRM and marketing platform.',\n stage: 'exploring',\n },\n ]}\n />\n }\n />\n <Route\n path=\"settings\"\n element={\n <OperationsHubPage\n title=\"Settings\"\n description=\"Module-level configuration visibility from live operational entities.\"\n sectionKeys={['templates', 'campaigns', 'snapshots']}\n />\n }\n />\n <Route\n path=\"settings/*\"\n element={\n <OperationsHubPage\n title=\"Settings\"\n description=\"Module-level configuration visibility from live operational entities.\"\n sectionKeys={['templates', 'campaigns', 'snapshots']}\n />\n }\n />\n <Route\n path=\"admin\"\n element={\n <OperationsHubPage\n title=\"Administration\"\n description=\"Administrative controls and policy telemetry via workflow and communication records.\"\n sectionKeys={['announcements', 'templates', 'rules']}\n />\n }\n />\n <Route\n path=\"admin/*\"\n element={\n <OperationsHubPage\n title=\"Administration\"\n description=\"Administrative controls and policy telemetry via workflow and communication records.\"\n sectionKeys={['announcements', 'templates', 'rules']}\n />\n }\n />\n <Route path=\"kiosk\" element={<KioskPage />} />\n <Route path=\"kiosk/*\" element={<KioskPage />} />\n\n <Route path=\"*\" element={<Navigate to=\".\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EntityTagsField.js","names":[],"sources":["../../../src/eventfullymanaged/components/EntityTagsField.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Plus, Tag as TagIcon, X } from 'lucide-react';\nimport {\n Badge,\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useAvailableTagsQuery,\n useCreateEntityTagMutation,\n useEntityTagsQuery,\n useTagEntityMutation,\n useUntagEntityMutation,\n} from '../api/eventApi';\nimport { describeError, mutationSucceeded } from '../lib/mutationResult';\nimport { notify } from '../lib/toast';\n\nexport interface EntityTagsFieldProps {\n /** Entity kind, e.g. \"sponsor\", \"event\", \"session\". Namespaces the assignments. */\n entityType: string;\n /** Target row id. When empty (create form) the field prompts to save first. */\n entityId: string;\n label?: string;\n className?: string;\n}\n\n/**\n * Inline tag editor for any EventfullyManaged entity, keyed by\n * `(entityType, entityId)`. Reads current assignments via\n * `eventfullyManagedEntityTags` and renders each chip from the INLINE\n * `tagInfo { label, color }` (never the federated `tag {}` field, which the\n * gateway does not resolve here). Supports attaching an existing workspace tag,\n * minting a brand-new tag, and detaching — each mutation refetches the\n * assignment list so the field stays in sync.\n */\nexport function EntityTagsField({ entityType, entityId, label = 'Tags', className }: EntityTagsFieldProps) {\n const [newLabel, setNewLabel] = useState('');\n const [selectedTagId, setSelectedTagId] = useState('');\n\n const enabled = Boolean(entityId);\n const assignmentsQuery = useEntityTagsQuery({ input: { entityType, entityId } });\n const { data: availableData } = useAvailableTagsQuery({ limit: 100 });\n const [tagEntity, { loading: tagging }] = useTagEntityMutation();\n const [untagEntity, { loading: untagging }] = useUntagEntityMutation();\n const [createTag, { loading: creating }] = useCreateEntityTagMutation();\n\n const assignments = useMemo(\n () => assignmentsQuery.data?.eventfullyManagedEntityTags ?? [],\n [assignmentsQuery.data]\n );\n const assignedTagIds = useMemo(() => new Set(assignments.map((a) => a.tagId)), [assignments]);\n const available = useMemo(\n () => (availableData?.availableEventfullyManagedTags ?? []).filter((tag) => !assignedTagIds.has(tag.id)),\n [availableData, assignedTagIds]\n );\n\n const busy = tagging || untagging || creating;\n\n const attachTag = async (tagId: string) => {\n const response = await tagEntity({ variables: { input: { entityType, entityId, tagId, source: 'manual' } } });\n if (!mutationSucceeded(response, response.data?.tagEventfullyManagedEntity?.id, 'Could not add tag')) {\n return false;\n }\n await assignmentsQuery.refetch();\n return true;\n };\n\n const onAttachExisting = async () => {\n if (!selectedTagId) {\n return;\n }\n try {\n if (await attachTag(selectedTagId)) {\n setSelectedTagId('');\n }\n } catch (error) {\n notify.error('Could not add tag', describeError(error));\n }\n };\n\n const onCreateAndAttach = async () => {\n const trimmed = newLabel.trim();\n if (!trimmed) {\n return;\n }\n try {\n const created = await createTag({ variables: { input: { label: trimmed } } });\n const createdId = created.data?.createEventfullyManagedEntityTag?.id;\n if (!mutationSucceeded(created, createdId, 'Could not create tag') || !createdId) {\n return;\n }\n if (await attachTag(createdId)) {\n setNewLabel('');\n }\n } catch (error) {\n notify.error('Could not create tag', describeError(error));\n }\n };\n\n const onRemove = async (tagId: string) => {\n try {\n const response = await untagEntity({ variables: { input: { entityType, entityId, tagId } } });\n if (response.error) {\n notify.error('Could not remove tag', response.error.message);\n return;\n }\n await assignmentsQuery.refetch();\n } catch (error) {\n notify.error('Could not remove tag', describeError(error));\n }\n };\n\n return (\n <div className={`space-y-2 ${className ?? ''}`}>\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <TagIcon className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <span>{label}</span>\n </div>\n\n {!enabled ? (\n <p className=\"text-sm text-text-secondary\">Save this record first to start adding tags.</p>\n ) : (\n <>\n <div className=\"flex flex-wrap gap-2\" role=\"list\" aria-label={label}>\n {assignments.length === 0 ? (\n <span className=\"text-sm text-text-secondary\">No tags yet.</span>\n ) : (\n assignments.map((assignment) => {\n const info = assignment.tagInfo;\n const color = info?.color ?? undefined;\n return (\n <Badge key={assignment.id} variant=\"secondary\" className=\"gap-1.5\" role=\"listitem\">\n {color ? (\n <span\n className=\"h-2 w-2 rounded-full\"\n style={{ backgroundColor: color }}\n aria-hidden=\"true\"\n />\n ) : null}\n <span>{info?.label ?? info?.key ?? 'Tag'}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(assignment.tagId)}\n disabled={busy}\n aria-label={`Remove ${info?.label ?? 'tag'}`}\n className=\"rounded-full text-text-muted transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus disabled:opacity-50\"\n >\n <X className=\"h-3 w-3\" aria-hidden=\"true\" />\n </button>\n </Badge>\n );\n })\n )}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n {available.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n <Select value={selectedTagId} onValueChange={setSelectedTagId}>\n <SelectTrigger className=\"w-48\" aria-label=\"Choose an existing tag\">\n <SelectValue placeholder=\"Add existing tag\" />\n </SelectTrigger>\n <SelectContent>\n {available.map((tag) => (\n <SelectItem key={tag.id} value={tag.id}>\n {tag.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onAttachExisting} disabled={!selectedTagId || busy}>\n Add\n </Button>\n </div>\n ) : null}\n\n <div className=\"flex items-center gap-2\">\n <Input\n value={newLabel}\n onChange={(event) => setNewLabel(event.target.value)}\n placeholder=\"New tag label\"\n aria-label=\"New tag label\"\n className=\"w-48\"\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n void onCreateAndAttach();\n }\n }}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={onCreateAndAttach} disabled={!newLabel.trim() || busy}>\n <Plus className=\"h-4 w-4\" />\n Create\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EntityTagsField.js","names":[],"sources":["../../../src/eventfullymanaged/components/EntityTagsField.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { Plus, Tag as TagIcon, X } from 'lucide-react';\nimport {\n Badge,\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useAvailableTagsQuery,\n useCreateEntityTagMutation,\n useEntityTagsQuery,\n useTagEntityMutation,\n useUntagEntityMutation,\n} from '../api/eventApi';\nimport { describeError, mutationSucceeded } from '../lib/mutationResult';\nimport { notify } from '../lib/toast';\n\nexport interface EntityTagsFieldProps {\n /** Entity kind, e.g. \"sponsor\", \"event\", \"session\". Namespaces the assignments. */\n entityType: string;\n /** Target row id. When empty (create form) the field prompts to save first. */\n entityId: string;\n label?: string;\n className?: string;\n}\n\n/**\n * Inline tag editor for any EventfullyManaged entity, keyed by\n * `(entityType, entityId)`. Reads current assignments via\n * `eventfullyManagedEntityTags` and renders each chip from the INLINE\n * `tagInfo { label, color }` (never the federated `tag {}` field, which the\n * gateway does not resolve here). Supports attaching an existing workspace tag,\n * minting a brand-new tag, and detaching — each mutation refetches the\n * assignment list so the field stays in sync.\n */\nexport function EntityTagsField({ entityType, entityId, label = 'Tags', className }: EntityTagsFieldProps) {\n const [newLabel, setNewLabel] = useState('');\n const [selectedTagId, setSelectedTagId] = useState('');\n\n const enabled = Boolean(entityId);\n const assignmentsQuery = useEntityTagsQuery({ input: { entityType, entityId } });\n const { data: availableData } = useAvailableTagsQuery({ limit: 100 });\n const [tagEntity, { loading: tagging }] = useTagEntityMutation();\n const [untagEntity, { loading: untagging }] = useUntagEntityMutation();\n const [createTag, { loading: creating }] = useCreateEntityTagMutation();\n\n const assignments = useMemo(() => assignmentsQuery.data?.eventfullyManagedEntityTags ?? [], [assignmentsQuery.data]);\n const assignedTagIds = useMemo(() => new Set(assignments.map((a) => a.tagId)), [assignments]);\n const available = useMemo(\n () => (availableData?.availableEventfullyManagedTags ?? []).filter((tag) => !assignedTagIds.has(tag.id)),\n [availableData, assignedTagIds]\n );\n\n const busy = tagging || untagging || creating;\n\n const attachTag = async (tagId: string) => {\n const response = await tagEntity({ variables: { input: { entityType, entityId, tagId, source: 'manual' } } });\n if (!mutationSucceeded(response, response.data?.tagEventfullyManagedEntity?.id, 'Could not add tag')) {\n return false;\n }\n await assignmentsQuery.refetch();\n return true;\n };\n\n const onAttachExisting = async () => {\n if (!selectedTagId) {\n return;\n }\n try {\n if (await attachTag(selectedTagId)) {\n setSelectedTagId('');\n }\n } catch (error) {\n notify.error('Could not add tag', describeError(error));\n }\n };\n\n const onCreateAndAttach = async () => {\n const trimmed = newLabel.trim();\n if (!trimmed) {\n return;\n }\n try {\n const created = await createTag({ variables: { input: { label: trimmed } } });\n const createdId = created.data?.createEventfullyManagedEntityTag?.id;\n if (!mutationSucceeded(created, createdId, 'Could not create tag') || !createdId) {\n return;\n }\n if (await attachTag(createdId)) {\n setNewLabel('');\n }\n } catch (error) {\n notify.error('Could not create tag', describeError(error));\n }\n };\n\n const onRemove = async (tagId: string) => {\n try {\n const response = await untagEntity({ variables: { input: { entityType, entityId, tagId } } });\n if (response.error) {\n notify.error('Could not remove tag', response.error.message);\n return;\n }\n await assignmentsQuery.refetch();\n } catch (error) {\n notify.error('Could not remove tag', describeError(error));\n }\n };\n\n return (\n <div className={`space-y-2 ${className ?? ''}`}>\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <TagIcon className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <span>{label}</span>\n </div>\n\n {!enabled ? (\n <p className=\"text-sm text-text-secondary\">Save this record first to start adding tags.</p>\n ) : (\n <>\n <div className=\"flex flex-wrap gap-2\" role=\"list\" aria-label={label}>\n {assignments.length === 0 ? (\n <span className=\"text-sm text-text-secondary\">No tags yet.</span>\n ) : (\n assignments.map((assignment) => {\n const info = assignment.tagInfo;\n const color = info?.color ?? undefined;\n return (\n <Badge key={assignment.id} variant=\"secondary\" className=\"gap-1.5\" role=\"listitem\">\n {color ? (\n <span className=\"h-2 w-2 rounded-full\" style={{ backgroundColor: color }} aria-hidden=\"true\" />\n ) : null}\n <span>{info?.label ?? info?.key ?? 'Tag'}</span>\n <button\n type=\"button\"\n onClick={() => onRemove(assignment.tagId)}\n disabled={busy}\n aria-label={`Remove ${info?.label ?? 'tag'}`}\n className=\"rounded-full text-text-muted transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border-focus disabled:opacity-50\"\n >\n <X className=\"h-3 w-3\" aria-hidden=\"true\" />\n </button>\n </Badge>\n );\n })\n )}\n </div>\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n {available.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n <Select value={selectedTagId} onValueChange={setSelectedTagId}>\n <SelectTrigger className=\"w-48\" aria-label=\"Choose an existing tag\">\n <SelectValue placeholder=\"Add existing tag\" />\n </SelectTrigger>\n <SelectContent>\n {available.map((tag) => (\n <SelectItem key={tag.id} value={tag.id}>\n {tag.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onAttachExisting}\n disabled={!selectedTagId || busy}\n >\n Add\n </Button>\n </div>\n ) : null}\n\n <div className=\"flex items-center gap-2\">\n <Input\n value={newLabel}\n onChange={(event) => setNewLabel(event.target.value)}\n placeholder=\"New tag label\"\n aria-label=\"New tag label\"\n className=\"w-48\"\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n void onCreateAndAttach();\n }\n }}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={onCreateAndAttach}\n disabled={!newLabel.trim() || busy}\n >\n <Plus className=\"h-4 w-4\" />\n Create\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAyCA,SAAgB,EAAgB,EAAE,eAAY,aAAU,WAAQ,QAAQ,gBAAmC;CACzG,IAAM,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAe,KAAoB,EAAS,GAAG,EAEhD,IAAU,EAAQ,GAClB,IAAmB,EAAmB,EAAE,OAAO;EAAE;EAAY;EAAU,EAAE,CAAC,EAC1E,EAAE,MAAM,MAAkB,EAAsB,EAAE,OAAO,KAAK,CAAC,EAC/D,CAAC,GAAW,EAAE,SAAS,OAAa,GAAsB,EAC1D,CAAC,GAAa,EAAE,SAAS,OAAe,GAAwB,EAChE,CAAC,GAAW,EAAE,SAAS,OAAc,GAA4B,EAEjE,IAAc,QAAc,EAAiB,MAAM,+BAA+B,EAAE,EAAE,CAAC,EAAiB,KAAK,CAAC,EAC9G,IAAiB,QAAc,IAAI,IAAI,EAAY,KAAK,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAY,CAAC,EACvF,IAAY,SACT,GAAe,kCAAkC,EAAE,EAAE,QAAQ,MAAQ,CAAC,EAAe,IAAI,EAAI,GAAG,CAAC,EACxG,CAAC,GAAe,EAAe,CAChC,EAEK,IAAO,KAAW,KAAa,GAE/B,IAAY,OAAO,MAAkB;EACzC,IAAM,IAAW,MAAM,EAAU,EAAE,WAAW,EAAE,OAAO;GAAE;GAAY;GAAU;GAAO,QAAQ;GAAU,EAAE,EAAE,CAAC;AAK7G,SAJK,EAAkB,GAAU,EAAS,MAAM,4BAA4B,IAAI,oBAAoB,IAGpG,MAAM,EAAiB,SAAS,EACzB,MAHE;IAML,IAAmB,YAAY;AAC9B,QAGL,KAAI;AACF,GAAI,MAAM,EAAU,EAAc,IAChC,EAAiB,GAAG;WAEf,GAAO;AACd,KAAO,MAAM,qBAAqB,EAAc,EAAM,CAAC;;IAIrD,IAAoB,YAAY;EACpC,IAAM,IAAU,EAAS,MAAM;AAC1B,QAGL,KAAI;GACF,IAAM,IAAU,MAAM,EAAU,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,GAAS,EAAE,EAAE,CAAC,EACvE,IAAY,EAAQ,MAAM,kCAAkC;AAClE,OAAI,CAAC,EAAkB,GAAS,GAAW,uBAAuB,IAAI,CAAC,EACrE;AAEF,GAAI,MAAM,EAAU,EAAU,IAC5B,EAAY,GAAG;WAEV,GAAO;AACd,KAAO,MAAM,wBAAwB,EAAc,EAAM,CAAC;;IAIxD,IAAW,OAAO,MAAkB;AACxC,MAAI;GACF,IAAM,IAAW,MAAM,EAAY,EAAE,WAAW,EAAE,OAAO;IAAE;IAAY;IAAU;IAAO,EAAE,EAAE,CAAC;AAC7F,OAAI,EAAS,OAAO;AAClB,MAAO,MAAM,wBAAwB,EAAS,MAAM,QAAQ;AAC5D;;AAEF,SAAM,EAAiB,SAAS;WACzB,GAAO;AACd,KAAO,MAAM,wBAAwB,EAAc,EAAM,CAAC;;;AAI9D,QACE,kBAAC,OAAD;EAAK,WAAW,aAAa,KAAa;YAA1C,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAS,WAAU;IAA0B,eAAY;IAAS,CAAA,EAClE,kBAAC,QAAD,EAAA,UAAO,GAAa,CAAA,CAChB;MAEJ,IAGA,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;GAAK,WAAU;GAAuB,MAAK;GAAO,cAAY;aAC3D,EAAY,WAAW,IACtB,kBAAC,QAAD;IAAM,WAAU;cAA8B;IAAmB,CAAA,GAEjE,EAAY,KAAK,MAAe;IAC9B,IAAM,IAAO,EAAW,SAClB,IAAQ,GAAM,SAAS,KAAA;AAC7B,WACE,kBAAC,GAAD;KAA2B,SAAQ;KAAY,WAAU;KAAU,MAAK;eAAxE;MACG,IACC,kBAAC,QAAD;OAAM,WAAU;OAAuB,OAAO,EAAE,iBAAiB,GAAO;OAAE,eAAY;OAAS,CAAA,GAC7F;MACJ,kBAAC,QAAD,EAAA,UAAO,GAAM,SAAS,GAAM,OAAO,OAAa,CAAA;MAChD,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,EAAW,MAAM;OACzC,UAAU;OACV,cAAY,UAAU,GAAM,SAAS;OACrC,WAAU;iBAEV,kBAAC,GAAD;QAAG,WAAU;QAAU,eAAY;QAAS,CAAA;OACrC,CAAA;MACH;OAdI,EAAW,GAcf;KAEV;GAEA,CAAA,EAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAU,SAAS,IAClB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAQ,OAAO;KAAe,eAAe;eAA7C,CACE,kBAAC,GAAD;MAAe,WAAU;MAAO,cAAW;gBACzC,kBAAC,GAAD,EAAa,aAAY,oBAAqB,CAAA;MAChC,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAU,KAAK,MACd,kBAAC,GAAD;MAAyB,OAAO,EAAI;gBACjC,EAAI;MACM,EAFI,EAAI,GAER,CACb,EACY,CAAA,CACT;QACT,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,SAAS;KACT,UAAU,CAAC,KAAiB;eAC7B;KAEQ,CAAA,CACL;QACJ,MAEJ,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,OAAO;KACP,WAAW,MAAU,EAAY,EAAM,OAAO,MAAM;KACpD,aAAY;KACZ,cAAW;KACX,WAAU;KACV,YAAY,MAAU;AACpB,MAAI,EAAM,QAAQ,YAChB,EAAM,gBAAgB,EACjB,GAAmB;;KAG5B,CAAA,EACF,kBAAC,GAAD;KACE,MAAK;KACL,SAAQ;KACR,MAAK;KACL,SAAS;KACT,UAAU,CAAC,EAAS,MAAM,IAAI;eALhC,CAOE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,SAErB;OACL;MACF;KACL,EAAA,CAAA,GApFH,kBAAC,KAAD;GAAG,WAAU;aAA8B;GAAgD,CAAA,CAsFzF"}
@@ -1 +1 @@
1
- {"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventDetailPage.tsx"],"sourcesContent":["import {\n ArrowLeft,\n CalendarClock,\n Edit,\n MapPin,\n Plus,\n Ticket as TicketIcon,\n Users,\n} 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 {[\n session.track,\n session.startsAt ? formatDateTime(session.startsAt) : undefined,\n ]\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 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 +1 @@
1
- {"version":3,"file":"EventFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport {\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { useCreateEventMutation, useEventQuery, useUpdateEventMutation, useVenuesQuery } from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\nimport {\n EVENT_STATUS_OPTIONS,\n EVENT_TYPE_OPTIONS,\n EVENT_VISIBILITY_OPTIONS,\n inputValueToIso,\n isoToInputValue,\n} from './eventFormUtils';\n\nconst VENUE_METADATA_KEY = 'venueId';\n\ntype EventFormState = {\n name: string;\n description: string;\n type: string;\n status: string;\n visibility: string;\n timezone: string;\n startAt: string;\n endAt: string;\n venueId: string;\n capacity: string;\n};\n\nfunction defaultState(): EventFormState {\n const now = new Date();\n const later = new Date(now.getTime() + 2 * 60 * 60 * 1000);\n return {\n name: '',\n description: '',\n type: 'IN_PERSON',\n status: 'DRAFT',\n visibility: 'private',\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'Asia/Kolkata',\n startAt: isoToInputValue(now.toISOString()),\n endAt: isoToInputValue(later.toISOString()),\n venueId: '',\n capacity: '100',\n };\n}\n\nexport default function EventFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data } = useEventQuery(id);\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const [createEvent, { loading: creating }] = useCreateEventMutation();\n const [updateEvent, { loading: updating }] = useUpdateEventMutation();\n const [form, setForm] = useState<EventFormState>(defaultState);\n\n useEffect(() => {\n const event = data?.event;\n if (!isEdit || !event) {\n return;\n }\n const metadata = (event.metadata ?? {}) as Record<string, unknown>;\n setForm({\n name: event.name ?? '',\n description: event.description ?? '',\n type: event.type ?? 'IN_PERSON',\n status: event.status ?? 'DRAFT',\n visibility: event.visibility ?? 'private',\n timezone: event.timezone ?? 'Asia/Kolkata',\n startAt: isoToInputValue(event.startAt),\n endAt: isoToInputValue(event.endAt),\n venueId: typeof metadata[VENUE_METADATA_KEY] === 'string' ? (metadata[VENUE_METADATA_KEY] as string) : '',\n capacity: event.capacity != null ? String(event.capacity) : '',\n });\n }, [data, isEdit]);\n\n const venues = venuesData?.venues?.items ?? [];\n\n const onChange = (field: keyof EventFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.name.trim()) {\n notify.error('Name required', 'Give the event a name before saving.');\n return;\n }\n const startIso = inputValueToIso(form.startAt);\n const endIso = inputValueToIso(form.endAt);\n if (!startIso || !endIso) {\n notify.error('Dates required', 'Set both a start and an end time.');\n return;\n }\n if (new Date(endIso).getTime() < new Date(startIso).getTime()) {\n notify.error('Invalid dates', 'The end time cannot be before the start time.');\n return;\n }\n\n const existingMetadata = (data?.event?.metadata ?? {}) as Record<string, unknown>;\n const input = {\n name: form.name.trim(),\n description: form.description,\n type: form.type,\n status: form.status,\n visibility: form.visibility,\n timezone: form.timezone,\n startAt: startIso,\n endAt: endIso,\n capacity: form.capacity ? Number(form.capacity) : null,\n metadata: { ...existingMetadata, [VENUE_METADATA_KEY]: form.venueId || null },\n };\n\n try {\n if (isEdit) {\n const response = await updateEvent({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateEvent?.id, 'Could not update event')) {\n return;\n }\n notify.success('Event updated');\n navigate(`/events/${id}`);\n return;\n }\n const response = await createEvent({ variables: { input } });\n const createdId = response.data?.createEvent?.id;\n if (!mutationSucceeded(response, createdId, 'Could not create event')) {\n return;\n }\n notify.success('Event created');\n navigate(`/events/${createdId}`);\n } catch (error) {\n notify.error('Could not save event', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Event' : 'Create Event'}\n description=\"Define the event people register for and attend.\"\n purpose=\"An event is the thing you sell tickets to and run on the day. Set its name, when it happens and where, then publish it so ticket types and registrations can open. Capacity caps how many attendees you can admit across all ticket types.\"\n backLabel={isEdit ? 'Back to Event' : 'Back to Events'}\n onBack={() => navigate(isEdit ? `/events/${id}` : '/events')}\n onSubmit={onSubmit}\n submitLabel=\"Save Event\"\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Capacity</span>\n <Input\n type=\"number\"\n min=\"0\"\n value={form.capacity}\n onChange={(e) => onChange('capacity', e.target.value)}\n />\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Description</span>\n <Textarea value={form.description} onChange={(e) => onChange('description', e.target.value)} rows={3} />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Start</span>\n <Input\n type=\"datetime-local\"\n value={form.startAt}\n onChange={(e) => onChange('startAt', e.target.value)}\n required\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">End</span>\n <Input\n type=\"datetime-local\"\n value={form.endAt}\n onChange={(e) => onChange('endAt', e.target.value)}\n required\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Venue</span>\n <Select value={form.venueId || 'none'} onValueChange={(value) => onChange('venueId', value === 'none' ? '' : value)}>\n <SelectTrigger aria-label=\"Venue\">\n <SelectValue placeholder=\"Select a venue\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No venue</SelectItem>\n {venues.map((venue: { id: string; name: string }) => (\n <SelectItem key={venue.id} value={venue.id}>\n {venue.name}\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\">Timezone</span>\n <Input value={form.timezone} onChange={(e) => onChange('timezone', e.target.value)} />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\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=\"Type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Visibility</span>\n <Select value={form.visibility} onValueChange={(value) => onChange('visibility', value)}>\n <SelectTrigger aria-label=\"Visibility\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_VISIBILITY_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Textarea } from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { useCreateEventMutation, useEventQuery, useUpdateEventMutation, useVenuesQuery } from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\nimport {\n EVENT_STATUS_OPTIONS,\n EVENT_TYPE_OPTIONS,\n EVENT_VISIBILITY_OPTIONS,\n inputValueToIso,\n isoToInputValue,\n} from './eventFormUtils';\n\nconst VENUE_METADATA_KEY = 'venueId';\n\ntype EventFormState = {\n name: string;\n description: string;\n type: string;\n status: string;\n visibility: string;\n timezone: string;\n startAt: string;\n endAt: string;\n venueId: string;\n capacity: string;\n};\n\nfunction defaultState(): EventFormState {\n const now = new Date();\n const later = new Date(now.getTime() + 2 * 60 * 60 * 1000);\n return {\n name: '',\n description: '',\n type: 'IN_PERSON',\n status: 'DRAFT',\n visibility: 'private',\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'Asia/Kolkata',\n startAt: isoToInputValue(now.toISOString()),\n endAt: isoToInputValue(later.toISOString()),\n venueId: '',\n capacity: '100',\n };\n}\n\nexport default function EventFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data } = useEventQuery(id);\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const [createEvent, { loading: creating }] = useCreateEventMutation();\n const [updateEvent, { loading: updating }] = useUpdateEventMutation();\n const [form, setForm] = useState<EventFormState>(defaultState);\n\n useEffect(() => {\n const event = data?.event;\n if (!isEdit || !event) {\n return;\n }\n const metadata = (event.metadata ?? {}) as Record<string, unknown>;\n setForm({\n name: event.name ?? '',\n description: event.description ?? '',\n type: event.type ?? 'IN_PERSON',\n status: event.status ?? 'DRAFT',\n visibility: event.visibility ?? 'private',\n timezone: event.timezone ?? 'Asia/Kolkata',\n startAt: isoToInputValue(event.startAt),\n endAt: isoToInputValue(event.endAt),\n venueId: typeof metadata[VENUE_METADATA_KEY] === 'string' ? (metadata[VENUE_METADATA_KEY] as string) : '',\n capacity: event.capacity != null ? String(event.capacity) : '',\n });\n }, [data, isEdit]);\n\n const venues = venuesData?.venues?.items ?? [];\n\n const onChange = (field: keyof EventFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.name.trim()) {\n notify.error('Name required', 'Give the event a name before saving.');\n return;\n }\n const startIso = inputValueToIso(form.startAt);\n const endIso = inputValueToIso(form.endAt);\n if (!startIso || !endIso) {\n notify.error('Dates required', 'Set both a start and an end time.');\n return;\n }\n if (new Date(endIso).getTime() < new Date(startIso).getTime()) {\n notify.error('Invalid dates', 'The end time cannot be before the start time.');\n return;\n }\n\n const existingMetadata = (data?.event?.metadata ?? {}) as Record<string, unknown>;\n const input = {\n name: form.name.trim(),\n description: form.description,\n type: form.type,\n status: form.status,\n visibility: form.visibility,\n timezone: form.timezone,\n startAt: startIso,\n endAt: endIso,\n capacity: form.capacity ? Number(form.capacity) : null,\n metadata: { ...existingMetadata, [VENUE_METADATA_KEY]: form.venueId || null },\n };\n\n try {\n if (isEdit) {\n const response = await updateEvent({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateEvent?.id, 'Could not update event')) {\n return;\n }\n notify.success('Event updated');\n navigate(`/events/${id}`);\n return;\n }\n const response = await createEvent({ variables: { input } });\n const createdId = response.data?.createEvent?.id;\n if (!mutationSucceeded(response, createdId, 'Could not create event')) {\n return;\n }\n notify.success('Event created');\n navigate(`/events/${createdId}`);\n } catch (error) {\n notify.error('Could not save event', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Event' : 'Create Event'}\n description=\"Define the event people register for and attend.\"\n purpose=\"An event is the thing you sell tickets to and run on the day. Set its name, when it happens and where, then publish it so ticket types and registrations can open. Capacity caps how many attendees you can admit across all ticket types.\"\n backLabel={isEdit ? 'Back to Event' : 'Back to Events'}\n onBack={() => navigate(isEdit ? `/events/${id}` : '/events')}\n onSubmit={onSubmit}\n submitLabel=\"Save Event\"\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Capacity</span>\n <Input type=\"number\" min=\"0\" value={form.capacity} onChange={(e) => onChange('capacity', e.target.value)} />\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Description</span>\n <Textarea value={form.description} onChange={(e) => onChange('description', e.target.value)} rows={3} />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Start</span>\n <Input\n type=\"datetime-local\"\n value={form.startAt}\n onChange={(e) => onChange('startAt', e.target.value)}\n required\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">End</span>\n <Input\n type=\"datetime-local\"\n value={form.endAt}\n onChange={(e) => onChange('endAt', e.target.value)}\n required\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Venue</span>\n <Select\n value={form.venueId || 'none'}\n onValueChange={(value) => onChange('venueId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Venue\">\n <SelectValue placeholder=\"Select a venue\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No venue</SelectItem>\n {venues.map((venue: { id: string; name: string }) => (\n <SelectItem key={venue.id} value={venue.id}>\n {venue.name}\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\">Timezone</span>\n <Input value={form.timezone} onChange={(e) => onChange('timezone', e.target.value)} />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\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=\"Type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Visibility</span>\n <Select value={form.visibility} onValueChange={(value) => onChange('visibility', value)}>\n <SelectTrigger aria-label=\"Visibility\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {EVENT_VISIBILITY_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n </EntityFormShell>\n );\n}\n"],"mappings":";;;;;;;;;;;AAkBA,IAAM,IAAqB;AAe3B,SAAS,IAA+B;CACtC,IAAM,oBAAM,IAAI,MAAM,EAChB,IAAQ,IAAI,KAAK,EAAI,SAAS,GAAG,OAAc,IAAK;AAC1D,QAAO;EACL,MAAM;EACN,aAAa;EACb,MAAM;EACN,QAAQ;EACR,YAAY;EACZ,UAAU,KAAK,gBAAgB,CAAC,iBAAiB,CAAC,YAAY;EAC9D,SAAS,EAAgB,EAAI,aAAa,CAAC;EAC3C,OAAO,EAAgB,EAAM,aAAa,CAAC;EAC3C,SAAS;EACT,UAAU;EACX;;AAGH,SAAwB,IAAgB;CACtC,IAAM,EAAE,QAAK,OAAO,GAA2B,EACzC,IAAS,QAAc,EAAQ,GAAK,CAAC,EAAG,CAAC,EACzC,EAAE,gBAAa,GAAsB,EAErC,EAAE,YAAS,EAAc,EAAG,EAC5B,EAAE,MAAM,MAAe,EAAe;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAChE,CAAC,GAAa,EAAE,SAAS,OAAc,GAAwB,EAC/D,CAAC,GAAa,EAAE,SAAS,OAAc,GAAwB,EAC/D,CAAC,GAAM,KAAW,EAAyB,EAAa;AAE9D,SAAgB;EACd,IAAM,IAAQ,GAAM;AACpB,MAAI,CAAC,KAAU,CAAC,EACd;EAEF,IAAM,IAAY,EAAM,YAAY,EAAE;AACtC,IAAQ;GACN,MAAM,EAAM,QAAQ;GACpB,aAAa,EAAM,eAAe;GAClC,MAAM,EAAM,QAAQ;GACpB,QAAQ,EAAM,UAAU;GACxB,YAAY,EAAM,cAAc;GAChC,UAAU,EAAM,YAAY;GAC5B,SAAS,EAAgB,EAAM,QAAQ;GACvC,OAAO,EAAgB,EAAM,MAAM;GACnC,SAAS,OAAO,EAAS,MAAwB,WAAY,EAAS,KAAiC;GACvG,UAAU,EAAM,YAAY,OAAgC,KAAzB,OAAO,EAAM,SAAS;GAC1D,CAAC;IACD,CAAC,GAAM,EAAO,CAAC;CAElB,IAAM,IAAS,GAAY,QAAQ,SAAS,EAAE,EAExC,KAAY,GAA6B,MAAkB;AAC/D,KAAS,OAAU;GAAE,GAAG;IAAO,IAAQ;GAAO,EAAE;;AA2DlD,QACE,kBAAC,GAAD;EACE,OAAO,IAAS,eAAe;EAC/B,aAAY;EACZ,SAAQ;EACR,WAAW,IAAS,kBAAkB;EACtC,cAAc,EAAS,IAAS,WAAW,MAAO,UAAU;EAClD,UA/DG,OAAO,MAA4C;AAGlE,OAFA,EAAM,gBAAgB,EAElB,CAAC,EAAK,KAAK,MAAM,EAAE;AACrB,MAAO,MAAM,iBAAiB,uCAAuC;AACrE;;GAEF,IAAM,IAAW,EAAgB,EAAK,QAAQ,EACxC,IAAS,EAAgB,EAAK,MAAM;AAC1C,OAAI,CAAC,KAAY,CAAC,GAAQ;AACxB,MAAO,MAAM,kBAAkB,oCAAoC;AACnE;;AAEF,OAAI,IAAI,KAAK,EAAO,CAAC,SAAS,GAAG,IAAI,KAAK,EAAS,CAAC,SAAS,EAAE;AAC7D,MAAO,MAAM,iBAAiB,gDAAgD;AAC9E;;GAGF,IAAM,IAAoB,GAAM,OAAO,YAAY,EAAE,EAC/C,IAAQ;IACZ,MAAM,EAAK,KAAK,MAAM;IACtB,aAAa,EAAK;IAClB,MAAM,EAAK;IACX,QAAQ,EAAK;IACb,YAAY,EAAK;IACjB,UAAU,EAAK;IACf,SAAS;IACT,OAAO;IACP,UAAU,EAAK,WAAW,OAAO,EAAK,SAAS,GAAG;IAClD,UAAU;KAAE,GAAG;MAAmB,IAAqB,EAAK,WAAW;KAAM;IAC9E;AAED,OAAI;AACF,QAAI,GAAQ;KACV,IAAM,IAAW,MAAM,EAAY,EAAE,WAAW;MAAE;MAAI;MAAO,EAAE,CAAC;AAChE,SAAI,CAAC,EAAkB,GAAU,EAAS,MAAM,aAAa,IAAI,yBAAyB,CACxF;AAGF,KADA,EAAO,QAAQ,gBAAgB,EAC/B,EAAS,WAAW,IAAK;AACzB;;IAEF,IAAM,IAAW,MAAM,EAAY,EAAE,WAAW,EAAE,UAAO,EAAE,CAAC,EACtD,IAAY,EAAS,MAAM,aAAa;AAC9C,QAAI,CAAC,EAAkB,GAAU,GAAW,yBAAyB,CACnE;AAGF,IADA,EAAO,QAAQ,gBAAgB,EAC/B,EAAS,WAAW,IAAY;YACzB,GAAO;AACd,MAAO,MAAM,wBAAwB,EAAc,EAAM,CAAC;;;EAc1D,aAAY;EACJ,QAXG,KAAY;YAGzB;GAUE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAW,CAAA,EAC3D,kBAAC,GAAD;MAAO,OAAO,EAAK;MAAM,WAAW,MAAM,EAAS,QAAQ,EAAE,OAAO,MAAM;MAAE,UAAA;MAAW,CAAA,CACjF;QACR,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAe,CAAA,EAC/D,kBAAC,GAAD;MAAO,MAAK;MAAS,KAAI;MAAI,OAAO,EAAK;MAAU,WAAW,MAAM,EAAS,YAAY,EAAE,OAAO,MAAM;MAAI,CAAA,CACtG;OACJ;;GAEN,kBAAC,SAAD;IAAO,WAAU;cAAjB,CACE,kBAAC,QAAD;KAAM,WAAU;eAAgC;KAAkB,CAAA,EAClE,kBAAC,GAAD;KAAU,OAAO,EAAK;KAAa,WAAW,MAAM,EAAS,eAAe,EAAE,OAAO,MAAM;KAAE,MAAM;KAAK,CAAA,CAClG;;GAER,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAY,CAAA,EAC5D,kBAAC,GAAD;MACE,MAAK;MACL,OAAO,EAAK;MACZ,WAAW,MAAM,EAAS,WAAW,EAAE,OAAO,MAAM;MACpD,UAAA;MACA,CAAA,CACI;QACR,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAU,CAAA,EAC1D,kBAAC,GAAD;MACE,MAAK;MACL,OAAO,EAAK;MACZ,WAAW,MAAM,EAAS,SAAS,EAAE,OAAO,MAAM;MAClD,UAAA;MACA,CAAA,CACI;OACJ;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAY,CAAA,EAC5D,kBAAC,GAAD;MACE,OAAO,EAAK,WAAW;MACvB,gBAAgB,MAAU,EAAS,WAAW,MAAU,SAAS,KAAK,EAAM;gBAF9E,CAIE,kBAAC,GAAD;OAAe,cAAW;iBACxB,kBAAC,GAAD,EAAa,aAAY,kBAAmB,CAAA;OAC9B,CAAA,EAChB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;OAAY,OAAM;iBAAO;OAAqB,CAAA,EAC7C,EAAO,KAAK,MACX,kBAAC,GAAD;OAA2B,OAAO,EAAM;iBACrC,EAAM;OACI,EAFI,EAAM,GAEV,CACb,CACY,EAAA,CAAA,CACT;QACH;QACR,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAgC;MAAe,CAAA,EAC/D,kBAAC,GAAD;MAAO,OAAO,EAAK;MAAU,WAAW,MAAM,EAAS,YAAY,EAAE,OAAO,MAAM;MAAI,CAAA,CAChF;OACJ;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAgC;OAAW,CAAA,EAC3D,kBAAC,GAAD;OAAQ,OAAO,EAAK;OAAM,gBAAgB,MAAU,EAAS,QAAQ,EAAM;iBAA3E,CACE,kBAAC,GAAD;QAAe,cAAW;kBACxB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAmB,KAAK,MACvB,kBAAC,GAAD;QAA+B,OAAO,EAAO;kBAC1C,EAAO;QACG,EAFI,EAAO,MAEX,CACb,EACY,CAAA,CACT;SACH;;KACR,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAgC;OAAa,CAAA,EAC7D,kBAAC,GAAD;OAAQ,OAAO,EAAK;OAAQ,gBAAgB,MAAU,EAAS,UAAU,EAAM;iBAA/E,CACE,kBAAC,GAAD;QAAe,cAAW;kBACxB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAqB,KAAK,MACzB,kBAAC,GAAD;QAA+B,OAAO,EAAO;kBAC1C,EAAO;QACG,EAFI,EAAO,MAEX,CACb,EACY,CAAA,CACT;SACH;;KACR,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAgC;OAAiB,CAAA,EACjE,kBAAC,GAAD;OAAQ,OAAO,EAAK;OAAY,gBAAgB,MAAU,EAAS,cAAc,EAAM;iBAAvF,CACE,kBAAC,GAAD;QAAe,cAAW;kBACxB,kBAAC,GAAD,EAAe,CAAA;QACD,CAAA,EAChB,kBAAC,GAAD,EAAA,UACG,EAAyB,KAAK,MAC7B,kBAAC,GAAD;QAA+B,OAAO,EAAO;kBAC1C,EAAO;QACG,EAFI,EAAO,MAEX,CACb,EACY,CAAA,CACT;SACH;;KACJ;;GACU"}
@@ -1 +1 @@
1
- {"version":3,"file":"SessionFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/SessionFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateEventSessionMutation,\n useEventQuery,\n useSpeakersQuery,\n useUpdateEventSessionMutation,\n useVenuesQuery,\n} from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\nimport {\n inputValueToIso,\n isoToInputValue,\n SESSION_STATUS_OPTIONS,\n SESSION_TYPE_OPTIONS,\n} from './eventFormUtils';\n\nconst SPEAKER_METADATA_KEY = 'speakerId';\n\n// The foundation EVENT_SESSIONS_QUERY omits description/capacity/metadata, but the\n// backend `updateEventSession` resolver is a FULL replace — editing with a partial\n// initial state would blank those columns. There is no by-id session resolver, so\n// this fuller list query is the edit-hydration source: it selects every editable\n// field and the form finds its row by id client-side.\nconst FULL_EVENT_SESSIONS_QUERY = gql`\n query EventfullymanagedSessionFormSessions($eventId: ID, $limit: Int, $offset: Int) {\n eventSessions: eventfullyManagedEventSessions(eventId: $eventId, limit: $limit, offset: $offset) {\n total\n items {\n id\n eventId\n venueId\n title\n description\n sessionType\n track\n startsAt\n endsAt\n capacity\n status\n metadata\n }\n }\n }\n`;\n\ntype FullSessionsResponse = {\n eventSessions: { total: number; items: SessionListItem[] };\n};\n\ntype SessionListItem = {\n id: string;\n eventId: string;\n venueId?: string | null;\n title: string;\n sessionType: string;\n track?: string | null;\n startsAt: string;\n endsAt: string;\n status: string;\n capacity?: number | null;\n description?: string | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype SessionFormState = {\n title: string;\n sessionType: string;\n track: string;\n venueId: string;\n speakerId: string;\n startsAt: string;\n endsAt: string;\n capacity: string;\n status: string;\n description: string;\n};\n\nfunction defaultState(): SessionFormState {\n const now = new Date();\n const later = new Date(now.getTime() + 60 * 60 * 1000);\n return {\n title: '',\n sessionType: 'TALK',\n track: '',\n venueId: '',\n speakerId: '',\n startsAt: isoToInputValue(now.toISOString()),\n endsAt: isoToInputValue(later.toISOString()),\n capacity: '',\n status: 'SCHEDULED',\n description: '',\n };\n}\n\nexport default function SessionFormPage() {\n const { id = '', sid = '' } = useParams<{ id: string; sid: string }>();\n const isEdit = useMemo(() => Boolean(sid), [sid]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventData } = useEventQuery(id);\n // No by-id session resolver — derive the edit initial state from the (fuller) list query.\n const { data: sessionsData } = useQuery<FullSessionsResponse, { eventId?: string; limit?: number; offset?: number }>(\n FULL_EVENT_SESSIONS_QUERY,\n { variables: { eventId: id, limit: 100, offset: 0 }, skip: !sid }\n );\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const { data: speakersData } = useSpeakersQuery({ limit: 100, offset: 0 });\n const [createSession, { loading: creating }] = useCreateEventSessionMutation();\n const [updateSession, { loading: updating }] = useUpdateEventSessionMutation();\n const [form, setForm] = useState<SessionFormState>(defaultState);\n\n const existingSession = useMemo(\n () => (sessionsData?.eventSessions?.items ?? []).find((item) => item.id === sid),\n [sessionsData, sid]\n );\n\n useEffect(() => {\n if (!isEdit || !existingSession) {\n return;\n }\n const metadata = (existingSession.metadata ?? {}) as Record<string, unknown>;\n setForm({\n title: existingSession.title ?? '',\n sessionType: existingSession.sessionType ?? 'TALK',\n track: existingSession.track ?? '',\n venueId: existingSession.venueId ?? '',\n speakerId: typeof metadata[SPEAKER_METADATA_KEY] === 'string' ? (metadata[SPEAKER_METADATA_KEY] as string) : '',\n startsAt: isoToInputValue(existingSession.startsAt),\n endsAt: isoToInputValue(existingSession.endsAt),\n capacity: existingSession.capacity != null ? String(existingSession.capacity) : '',\n status: existingSession.status ?? 'SCHEDULED',\n description: existingSession.description ?? '',\n });\n }, [existingSession, isEdit]);\n\n const venues = venuesData?.venues?.items ?? [];\n const speakers = (speakersData?.speakers?.items ?? []) as Array<{ id: string; fullName: string }>;\n const eventName = eventData?.event?.name ?? 'Event';\n\n const onChange = (field: keyof SessionFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.title.trim()) {\n notify.error('Title required', 'Give the session a title before saving.');\n return;\n }\n const startIso = inputValueToIso(form.startsAt);\n const endIso = inputValueToIso(form.endsAt);\n if (!startIso || !endIso) {\n notify.error('Times required', 'Set both a start and an end time.');\n return;\n }\n if (new Date(endIso).getTime() < new Date(startIso).getTime()) {\n notify.error('Invalid times', 'The end time cannot be before the start time.');\n return;\n }\n\n const existingMetadata = (existingSession?.metadata ?? {}) as Record<string, unknown>;\n const input = {\n eventId: id,\n title: form.title.trim(),\n sessionType: form.sessionType,\n track: form.track || null,\n venueId: form.venueId || null,\n startsAt: startIso,\n endsAt: endIso,\n capacity: form.capacity ? Number(form.capacity) : null,\n status: form.status,\n description: form.description || null,\n metadata: { ...existingMetadata, [SPEAKER_METADATA_KEY]: form.speakerId || null },\n };\n\n try {\n if (isEdit) {\n const response = await updateSession({ variables: { id: sid, input } });\n if (!mutationSucceeded(response, response.data?.updateEventSession?.id, 'Could not update session')) {\n return;\n }\n notify.success('Session updated');\n navigate(`/events/${id}`);\n return;\n }\n const response = await createSession({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createEventSession?.id, 'Could not create session')) {\n return;\n }\n notify.success('Session created');\n navigate(`/events/${id}`);\n } catch (error) {\n notify.error('Could not save session', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Session' : 'Add Session'}\n description={`Agenda item for ${eventName}.`}\n purpose=\"Sessions make up the agenda attendees follow on the day — a talk, workshop or panel with a time, a room and a speaker. Set the slot and assign a room so two sessions never clash, and pick the speaker who will present it.\"\n backLabel=\"Back to Event\"\n onBack={() => navigate(`/events/${id}`)}\n onSubmit={onSubmit}\n submitLabel=\"Save Session\"\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Title</span>\n <Input value={form.title} onChange={(e) => onChange('title', e.target.value)} required />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Track</span>\n <Input\n value={form.track}\n onChange={(e) => onChange('track', e.target.value)}\n placeholder=\"Main stage, Product, Engineering…\"\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Room / Venue</span>\n <Select\n value={form.venueId || 'none'}\n onValueChange={(value) => onChange('venueId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Room or venue\">\n <SelectValue placeholder=\"Select a room\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No room</SelectItem>\n {venues.map((venue: { id: string; name: string }) => (\n <SelectItem key={venue.id} value={venue.id}>\n {venue.name}\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\">Speaker</span>\n <Select\n value={form.speakerId || 'none'}\n onValueChange={(value) => onChange('speakerId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Speaker\">\n <SelectValue placeholder=\"Select a speaker\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No speaker</SelectItem>\n {speakers.map((speaker) => (\n <SelectItem key={speaker.id} value={speaker.id}>\n {speaker.fullName}\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\">Capacity</span>\n <Input\n type=\"number\"\n min=\"0\"\n value={form.capacity}\n onChange={(e) => onChange('capacity', e.target.value)}\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Start</span>\n <Input\n type=\"datetime-local\"\n value={form.startsAt}\n onChange={(e) => onChange('startsAt', e.target.value)}\n required\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">End</span>\n <Input\n type=\"datetime-local\"\n value={form.endsAt}\n onChange={(e) => onChange('endsAt', e.target.value)}\n required\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Type</span>\n <Select value={form.sessionType} onValueChange={(value) => onChange('sessionType', value)}>\n <SelectTrigger aria-label=\"Session type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SESSION_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SESSION_STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Description</span>\n <Textarea value={form.description} onChange={(e) => onChange('description', e.target.value)} rows={3} />\n </label>\n\n {isEdit ? <EntityTagsField entityType=\"session\" entityId={sid} /> : null}\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SessionFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/SessionFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Textarea } from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateEventSessionMutation,\n useEventQuery,\n useSpeakersQuery,\n useUpdateEventSessionMutation,\n useVenuesQuery,\n} from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\nimport { inputValueToIso, isoToInputValue, SESSION_STATUS_OPTIONS, SESSION_TYPE_OPTIONS } from './eventFormUtils';\n\nconst SPEAKER_METADATA_KEY = 'speakerId';\n\n// The foundation EVENT_SESSIONS_QUERY omits description/capacity/metadata, but the\n// backend `updateEventSession` resolver is a FULL replace — editing with a partial\n// initial state would blank those columns. There is no by-id session resolver, so\n// this fuller list query is the edit-hydration source: it selects every editable\n// field and the form finds its row by id client-side.\nconst FULL_EVENT_SESSIONS_QUERY = gql`\n query EventfullymanagedSessionFormSessions($eventId: ID, $limit: Int, $offset: Int) {\n eventSessions: eventfullyManagedEventSessions(eventId: $eventId, limit: $limit, offset: $offset) {\n total\n items {\n id\n eventId\n venueId\n title\n description\n sessionType\n track\n startsAt\n endsAt\n capacity\n status\n metadata\n }\n }\n }\n`;\n\ntype FullSessionsResponse = {\n eventSessions: { total: number; items: SessionListItem[] };\n};\n\ntype SessionListItem = {\n id: string;\n eventId: string;\n venueId?: string | null;\n title: string;\n sessionType: string;\n track?: string | null;\n startsAt: string;\n endsAt: string;\n status: string;\n capacity?: number | null;\n description?: string | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype SessionFormState = {\n title: string;\n sessionType: string;\n track: string;\n venueId: string;\n speakerId: string;\n startsAt: string;\n endsAt: string;\n capacity: string;\n status: string;\n description: string;\n};\n\nfunction defaultState(): SessionFormState {\n const now = new Date();\n const later = new Date(now.getTime() + 60 * 60 * 1000);\n return {\n title: '',\n sessionType: 'TALK',\n track: '',\n venueId: '',\n speakerId: '',\n startsAt: isoToInputValue(now.toISOString()),\n endsAt: isoToInputValue(later.toISOString()),\n capacity: '',\n status: 'SCHEDULED',\n description: '',\n };\n}\n\nexport default function SessionFormPage() {\n const { id = '', sid = '' } = useParams<{ id: string; sid: string }>();\n const isEdit = useMemo(() => Boolean(sid), [sid]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventData } = useEventQuery(id);\n // No by-id session resolver — derive the edit initial state from the (fuller) list query.\n const { data: sessionsData } = useQuery<FullSessionsResponse, { eventId?: string; limit?: number; offset?: number }>(\n FULL_EVENT_SESSIONS_QUERY,\n { variables: { eventId: id, limit: 100, offset: 0 }, skip: !sid }\n );\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const { data: speakersData } = useSpeakersQuery({ limit: 100, offset: 0 });\n const [createSession, { loading: creating }] = useCreateEventSessionMutation();\n const [updateSession, { loading: updating }] = useUpdateEventSessionMutation();\n const [form, setForm] = useState<SessionFormState>(defaultState);\n\n const existingSession = useMemo(\n () => (sessionsData?.eventSessions?.items ?? []).find((item) => item.id === sid),\n [sessionsData, sid]\n );\n\n useEffect(() => {\n if (!isEdit || !existingSession) {\n return;\n }\n const metadata = (existingSession.metadata ?? {}) as Record<string, unknown>;\n setForm({\n title: existingSession.title ?? '',\n sessionType: existingSession.sessionType ?? 'TALK',\n track: existingSession.track ?? '',\n venueId: existingSession.venueId ?? '',\n speakerId: typeof metadata[SPEAKER_METADATA_KEY] === 'string' ? (metadata[SPEAKER_METADATA_KEY] as string) : '',\n startsAt: isoToInputValue(existingSession.startsAt),\n endsAt: isoToInputValue(existingSession.endsAt),\n capacity: existingSession.capacity != null ? String(existingSession.capacity) : '',\n status: existingSession.status ?? 'SCHEDULED',\n description: existingSession.description ?? '',\n });\n }, [existingSession, isEdit]);\n\n const venues = venuesData?.venues?.items ?? [];\n const speakers = (speakersData?.speakers?.items ?? []) as Array<{ id: string; fullName: string }>;\n const eventName = eventData?.event?.name ?? 'Event';\n\n const onChange = (field: keyof SessionFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.title.trim()) {\n notify.error('Title required', 'Give the session a title before saving.');\n return;\n }\n const startIso = inputValueToIso(form.startsAt);\n const endIso = inputValueToIso(form.endsAt);\n if (!startIso || !endIso) {\n notify.error('Times required', 'Set both a start and an end time.');\n return;\n }\n if (new Date(endIso).getTime() < new Date(startIso).getTime()) {\n notify.error('Invalid times', 'The end time cannot be before the start time.');\n return;\n }\n\n const existingMetadata = (existingSession?.metadata ?? {}) as Record<string, unknown>;\n const input = {\n eventId: id,\n title: form.title.trim(),\n sessionType: form.sessionType,\n track: form.track || null,\n venueId: form.venueId || null,\n startsAt: startIso,\n endsAt: endIso,\n capacity: form.capacity ? Number(form.capacity) : null,\n status: form.status,\n description: form.description || null,\n metadata: { ...existingMetadata, [SPEAKER_METADATA_KEY]: form.speakerId || null },\n };\n\n try {\n if (isEdit) {\n const response = await updateSession({ variables: { id: sid, input } });\n if (!mutationSucceeded(response, response.data?.updateEventSession?.id, 'Could not update session')) {\n return;\n }\n notify.success('Session updated');\n navigate(`/events/${id}`);\n return;\n }\n const response = await createSession({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createEventSession?.id, 'Could not create session')) {\n return;\n }\n notify.success('Session created');\n navigate(`/events/${id}`);\n } catch (error) {\n notify.error('Could not save session', describeError(error));\n }\n };\n\n const saving = creating || updating;\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Session' : 'Add Session'}\n description={`Agenda item for ${eventName}.`}\n purpose=\"Sessions make up the agenda attendees follow on the day — a talk, workshop or panel with a time, a room and a speaker. Set the slot and assign a room so two sessions never clash, and pick the speaker who will present it.\"\n backLabel=\"Back to Event\"\n onBack={() => navigate(`/events/${id}`)}\n onSubmit={onSubmit}\n submitLabel=\"Save Session\"\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Title</span>\n <Input value={form.title} onChange={(e) => onChange('title', e.target.value)} required />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Track</span>\n <Input\n value={form.track}\n onChange={(e) => onChange('track', e.target.value)}\n placeholder=\"Main stage, Product, Engineering…\"\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Room / Venue</span>\n <Select\n value={form.venueId || 'none'}\n onValueChange={(value) => onChange('venueId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Room or venue\">\n <SelectValue placeholder=\"Select a room\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No room</SelectItem>\n {venues.map((venue: { id: string; name: string }) => (\n <SelectItem key={venue.id} value={venue.id}>\n {venue.name}\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\">Speaker</span>\n <Select\n value={form.speakerId || 'none'}\n onValueChange={(value) => onChange('speakerId', value === 'none' ? '' : value)}\n >\n <SelectTrigger aria-label=\"Speaker\">\n <SelectValue placeholder=\"Select a speaker\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"none\">No speaker</SelectItem>\n {speakers.map((speaker) => (\n <SelectItem key={speaker.id} value={speaker.id}>\n {speaker.fullName}\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\">Capacity</span>\n <Input type=\"number\" min=\"0\" value={form.capacity} onChange={(e) => onChange('capacity', e.target.value)} />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Start</span>\n <Input\n type=\"datetime-local\"\n value={form.startsAt}\n onChange={(e) => onChange('startsAt', e.target.value)}\n required\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">End</span>\n <Input\n type=\"datetime-local\"\n value={form.endsAt}\n onChange={(e) => onChange('endsAt', e.target.value)}\n required\n />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Type</span>\n <Select value={form.sessionType} onValueChange={(value) => onChange('sessionType', value)}>\n <SelectTrigger aria-label=\"Session type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SESSION_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\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\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SESSION_STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Description</span>\n <Textarea value={form.description} onChange={(e) => onChange('description', e.target.value)} rows={3} />\n </label>\n\n {isEdit ? <EntityTagsField entityType=\"session\" entityId={sid} /> : null}\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ExhibitorFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport {\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateExhibitorMutation,\n useEventsQuery,\n useExhibitorsQuery,\n useUpdateExhibitorMutation,\n} from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { safeUrl } from '../../components/SafeLink';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype ExhibitorFormState = {\n eventId: string;\n name: string;\n boothCode: string;\n category: string;\n status: string;\n website: string;\n contactName: string;\n contactEmail: string;\n};\n\nconst initialState: ExhibitorFormState = {\n eventId: '',\n name: '',\n boothCode: '',\n category: '',\n status: 'CONFIRMED',\n website: '',\n contactName: '',\n contactEmail: '',\n};\n\nconst STATUS_OPTIONS = [\n { value: 'INVITED', label: 'Invited' },\n { value: 'CONFIRMED', label: 'Confirmed' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport default function ExhibitorFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventsData } = useEventsQuery({ limit: 100, offset: 0 });\n // No by-id resolver exists for exhibitors, so the edit initial-state is derived\n // from the list query row.\n const { data: exhibitorsData } = useExhibitorsQuery({ limit: 100, offset: 0 });\n\n const existing = useMemo(\n () => (exhibitorsData?.exhibitors?.items ?? []).find((item) => item.id === id),\n [exhibitorsData, id]\n );\n\n const [createExhibitor, { loading: creating }] = useCreateExhibitorMutation();\n const [updateExhibitor, { loading: updating }] = useUpdateExhibitorMutation();\n const [form, setForm] = useState<ExhibitorFormState>(initialState);\n\n useEffect(() => {\n if (!isEdit || !existing) {\n return;\n }\n const metadata = existing.metadata ?? {};\n const website = typeof metadata.website === 'string' ? metadata.website : '';\n setForm({\n eventId: existing.eventId ?? '',\n name: existing.name ?? '',\n boothCode: existing.boothCode ?? '',\n category: existing.category ?? '',\n status: existing.status ?? 'CONFIRMED',\n website,\n contactName: existing.contactName ?? '',\n contactEmail: existing.contactEmail ?? '',\n });\n }, [existing, isEdit]);\n\n const onChange = (field: keyof ExhibitorFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.eventId) {\n notify.error('Event required', 'Choose the event this exhibitor belongs to.');\n return;\n }\n\n // The website is free text persisted verbatim, so normalise/reject it before\n // it is stored and later rendered as a link.\n const normalizedWebsite = safeUrl(form.website);\n if (form.website.trim() && !normalizedWebsite) {\n notify.error('Invalid website', 'Enter a valid http(s) URL, or leave it blank.');\n return;\n }\n\n const existingMetadata = existing?.metadata ?? {};\n const input = {\n eventId: form.eventId,\n name: form.name,\n boothCode: form.boothCode,\n category: form.category,\n status: form.status,\n contactName: form.contactName,\n contactEmail: form.contactEmail,\n metadata: { ...existingMetadata, website: normalizedWebsite ?? '' },\n };\n\n try {\n if (isEdit) {\n const response = await updateExhibitor({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateExhibitor?.id, 'Could not update exhibitor')) {\n return;\n }\n navigate('/exhibitors');\n return;\n }\n\n const response = await createExhibitor({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createExhibitor?.id, 'Could not create exhibitor')) {\n return;\n }\n navigate('/exhibitors');\n } catch (error) {\n notify.error('Could not save exhibitor', describeError(error));\n }\n };\n\n const saving = creating || updating;\n const events = eventsData?.events?.items ?? [];\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Exhibitor' : 'New Exhibitor'}\n description=\"Manage a booth exhibitor with live backend persistence.\"\n purpose=\"Register a company staffing a booth: link it to the event, give it a booth code and category, and record who to contact. Once saved, capture the leads their booth scans from the exhibitor list.\"\n backLabel=\"Back to Exhibitors\"\n onBack={() => navigate('/exhibitors')}\n onSubmit={onSubmit}\n submitLabel={isEdit ? 'Save Exhibitor' : 'Create Exhibitor'}\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Event</span>\n <Select value={form.eventId} onValueChange={(value) => onChange('eventId', value)}>\n <SelectTrigger aria-label=\"Event\">\n <SelectValue placeholder=\"Select event\" />\n </SelectTrigger>\n <SelectContent>\n {events.map((eventItem) => (\n <SelectItem key={eventItem.id} value={eventItem.id}>\n {eventItem.name}\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\">Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Booth Code</span>\n <Input value={form.boothCode} onChange={(e) => onChange('boothCode', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Category</span>\n <Input value={form.category} onChange={(e) => onChange('category', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Website</span>\n <Input\n value={form.website}\n onChange={(e) => onChange('website', e.target.value)}\n placeholder=\"https://example.com\"\n />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Name</span>\n <Input value={form.contactName} onChange={(e) => onChange('contactName', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Email</span>\n <Input\n type=\"email\"\n value={form.contactEmail}\n onChange={(e) => onChange('contactEmail', e.target.value)}\n />\n </label>\n </div>\n\n {isEdit ? <EntityTagsField entityType=\"exhibitor\" entityId={id} /> : null}\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ExhibitorFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { Input, Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateExhibitorMutation,\n useEventsQuery,\n useExhibitorsQuery,\n useUpdateExhibitorMutation,\n} from '../../api/eventApi';\nimport { EntityFormShell } from '../../components/EntityFormShell';\nimport { EntityTagsField } from '../../components/EntityTagsField';\nimport { safeUrl } from '../../components/SafeLink';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype ExhibitorFormState = {\n eventId: string;\n name: string;\n boothCode: string;\n category: string;\n status: string;\n website: string;\n contactName: string;\n contactEmail: string;\n};\n\nconst initialState: ExhibitorFormState = {\n eventId: '',\n name: '',\n boothCode: '',\n category: '',\n status: 'CONFIRMED',\n website: '',\n contactName: '',\n contactEmail: '',\n};\n\nconst STATUS_OPTIONS = [\n { value: 'INVITED', label: 'Invited' },\n { value: 'CONFIRMED', label: 'Confirmed' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport default function ExhibitorFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventsData } = useEventsQuery({ limit: 100, offset: 0 });\n // No by-id resolver exists for exhibitors, so the edit initial-state is derived\n // from the list query row.\n const { data: exhibitorsData } = useExhibitorsQuery({ limit: 100, offset: 0 });\n\n const existing = useMemo(\n () => (exhibitorsData?.exhibitors?.items ?? []).find((item) => item.id === id),\n [exhibitorsData, id]\n );\n\n const [createExhibitor, { loading: creating }] = useCreateExhibitorMutation();\n const [updateExhibitor, { loading: updating }] = useUpdateExhibitorMutation();\n const [form, setForm] = useState<ExhibitorFormState>(initialState);\n\n useEffect(() => {\n if (!isEdit || !existing) {\n return;\n }\n const metadata = existing.metadata ?? {};\n const website = typeof metadata.website === 'string' ? metadata.website : '';\n setForm({\n eventId: existing.eventId ?? '',\n name: existing.name ?? '',\n boothCode: existing.boothCode ?? '',\n category: existing.category ?? '',\n status: existing.status ?? 'CONFIRMED',\n website,\n contactName: existing.contactName ?? '',\n contactEmail: existing.contactEmail ?? '',\n });\n }, [existing, isEdit]);\n\n const onChange = (field: keyof ExhibitorFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n if (!form.eventId) {\n notify.error('Event required', 'Choose the event this exhibitor belongs to.');\n return;\n }\n\n // The website is free text persisted verbatim, so normalise/reject it before\n // it is stored and later rendered as a link.\n const normalizedWebsite = safeUrl(form.website);\n if (form.website.trim() && !normalizedWebsite) {\n notify.error('Invalid website', 'Enter a valid http(s) URL, or leave it blank.');\n return;\n }\n\n const existingMetadata = existing?.metadata ?? {};\n const input = {\n eventId: form.eventId,\n name: form.name,\n boothCode: form.boothCode,\n category: form.category,\n status: form.status,\n contactName: form.contactName,\n contactEmail: form.contactEmail,\n metadata: { ...existingMetadata, website: normalizedWebsite ?? '' },\n };\n\n try {\n if (isEdit) {\n const response = await updateExhibitor({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateExhibitor?.id, 'Could not update exhibitor')) {\n return;\n }\n navigate('/exhibitors');\n return;\n }\n\n const response = await createExhibitor({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createExhibitor?.id, 'Could not create exhibitor')) {\n return;\n }\n navigate('/exhibitors');\n } catch (error) {\n notify.error('Could not save exhibitor', describeError(error));\n }\n };\n\n const saving = creating || updating;\n const events = eventsData?.events?.items ?? [];\n\n return (\n <EntityFormShell\n title={isEdit ? 'Edit Exhibitor' : 'New Exhibitor'}\n description=\"Manage a booth exhibitor with live backend persistence.\"\n purpose=\"Register a company staffing a booth: link it to the event, give it a booth code and category, and record who to contact. Once saved, capture the leads their booth scans from the exhibitor list.\"\n backLabel=\"Back to Exhibitors\"\n onBack={() => navigate('/exhibitors')}\n onSubmit={onSubmit}\n submitLabel={isEdit ? 'Save Exhibitor' : 'Create Exhibitor'}\n saving={saving}\n >\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Event</span>\n <Select value={form.eventId} onValueChange={(value) => onChange('eventId', value)}>\n <SelectTrigger aria-label=\"Event\">\n <SelectValue placeholder=\"Select event\" />\n </SelectTrigger>\n <SelectContent>\n {events.map((eventItem) => (\n <SelectItem key={eventItem.id} value={eventItem.id}>\n {eventItem.name}\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\">Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Booth Code</span>\n <Input value={form.boothCode} onChange={(e) => onChange('boothCode', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Category</span>\n <Input value={form.category} onChange={(e) => onChange('category', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Status</span>\n <Select value={form.status} onValueChange={(value) => onChange('status', value)}>\n <SelectTrigger aria-label=\"Status\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {STATUS_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n </div>\n\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Website</span>\n <Input\n value={form.website}\n onChange={(e) => onChange('website', e.target.value)}\n placeholder=\"https://example.com\"\n />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Name</span>\n <Input value={form.contactName} onChange={(e) => onChange('contactName', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Email</span>\n <Input type=\"email\" value={form.contactEmail} onChange={(e) => onChange('contactEmail', e.target.value)} />\n </label>\n </div>\n\n {isEdit ? <EntityTagsField entityType=\"exhibitor\" entityId={id} /> : null}\n </EntityFormShell>\n );\n}\n"],"mappings":"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"}