@burdenoff/microfe-eventfullymanaged 2026.731.1 → 2026.801.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/eventfullymanaged/EventfullyManagedRoutes.js +1 -1
- package/dist/eventfullymanaged/EventfullyManagedRoutes.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js +1 -1
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/EventFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/events/EventFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/VirtualSessionPage.js +1 -1
- package/dist/eventfullymanaged/pages/events/VirtualSessionPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js +1 -1
- package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js +1 -1
- package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js +1 -1
- package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
- package/package.json +9 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Suspense as e, lazy as t } from "react";
|
|
2
|
-
import { Navigate as n, Route as r, Routes as i } from "react-router
|
|
2
|
+
import { Navigate as n, Route as r, Routes as i } from "react-router";
|
|
3
3
|
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
4
4
|
//#region src/eventfullymanaged/EventfullyManagedRoutes.tsx
|
|
5
5
|
var s = t(() => import("./pages/dashboard/DashboardPage.js")), c = t(() => import("./pages/venues/VenueListPage.js")), l = t(() => import("./pages/venues/VenueFormPage.js")), u = t(() => import("./pages/venues/VenueDetailPage.js")), d = t(() => import("./pages/venues/FloorPlansPage.js")), f = t(() => import("./pages/sponsors/SponsorsListPage.js")), p = t(() => import("./pages/sponsors/SponsorFormPage.js")), m = t(() => import("./pages/modules/EventsPage.js")), h = t(() => import("./pages/events/EventDetailPage.js")), g = t(() => import("./pages/events/VirtualSessionPage.js")), _ = t(() => import("./pages/events/EventFormPage.js")), v = t(() => import("./pages/events/SessionFormPage.js")), y = t(() => import("./pages/events/TicketTypeFormPage.js")), b = t(() => import("./pages/speakers/SpeakersPage.js")), x = t(() => import("./pages/speakers/SpeakerFormPage.js")), S = t(() => import("./pages/modules/RegistrationPage.js")), C = t(() => import("./pages/registration/RegisterAttendeePage.js")), w = t(() => import("./pages/registration/AttendeeFormPage.js")), T = t(() => import("./pages/registration/PromoCodeFormPage.js")), E = t(() => import("./pages/modules/CommunicationPage.js")), D = t(() => import("./pages/modules/AnalyticsPage.js")), O = t(() => import("./pages/modules/NetworkingPage.js")), k = t(() => import("./pages/networking/NetworkingProfileFormPage.js")), A = t(() => import("./pages/networking/MeetingFormPage.js")), j = t(() => import("./pages/exhibitors/ExhibitorsPage.js")), M = t(() => import("./pages/exhibitors/ExhibitorFormPage.js")), N = t(() => import("./pages/modules/WorkflowsPage.js")), P = t(() => import("./pages/modules/KioskPage.js")), F = t(() => import("./pages/modules/OperationsHubPage.js")), I = t(() => import("./pages/modules/RoadmapPanel.js")), L = t(() => import("./pages/modules/IntegrationsPage.js")), R = t(() => import("./pages/modules/VenueResourcesPage.js")), z = t(() => import("./pages/modules/SponsorDetailsPage.js")), B = t(() => import("./pages/modules/SponsorLeadsPage.js")), V = t(() => import("./pages/modules/AttendeeProfilePage.js"));
|
|
@@ -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 VirtualSessionPage = lazy(() => import('./pages/events/VirtualSessionPage'));\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 IntegrationsPage = lazy(() => import('./pages/modules/IntegrationsPage'));\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 <Route path=\"events/:id/virtual\" element={<VirtualSessionPage />} />\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 {/*\n BOFF-4324 — CRM/marketing-automation connectors are a real, shipped\n core (IntegrationsPage). Outbound webhooks and calendar sync are\n still not built — IntegrationsPage's footer note says so honestly\n rather than claiming the whole \"Integrations\" area is live.\n */}\n <Route path=\"integrations\" element={<IntegrationsPage />} />\n <Route path=\"integrations/*\" element={<IntegrationsPage />} />\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';\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 VirtualSessionPage = lazy(() => import('./pages/events/VirtualSessionPage'));\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 IntegrationsPage = lazy(() => import('./pages/modules/IntegrationsPage'));\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 <Route path=\"events/:id/virtual\" element={<VirtualSessionPage />} />\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 {/*\n BOFF-4324 — CRM/marketing-automation connectors are a real, shipped\n core (IntegrationsPage). Outbound webhooks and calendar sync are\n still not built — IntegrationsPage's footer note says so honestly\n rather than claiming the whole \"Integrations\" area is live.\n */}\n <Route path=\"integrations\" element={<IntegrationsPage />} />\n <Route path=\"integrations/*\" element={<IntegrationsPage />} />\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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"}
|
|
@@ -8,7 +8,7 @@ import { formatDateTime as f } from "./eventFormUtils.js";
|
|
|
8
8
|
import { ActionMenu as p } from "../../components/ActionMenu.js";
|
|
9
9
|
import { Pagination as m, usePagination as h } from "../../components/Pagination.js";
|
|
10
10
|
import { useMemo as g, useState as _ } from "react";
|
|
11
|
-
import { useParams as v } from "react-router
|
|
11
|
+
import { useParams as v } from "react-router";
|
|
12
12
|
import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
13
13
|
import { ArrowLeft as S, CalendarClock as C, Clock as w, Edit as T, Eye as E, MapPin as D, Mic2 as O, Plus as k, Ticket as A, Users as j, Video as M } from "lucide-react";
|
|
14
14
|
import { Badge as N, Button as P, GlassCard as F, IllustratedEmptyState as I, Skeleton as L, Tabs as R, TabsContent as z, TabsList as B, TabsTrigger as V } from "@burdenoff/fe-libs/ui";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventDetailPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/events/EventDetailPage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n ArrowLeft,\n CalendarClock,\n Clock,\n Edit,\n Eye,\n MapPin,\n Mic2,\n Plus,\n Ticket as TicketIcon,\n Users,\n Video,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n IllustratedEmptyState,\n Skeleton,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useDeleteEventSessionMutation,\n useDeleteSpeakerMutation,\n useDeleteTicketTypeMutation,\n useEventQuery,\n useSpeakersQuery,\n useTicketTypesQuery,\n useVenuesQuery,\n type TicketTypeGql,\n} from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { CHART_COLORS } from '../../components/EventCharts';\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\nfunction formatDuration(startsAt: string, endsAt: string): string {\n const start = new Date(startsAt).getTime();\n const end = new Date(endsAt).getTime();\n if (Number.isNaN(start) || Number.isNaN(end) || end <= start) {\n return '';\n }\n const totalMinutes = Math.round((end - start) / 60000);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n if (hours && minutes) {\n return `${hours}h ${minutes}m`;\n }\n if (hours) {\n return `${hours}h`;\n }\n return `${minutes}m`;\n}\n\nfunction formatHour(hour: number): string {\n const period = hour < 12 ? 'AM' : 'PM';\n const display = hour % 12 === 0 ? 12 : hour % 12;\n return `${display}:00 ${period}`;\n}\n\nfunction formatClock(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n return date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\n// ---------------------------------------------------------------------------\n// Sessions tab — multi-track schedule grid.\n//\n// The shared EVENT_SESSIONS_QUERY omits `metadata` (which carries speakerId) and\n// `description`/`capacity`, so this tab owns a fuller read that selects them; the\n// grid resolves room names from venues and speaker names from speakers.\n// ---------------------------------------------------------------------------\n\nconst SCHEDULE_SESSIONS_QUERY = gql`\n query EventfullymanagedScheduleSessions($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 sessionType\n track\n startsAt\n endsAt\n status\n metadata\n }\n }\n }\n`;\n\ntype ScheduleSession = {\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 metadata?: Record<string, unknown> | null;\n};\n\ntype ScheduleSessionsResponse = { eventSessions: { total: number; items: ScheduleSession[] } };\n\nconst UNTRACKED = 'General';\n\nfunction dayKey(iso: string): string {\n const date = new Date(iso);\n return Number.isNaN(date.getTime()) ? 'unknown' : date.toISOString().slice(0, 10);\n}\n\nfunction SessionBlock({\n session,\n color,\n speakerName,\n roomName,\n onEdit,\n onDelete,\n}: {\n session: ScheduleSession;\n color: string;\n speakerName?: string;\n roomName?: string;\n onEdit: () => void;\n onDelete: () => void | Promise<void>;\n}) {\n const duration = formatDuration(session.startsAt, session.endsAt);\n return (\n <div\n className=\"relative rounded-card border border-border-subtle p-3 shadow-elevation-1\"\n style={{\n borderLeftWidth: '3px',\n borderLeftColor: color,\n background: `color-mix(in srgb, ${color} 8%, var(--color-bg-surface))`,\n }}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"min-w-0 pr-1 text-sm font-semibold leading-snug text-text-primary\">{session.title}</p>\n <div className=\"-mr-1 -mt-1 shrink-0\">\n <ActionMenu\n ariaLabel={`Session actions for ${session.title}`}\n entityName={session.title}\n deleteLabel=\"Delete session\"\n onEdit={onEdit}\n onDelete={onDelete}\n />\n </div>\n </div>\n <dl className=\"mt-2 space-y-1 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1.5\">\n <Mic2 className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span className=\"truncate\">{speakerName ?? 'Speaker TBD'}</span>\n </div>\n {roomName ? (\n <div className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span className=\"truncate\">{roomName}</span>\n </div>\n ) : null}\n <div className=\"flex items-center gap-1.5\">\n <Clock className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span>\n {formatClock(session.startsAt)}\n {duration ? ` · ${duration}` : ''}\n </span>\n </div>\n </dl>\n </div>\n );\n}\n\nfunction SessionsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useQuery<\n ScheduleSessionsResponse,\n { eventId?: string; limit?: number; offset?: number }\n >(SCHEDULE_SESSIONS_QUERY, {\n variables: { eventId, limit: pagination.limit, offset: pagination.offset },\n });\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const { data: speakersData } = useSpeakersQuery({ limit: 100, offset: 0 });\n const [deleteEventSession] = useDeleteEventSessionMutation();\n\n const total = data?.eventSessions?.total ?? 0;\n const rows = useMemo(() => data?.eventSessions?.items ?? [], [data]);\n\n const venueNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const venue of venuesData?.venues?.items ?? []) {\n map.set(venue.id, venue.name);\n }\n return map;\n }, [venuesData]);\n\n const speakerNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const speaker of speakersData?.speakers?.items ?? []) {\n map.set(speaker.id, speaker.fullName);\n }\n return map;\n }, [speakersData]);\n\n // Distinct tracks (ordered by first appearance) → stable colour per track.\n const trackColor = useMemo(() => {\n const map = new Map<string, string>();\n let index = 0;\n for (const session of rows) {\n const track = session.track?.trim() || UNTRACKED;\n if (!map.has(track)) {\n map.set(track, CHART_COLORS[index % CHART_COLORS.length]);\n index += 1;\n }\n }\n return map;\n }, [rows]);\n\n // Group sessions by day, then by track, keyed by the hour they start.\n const days = useMemo(() => {\n const byDay = new Map<string, ScheduleSession[]>();\n for (const session of [...rows].sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime())) {\n const key = dayKey(session.startsAt);\n const list = byDay.get(key) ?? [];\n list.push(session);\n byDay.set(key, list);\n }\n return Array.from(byDay.entries()).map(([key, sessions]) => {\n const tracks = Array.from(new Set(sessions.map((s) => s.track?.trim() || UNTRACKED)));\n const hours = sessions.map((s) => new Date(s.startsAt).getHours()).filter((h) => !Number.isNaN(h));\n const minHour = hours.length ? Math.min(...hours) : 9;\n const maxHour = hours.length ? Math.max(...hours) : 17;\n const hourRange: number[] = [];\n for (let hour = minHour; hour <= maxHour; hour += 1) {\n hourRange.push(hour);\n }\n return { key, sessions, tracks, hourRange };\n });\n }, [rows]);\n\n const onDelete = async (session: ScheduleSession) => {\n const response = await deleteEventSession({ variables: { id: session.id } });\n if (response.error) {\n notify.error('Could not delete session', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteEventSession) {\n notify.error('Could not delete session', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Session deleted', session.title);\n await refetch();\n };\n\n const resolveSpeaker = (session: ScheduleSession): string | undefined => {\n const metadata = (session.metadata ?? {}) as Record<string, unknown>;\n const speakerId = typeof metadata.speakerId === 'string' ? metadata.speakerId : '';\n return speakerId ? speakerNameById.get(speakerId) : undefined;\n };\n const resolveRoom = (session: ScheduleSession): string | undefined =>\n session.venueId ? venueNameById.get(session.venueId) : undefined;\n\n return (\n <div className=\"space-y-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Agenda & Sessions</h2>\n <p className=\"text-sm text-text-secondary\">A multi-track schedule of everything happening on the day.</p>\n </div>\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 <Skeleton className=\"h-64 w-full rounded-card\" />\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 action={\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 }\n className=\"py-10\"\n />\n ) : (\n <div className=\"space-y-8\">\n {days.map((day) => (\n <section key={day.key} className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {new Date(`${day.key}T00:00:00`).toLocaleDateString(undefined, {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n })}\n </h3>\n\n {/* Desktop / tablet: multi-track grid */}\n <div className=\"hidden overflow-x-auto rounded-card border border-border-seam md:block\">\n <div\n className=\"grid min-w-max\"\n style={{ gridTemplateColumns: `88px repeat(${day.tracks.length}, minmax(200px, 1fr))` }}\n >\n {/* Header row */}\n <div className=\"sticky left-0 z-10 border-b border-border-seam bg-bg-sunken px-3 py-2.5\" />\n {day.tracks.map((track) => (\n <div\n key={track}\n className=\"border-b border-l border-border-seam bg-bg-sunken px-3 py-2.5 text-center text-sm font-semibold text-text-primary\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"h-2 w-2 rounded-full\"\n style={{ background: trackColor.get(track) }}\n aria-hidden=\"true\"\n />\n {track}\n </span>\n </div>\n ))}\n\n {/* Hour rows */}\n {day.hourRange.map((hour) => (\n <div key={hour} className=\"contents\">\n <div className=\"sticky left-0 z-10 border-b border-border-subtle bg-bg-surface px-3 py-3 text-xs font-medium text-text-muted\">\n {formatHour(hour)}\n </div>\n {day.tracks.map((track) => {\n const cellSessions = day.sessions.filter(\n (session) =>\n (session.track?.trim() || UNTRACKED) === track &&\n new Date(session.startsAt).getHours() === hour\n );\n return (\n <div\n key={`${hour}-${track}`}\n className=\"space-y-2 border-b border-l border-border-subtle p-2 align-top\"\n >\n {cellSessions.map((session) => (\n <SessionBlock\n key={session.id}\n session={session}\n color={trackColor.get(track) ?? CHART_COLORS[0]}\n speakerName={resolveSpeaker(session)}\n roomName={resolveRoom(session)}\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n onDelete={() => onDelete(session)}\n />\n ))}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n\n {/* Mobile: clean time-ordered day list */}\n <ul className=\"space-y-2.5 md:hidden\">\n {day.sessions.map((session) => {\n const track = session.track?.trim() || UNTRACKED;\n return (\n <li key={session.id}>\n <SessionBlock\n session={session}\n color={trackColor.get(track) ?? CHART_COLORS[0]}\n speakerName={resolveSpeaker(session)}\n roomName={resolveRoom(session) ?? track}\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n onDelete={() => onDelete(session)}\n />\n </li>\n );\n })}\n </ul>\n </section>\n ))}\n </div>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sessions\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\ntype SpeakerRow = { id: string; fullName: string; title?: string | null; organization?: string | null };\n\nfunction SpeakersTab() {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useSpeakersQuery({ limit: pagination.limit, offset: pagination.offset });\n const [deleteSpeaker] = useDeleteSpeakerMutation();\n\n const total = data?.speakers?.total ?? 0;\n const rows = (data?.speakers?.items ?? []) as unknown as SpeakerRow[];\n\n const onDelete = async (speaker: SpeakerRow) => {\n const response = await deleteSpeaker({ variables: { id: speaker.id } });\n if (response.error) {\n notify.error('Could not delete speaker', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteSpeaker) {\n notify.error('Could not delete speaker', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Speaker deleted', speaker.fullName);\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Speakers</h2>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate('/speakers')}>\n Manage speakers\n </Button>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate('/speakers/create')}>\n <Plus className=\"h-4 w-4\" />\n New Speaker\n </Button>\n </div>\n </div>\n\n {loading ? (\n <Skeleton className=\"h-40 w-full rounded-card\" />\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=\"grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\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=\"flex min-w-0 items-center gap-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent-wash text-sm font-semibold text-action-primary-bg\">\n {speaker.fullName.slice(0, 1).toUpperCase()}\n </span>\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 </div>\n <ActionMenu\n ariaLabel={`Speaker actions for ${speaker.fullName}`}\n entityName={speaker.fullName}\n deleteLabel=\"Delete speaker\"\n onEdit={() => navigate(`/speakers/${speaker.id}/edit`)}\n onDelete={() => onDelete(speaker)}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"speakers\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nfunction TicketsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useTicketTypesQuery({\n eventId,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteTicketType] = useDeleteTicketTypeMutation();\n\n const total = data?.ticketTypes?.total ?? 0;\n const rows = (data?.ticketTypes?.items ?? []) as TicketTypeGql[];\n\n const onDelete = async (ticket: TicketTypeGql) => {\n const response = await deleteTicketType({ variables: { id: ticket.id } });\n if (response.error) {\n notify.error('Could not delete ticket type', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteTicketType) {\n notify.error('Could not delete ticket type', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Ticket type deleted');\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket Types</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/tickets/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Ticket Type\n </Button>\n </div>\n\n {loading ? (\n <Skeleton className=\"h-40 w-full rounded-card\" />\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-3\">\n {rows.map((ticket) => {\n const hasCapacity = ticket.capacity != null && ticket.capacity > 0;\n const pct = hasCapacity\n ? Math.min(100, Math.round((ticket.soldCount / (ticket.capacity as number)) * 100))\n : 0;\n const nearlyFull = pct >= 90;\n return (\n <li\n key={ticket.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-start 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 text-sm text-text-secondary\">\n {ticket.price} {ticket.currency}\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\n <div className=\"mt-3\">\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {ticket.soldCount.toLocaleString()}\n </span>{' '}\n sold\n {hasCapacity ? (\n <> / {(ticket.capacity as number).toLocaleString()} capacity</>\n ) : (\n ' • unlimited capacity'\n )}\n </span>\n {hasCapacity ? (\n <span className={nearlyFull ? 'font-medium text-text-primary' : ''}>{pct}%</span>\n ) : null}\n </div>\n {hasCapacity ? (\n <div\n className=\"mt-1.5 h-2 overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`${ticket.name} sold`}\n >\n <div\n className=\"h-full rounded-full transition-[width] duration-500\"\n style={{\n width: `${pct}%`,\n background: 'linear-gradient(90deg, var(--color-chart-1), var(--color-chart-2))',\n }}\n />\n </div>\n ) : null}\n </div>\n </li>\n );\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\nfunction MetricTile({\n label,\n value,\n icon: Icon,\n}: {\n label: string;\n value: string;\n icon: React.ComponentType<{ className?: string }>;\n}) {\n return (\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-button bg-accent-wash text-action-primary-bg\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <div className=\"mt-2.5 text-xl font-semibold tabular-nums text-text-primary\">{value}</div>\n <div className=\"mt-0.5 text-xs text-text-muted\">{label}</div>\n </GlassCard>\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 { data: sessionsData } = useQuery<ScheduleSessionsResponse, { eventId?: string; limit?: number }>(\n SCHEDULE_SESSIONS_QUERY,\n { variables: { eventId: id, limit: 200 }, skip: !id }\n );\n const { data: ticketsData } = useTicketTypesQuery({ eventId: id, limit: 100, offset: 0 });\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\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 const venueName = useMemo(\n () => (venueId ? venuesData?.venues?.items?.find((venue) => venue.id === venueId)?.name : undefined),\n [venueId, venuesData]\n );\n\n const sessionCount = sessionsData?.eventSessions?.total ?? 0;\n const ticketsSold = useMemo(\n () => (ticketsData?.ticketTypes?.items ?? []).reduce((sum, ticket) => sum + (ticket.soldCount ?? 0), 0),\n [ticketsData]\n );\n\n if (loading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-8 w-40\" />\n <Skeleton className=\"h-24 w-full rounded-card\" />\n <Skeleton className=\"h-64 w-full rounded-card\" />\n </div>\n );\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 flex-wrap items-center gap-x-4 gap-y-1 text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1.5\">\n <CalendarClock className=\"h-4 w-4 text-text-muted\" />\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </span>\n {venueName ? (\n <span className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-4 w-4 text-text-muted\" />\n {venueName}\n </span>\n ) : null}\n </p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {event.type === 'VIRTUAL' || event.type === 'HYBRID' ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate(`/events/${id}/virtual`)}>\n <Video className=\"h-4 w-4\" />\n Virtual Session\n </Button>\n ) : null}\n <Button type=\"button\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit Event\n </Button>\n </div>\n </div>\n\n {/* Metrics strip */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <MetricTile label=\"Capacity\" value={(event.capacity ?? 0).toLocaleString()} icon={Users} />\n <MetricTile label=\"Sessions\" value={sessionCount.toLocaleString()} icon={CalendarClock} />\n <MetricTile\n label=\"Ticket types\"\n value={(ticketsData?.ticketTypes?.total ?? 0).toLocaleString()}\n icon={TicketIcon}\n />\n <MetricTile label=\"Tickets sold\" value={ticketsSold.toLocaleString()} icon={Eye} />\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=\"plain\" className=\"border-border-seam p-5 lg:col-span-2\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Event Details</h2>\n <dl className=\"mt-4 space-y-4 text-sm\">\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Dates</dt>\n <dd className=\"text-text-primary\">\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Venue</dt>\n <dd className=\"text-text-primary\">\n {venueName ? (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n className=\"h-auto p-0\"\n onClick={() => navigate(`/venues/${venueId}`)}\n >\n {venueName}\n </Button>\n ) : (\n 'No venue assigned'\n )}\n </dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Capacity</dt>\n <dd className=\"text-text-primary\">{(event.capacity ?? 0).toLocaleString()} attendees</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Type</dt>\n <dd className=\"capitalize text-text-primary\">{event.type.toLowerCase().replace(/_/g, ' ')}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Timezone</dt>\n <dd className=\"text-text-primary\">{event.timezone}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Visibility</dt>\n <dd className=\"capitalize text-text-primary\">{event.visibility}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Description</dt>\n <dd className=\"text-text-secondary\">\n {event.description?.trim() ? event.description : 'No description provided.'}\n </dd>\n </div>\n </dl>\n <div className=\"mt-5\">\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\n <GlassCard treatment=\"glass\" glow className=\"p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Key Metrics</h2>\n <dl className=\"mt-4 space-y-4\">\n <div>\n <dt className=\"text-sm text-text-secondary\">Capacity</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {(event.capacity ?? 0).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Sessions</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {sessionCount.toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Ticket types</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {(ticketsData?.ticketTypes?.total ?? 0).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Tickets sold</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {ticketsSold.toLocaleString()}\n </dd>\n </div>\n </dl>\n </GlassCard>\n </div>\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 { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n ArrowLeft,\n CalendarClock,\n Clock,\n Edit,\n Eye,\n MapPin,\n Mic2,\n Plus,\n Ticket as TicketIcon,\n Users,\n Video,\n} from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n IllustratedEmptyState,\n Skeleton,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\nimport { useParams } from 'react-router';\n\nimport {\n useDeleteEventSessionMutation,\n useDeleteSpeakerMutation,\n useDeleteTicketTypeMutation,\n useEventQuery,\n useSpeakersQuery,\n useTicketTypesQuery,\n useVenuesQuery,\n type TicketTypeGql,\n} from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { CHART_COLORS } from '../../components/EventCharts';\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\nfunction formatDuration(startsAt: string, endsAt: string): string {\n const start = new Date(startsAt).getTime();\n const end = new Date(endsAt).getTime();\n if (Number.isNaN(start) || Number.isNaN(end) || end <= start) {\n return '';\n }\n const totalMinutes = Math.round((end - start) / 60000);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n if (hours && minutes) {\n return `${hours}h ${minutes}m`;\n }\n if (hours) {\n return `${hours}h`;\n }\n return `${minutes}m`;\n}\n\nfunction formatHour(hour: number): string {\n const period = hour < 12 ? 'AM' : 'PM';\n const display = hour % 12 === 0 ? 12 : hour % 12;\n return `${display}:00 ${period}`;\n}\n\nfunction formatClock(iso: string): string {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n return date.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n}\n\n// ---------------------------------------------------------------------------\n// Sessions tab — multi-track schedule grid.\n//\n// The shared EVENT_SESSIONS_QUERY omits `metadata` (which carries speakerId) and\n// `description`/`capacity`, so this tab owns a fuller read that selects them; the\n// grid resolves room names from venues and speaker names from speakers.\n// ---------------------------------------------------------------------------\n\nconst SCHEDULE_SESSIONS_QUERY = gql`\n query EventfullymanagedScheduleSessions($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 sessionType\n track\n startsAt\n endsAt\n status\n metadata\n }\n }\n }\n`;\n\ntype ScheduleSession = {\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 metadata?: Record<string, unknown> | null;\n};\n\ntype ScheduleSessionsResponse = { eventSessions: { total: number; items: ScheduleSession[] } };\n\nconst UNTRACKED = 'General';\n\nfunction dayKey(iso: string): string {\n const date = new Date(iso);\n return Number.isNaN(date.getTime()) ? 'unknown' : date.toISOString().slice(0, 10);\n}\n\nfunction SessionBlock({\n session,\n color,\n speakerName,\n roomName,\n onEdit,\n onDelete,\n}: {\n session: ScheduleSession;\n color: string;\n speakerName?: string;\n roomName?: string;\n onEdit: () => void;\n onDelete: () => void | Promise<void>;\n}) {\n const duration = formatDuration(session.startsAt, session.endsAt);\n return (\n <div\n className=\"relative rounded-card border border-border-subtle p-3 shadow-elevation-1\"\n style={{\n borderLeftWidth: '3px',\n borderLeftColor: color,\n background: `color-mix(in srgb, ${color} 8%, var(--color-bg-surface))`,\n }}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <p className=\"min-w-0 pr-1 text-sm font-semibold leading-snug text-text-primary\">{session.title}</p>\n <div className=\"-mr-1 -mt-1 shrink-0\">\n <ActionMenu\n ariaLabel={`Session actions for ${session.title}`}\n entityName={session.title}\n deleteLabel=\"Delete session\"\n onEdit={onEdit}\n onDelete={onDelete}\n />\n </div>\n </div>\n <dl className=\"mt-2 space-y-1 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1.5\">\n <Mic2 className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span className=\"truncate\">{speakerName ?? 'Speaker TBD'}</span>\n </div>\n {roomName ? (\n <div className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span className=\"truncate\">{roomName}</span>\n </div>\n ) : null}\n <div className=\"flex items-center gap-1.5\">\n <Clock className=\"h-3.5 w-3.5 shrink-0 text-text-muted\" />\n <span>\n {formatClock(session.startsAt)}\n {duration ? ` · ${duration}` : ''}\n </span>\n </div>\n </dl>\n </div>\n );\n}\n\nfunction SessionsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useQuery<\n ScheduleSessionsResponse,\n { eventId?: string; limit?: number; offset?: number }\n >(SCHEDULE_SESSIONS_QUERY, {\n variables: { eventId, limit: pagination.limit, offset: pagination.offset },\n });\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\n const { data: speakersData } = useSpeakersQuery({ limit: 100, offset: 0 });\n const [deleteEventSession] = useDeleteEventSessionMutation();\n\n const total = data?.eventSessions?.total ?? 0;\n const rows = useMemo(() => data?.eventSessions?.items ?? [], [data]);\n\n const venueNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const venue of venuesData?.venues?.items ?? []) {\n map.set(venue.id, venue.name);\n }\n return map;\n }, [venuesData]);\n\n const speakerNameById = useMemo(() => {\n const map = new Map<string, string>();\n for (const speaker of speakersData?.speakers?.items ?? []) {\n map.set(speaker.id, speaker.fullName);\n }\n return map;\n }, [speakersData]);\n\n // Distinct tracks (ordered by first appearance) → stable colour per track.\n const trackColor = useMemo(() => {\n const map = new Map<string, string>();\n let index = 0;\n for (const session of rows) {\n const track = session.track?.trim() || UNTRACKED;\n if (!map.has(track)) {\n map.set(track, CHART_COLORS[index % CHART_COLORS.length]);\n index += 1;\n }\n }\n return map;\n }, [rows]);\n\n // Group sessions by day, then by track, keyed by the hour they start.\n const days = useMemo(() => {\n const byDay = new Map<string, ScheduleSession[]>();\n for (const session of [...rows].sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime())) {\n const key = dayKey(session.startsAt);\n const list = byDay.get(key) ?? [];\n list.push(session);\n byDay.set(key, list);\n }\n return Array.from(byDay.entries()).map(([key, sessions]) => {\n const tracks = Array.from(new Set(sessions.map((s) => s.track?.trim() || UNTRACKED)));\n const hours = sessions.map((s) => new Date(s.startsAt).getHours()).filter((h) => !Number.isNaN(h));\n const minHour = hours.length ? Math.min(...hours) : 9;\n const maxHour = hours.length ? Math.max(...hours) : 17;\n const hourRange: number[] = [];\n for (let hour = minHour; hour <= maxHour; hour += 1) {\n hourRange.push(hour);\n }\n return { key, sessions, tracks, hourRange };\n });\n }, [rows]);\n\n const onDelete = async (session: ScheduleSession) => {\n const response = await deleteEventSession({ variables: { id: session.id } });\n if (response.error) {\n notify.error('Could not delete session', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteEventSession) {\n notify.error('Could not delete session', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Session deleted', session.title);\n await refetch();\n };\n\n const resolveSpeaker = (session: ScheduleSession): string | undefined => {\n const metadata = (session.metadata ?? {}) as Record<string, unknown>;\n const speakerId = typeof metadata.speakerId === 'string' ? metadata.speakerId : '';\n return speakerId ? speakerNameById.get(speakerId) : undefined;\n };\n const resolveRoom = (session: ScheduleSession): string | undefined =>\n session.venueId ? venueNameById.get(session.venueId) : undefined;\n\n return (\n <div className=\"space-y-5\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Agenda & Sessions</h2>\n <p className=\"text-sm text-text-secondary\">A multi-track schedule of everything happening on the day.</p>\n </div>\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 <Skeleton className=\"h-64 w-full rounded-card\" />\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 action={\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 }\n className=\"py-10\"\n />\n ) : (\n <div className=\"space-y-8\">\n {days.map((day) => (\n <section key={day.key} className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {new Date(`${day.key}T00:00:00`).toLocaleDateString(undefined, {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n })}\n </h3>\n\n {/* Desktop / tablet: multi-track grid */}\n <div className=\"hidden overflow-x-auto rounded-card border border-border-seam md:block\">\n <div\n className=\"grid min-w-max\"\n style={{ gridTemplateColumns: `88px repeat(${day.tracks.length}, minmax(200px, 1fr))` }}\n >\n {/* Header row */}\n <div className=\"sticky left-0 z-10 border-b border-border-seam bg-bg-sunken px-3 py-2.5\" />\n {day.tracks.map((track) => (\n <div\n key={track}\n className=\"border-b border-l border-border-seam bg-bg-sunken px-3 py-2.5 text-center text-sm font-semibold text-text-primary\"\n >\n <span className=\"inline-flex items-center gap-2\">\n <span\n className=\"h-2 w-2 rounded-full\"\n style={{ background: trackColor.get(track) }}\n aria-hidden=\"true\"\n />\n {track}\n </span>\n </div>\n ))}\n\n {/* Hour rows */}\n {day.hourRange.map((hour) => (\n <div key={hour} className=\"contents\">\n <div className=\"sticky left-0 z-10 border-b border-border-subtle bg-bg-surface px-3 py-3 text-xs font-medium text-text-muted\">\n {formatHour(hour)}\n </div>\n {day.tracks.map((track) => {\n const cellSessions = day.sessions.filter(\n (session) =>\n (session.track?.trim() || UNTRACKED) === track &&\n new Date(session.startsAt).getHours() === hour\n );\n return (\n <div\n key={`${hour}-${track}`}\n className=\"space-y-2 border-b border-l border-border-subtle p-2 align-top\"\n >\n {cellSessions.map((session) => (\n <SessionBlock\n key={session.id}\n session={session}\n color={trackColor.get(track) ?? CHART_COLORS[0]}\n speakerName={resolveSpeaker(session)}\n roomName={resolveRoom(session)}\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n onDelete={() => onDelete(session)}\n />\n ))}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n\n {/* Mobile: clean time-ordered day list */}\n <ul className=\"space-y-2.5 md:hidden\">\n {day.sessions.map((session) => {\n const track = session.track?.trim() || UNTRACKED;\n return (\n <li key={session.id}>\n <SessionBlock\n session={session}\n color={trackColor.get(track) ?? CHART_COLORS[0]}\n speakerName={resolveSpeaker(session)}\n roomName={resolveRoom(session) ?? track}\n onEdit={() => navigate(`/events/${eventId}/sessions/${session.id}/edit`)}\n onDelete={() => onDelete(session)}\n />\n </li>\n );\n })}\n </ul>\n </section>\n ))}\n </div>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sessions\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\ntype SpeakerRow = { id: string; fullName: string; title?: string | null; organization?: string | null };\n\nfunction SpeakersTab() {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useSpeakersQuery({ limit: pagination.limit, offset: pagination.offset });\n const [deleteSpeaker] = useDeleteSpeakerMutation();\n\n const total = data?.speakers?.total ?? 0;\n const rows = (data?.speakers?.items ?? []) as unknown as SpeakerRow[];\n\n const onDelete = async (speaker: SpeakerRow) => {\n const response = await deleteSpeaker({ variables: { id: speaker.id } });\n if (response.error) {\n notify.error('Could not delete speaker', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteSpeaker) {\n notify.error('Could not delete speaker', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Speaker deleted', speaker.fullName);\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Speakers</h2>\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => navigate('/speakers')}>\n Manage speakers\n </Button>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate('/speakers/create')}>\n <Plus className=\"h-4 w-4\" />\n New Speaker\n </Button>\n </div>\n </div>\n\n {loading ? (\n <Skeleton className=\"h-40 w-full rounded-card\" />\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=\"grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\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=\"flex min-w-0 items-center gap-3\">\n <span className=\"flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent-wash text-sm font-semibold text-action-primary-bg\">\n {speaker.fullName.slice(0, 1).toUpperCase()}\n </span>\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 </div>\n <ActionMenu\n ariaLabel={`Speaker actions for ${speaker.fullName}`}\n entityName={speaker.fullName}\n deleteLabel=\"Delete speaker\"\n onEdit={() => navigate(`/speakers/${speaker.id}/edit`)}\n onDelete={() => onDelete(speaker)}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={rows.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"speakers\"\n loading={loading}\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n\nfunction TicketsTab({ eventId }: { eventId: string }) {\n const { navigate } = useEventfullyManaged();\n const pagination = usePagination();\n const { data, loading, refetch } = useTicketTypesQuery({\n eventId,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteTicketType] = useDeleteTicketTypeMutation();\n\n const total = data?.ticketTypes?.total ?? 0;\n const rows = (data?.ticketTypes?.items ?? []) as TicketTypeGql[];\n\n const onDelete = async (ticket: TicketTypeGql) => {\n const response = await deleteTicketType({ variables: { id: ticket.id } });\n if (response.error) {\n notify.error('Could not delete ticket type', response.error.message);\n throw response.error;\n }\n if (!response.data?.deleteTicketType) {\n notify.error('Could not delete ticket type', 'The server did not confirm the change.');\n throw new Error('delete-unconfirmed');\n }\n notify.success('Ticket type deleted');\n await refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket Types</h2>\n <Button type=\"button\" size=\"sm\" onClick={() => navigate(`/events/${eventId}/tickets/create`)}>\n <Plus className=\"h-4 w-4\" />\n New Ticket Type\n </Button>\n </div>\n\n {loading ? (\n <Skeleton className=\"h-40 w-full rounded-card\" />\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-3\">\n {rows.map((ticket) => {\n const hasCapacity = ticket.capacity != null && ticket.capacity > 0;\n const pct = hasCapacity\n ? Math.min(100, Math.round((ticket.soldCount / (ticket.capacity as number)) * 100))\n : 0;\n const nearlyFull = pct >= 90;\n return (\n <li\n key={ticket.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-4 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-start 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 text-sm text-text-secondary\">\n {ticket.price} {ticket.currency}\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\n <div className=\"mt-3\">\n <div className=\"flex items-center justify-between text-xs text-text-secondary\">\n <span>\n <span className=\"font-medium tabular-nums text-text-primary\">\n {ticket.soldCount.toLocaleString()}\n </span>{' '}\n sold\n {hasCapacity ? (\n <> / {(ticket.capacity as number).toLocaleString()} capacity</>\n ) : (\n ' • unlimited capacity'\n )}\n </span>\n {hasCapacity ? (\n <span className={nearlyFull ? 'font-medium text-text-primary' : ''}>{pct}%</span>\n ) : null}\n </div>\n {hasCapacity ? (\n <div\n className=\"mt-1.5 h-2 overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-valuenow={pct}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`${ticket.name} sold`}\n >\n <div\n className=\"h-full rounded-full transition-[width] duration-500\"\n style={{\n width: `${pct}%`,\n background: 'linear-gradient(90deg, var(--color-chart-1), var(--color-chart-2))',\n }}\n />\n </div>\n ) : null}\n </div>\n </li>\n );\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\nfunction MetricTile({\n label,\n value,\n icon: Icon,\n}: {\n label: string;\n value: string;\n icon: React.ComponentType<{ className?: string }>;\n}) {\n return (\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <span className=\"flex h-8 w-8 items-center justify-center rounded-button bg-accent-wash text-action-primary-bg\">\n <Icon className=\"h-4 w-4\" />\n </span>\n <div className=\"mt-2.5 text-xl font-semibold tabular-nums text-text-primary\">{value}</div>\n <div className=\"mt-0.5 text-xs text-text-muted\">{label}</div>\n </GlassCard>\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 { data: sessionsData } = useQuery<ScheduleSessionsResponse, { eventId?: string; limit?: number }>(\n SCHEDULE_SESSIONS_QUERY,\n { variables: { eventId: id, limit: 200 }, skip: !id }\n );\n const { data: ticketsData } = useTicketTypesQuery({ eventId: id, limit: 100, offset: 0 });\n const { data: venuesData } = useVenuesQuery({ limit: 100, offset: 0 });\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 const venueName = useMemo(\n () => (venueId ? venuesData?.venues?.items?.find((venue) => venue.id === venueId)?.name : undefined),\n [venueId, venuesData]\n );\n\n const sessionCount = sessionsData?.eventSessions?.total ?? 0;\n const ticketsSold = useMemo(\n () => (ticketsData?.ticketTypes?.items ?? []).reduce((sum, ticket) => sum + (ticket.soldCount ?? 0), 0),\n [ticketsData]\n );\n\n if (loading) {\n return (\n <div className=\"space-y-4 p-6\">\n <Skeleton className=\"h-8 w-40\" />\n <Skeleton className=\"h-24 w-full rounded-card\" />\n <Skeleton className=\"h-64 w-full rounded-card\" />\n </div>\n );\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 flex-wrap items-center gap-x-4 gap-y-1 text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1.5\">\n <CalendarClock className=\"h-4 w-4 text-text-muted\" />\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </span>\n {venueName ? (\n <span className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-4 w-4 text-text-muted\" />\n {venueName}\n </span>\n ) : null}\n </p>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {event.type === 'VIRTUAL' || event.type === 'HYBRID' ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate(`/events/${id}/virtual`)}>\n <Video className=\"h-4 w-4\" />\n Virtual Session\n </Button>\n ) : null}\n <Button type=\"button\" onClick={() => navigate(`/events/${id}/edit`)}>\n <Edit className=\"h-4 w-4\" />\n Edit Event\n </Button>\n </div>\n </div>\n\n {/* Metrics strip */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <MetricTile label=\"Capacity\" value={(event.capacity ?? 0).toLocaleString()} icon={Users} />\n <MetricTile label=\"Sessions\" value={sessionCount.toLocaleString()} icon={CalendarClock} />\n <MetricTile\n label=\"Ticket types\"\n value={(ticketsData?.ticketTypes?.total ?? 0).toLocaleString()}\n icon={TicketIcon}\n />\n <MetricTile label=\"Tickets sold\" value={ticketsSold.toLocaleString()} icon={Eye} />\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=\"plain\" className=\"border-border-seam p-5 lg:col-span-2\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Event Details</h2>\n <dl className=\"mt-4 space-y-4 text-sm\">\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Dates</dt>\n <dd className=\"text-text-primary\">\n {formatDateTime(event.startAt)} — {formatDateTime(event.endAt)}\n </dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Venue</dt>\n <dd className=\"text-text-primary\">\n {venueName ? (\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n className=\"h-auto p-0\"\n onClick={() => navigate(`/venues/${venueId}`)}\n >\n {venueName}\n </Button>\n ) : (\n 'No venue assigned'\n )}\n </dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Capacity</dt>\n <dd className=\"text-text-primary\">{(event.capacity ?? 0).toLocaleString()} attendees</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Type</dt>\n <dd className=\"capitalize text-text-primary\">{event.type.toLowerCase().replace(/_/g, ' ')}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Timezone</dt>\n <dd className=\"text-text-primary\">{event.timezone}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Visibility</dt>\n <dd className=\"capitalize text-text-primary\">{event.visibility}</dd>\n </div>\n <div className=\"grid grid-cols-1 gap-1 sm:grid-cols-[140px_1fr]\">\n <dt className=\"text-text-muted\">Description</dt>\n <dd className=\"text-text-secondary\">\n {event.description?.trim() ? event.description : 'No description provided.'}\n </dd>\n </div>\n </dl>\n <div className=\"mt-5\">\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\n <GlassCard treatment=\"glass\" glow className=\"p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Key Metrics</h2>\n <dl className=\"mt-4 space-y-4\">\n <div>\n <dt className=\"text-sm text-text-secondary\">Capacity</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {(event.capacity ?? 0).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Sessions</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {sessionCount.toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Ticket types</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {(ticketsData?.ticketTypes?.total ?? 0).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm text-text-secondary\">Tickets sold</dt>\n <dd className=\"text-2xl font-semibold tabular-nums text-text-primary\">\n {ticketsSold.toLocaleString()}\n </dd>\n </div>\n </dl>\n </GlassCard>\n </div>\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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"}
|
|
@@ -5,7 +5,7 @@ import { EVENT_STATUS_OPTIONS as o, EVENT_TYPE_OPTIONS as s, EVENT_VISIBILITY_OP
|
|
|
5
5
|
import { EntityFormShell as d } from "../../components/EntityFormShell.js";
|
|
6
6
|
import { describeError as f, mutationSucceeded as p } from "../../lib/mutationResult.js";
|
|
7
7
|
import { useEffect as m, useMemo as h, useState as g } from "react";
|
|
8
|
-
import { useParams as _ } from "react-router
|
|
8
|
+
import { useParams as _ } from "react-router";
|
|
9
9
|
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
10
10
|
import { Input as b, Select as x, SelectContent as S, SelectItem as C, SelectTrigger as w, SelectValue as T, Textarea as E } from "@burdenoff/fe-libs/ui";
|
|
11
11
|
//#region src/eventfullymanaged/pages/events/EventFormPage.tsx
|
|
@@ -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 { 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 <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Basics</p>\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=\"border-t border-border-subtle pt-4\" />\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Schedule & location</p>\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=\"border-t border-border-subtle pt-4\" />\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Classification</p>\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';\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 <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Basics</p>\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=\"border-t border-border-subtle pt-4\" />\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Schedule & location</p>\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=\"border-t border-border-subtle pt-4\" />\n <p className=\"text-xs font-semibold uppercase tracking-wide text-text-muted\">Classification</p>\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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"}
|
|
@@ -8,7 +8,7 @@ import { EntityFormShell as m } from "../../components/EntityFormShell.js";
|
|
|
8
8
|
import { describeError as h, mutationSucceeded as g } from "../../lib/mutationResult.js";
|
|
9
9
|
import { EntityTagsField as _ } from "../../components/EntityTagsField.js";
|
|
10
10
|
import { useEffect as v, useMemo as y, useState as b } from "react";
|
|
11
|
-
import { useParams as x } from "react-router
|
|
11
|
+
import { useParams as x } from "react-router";
|
|
12
12
|
import { jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
13
13
|
import { Input as w, Select as T, SelectContent as E, SelectItem as D, SelectTrigger as O, SelectValue as k, Textarea as A } from "@burdenoff/fe-libs/ui";
|
|
14
14
|
//#region src/eventfullymanaged/pages/events/SessionFormPage.tsx
|