@burdenoff/microfe-eventfullymanaged 2026.608.1 → 2026.625.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/eventfullymanaged/components/PageLayout.js +44 -38
  2. package/dist/eventfullymanaged/components/PageLayout.js.map +1 -1
  3. package/dist/eventfullymanaged/pages/dashboard/DashboardPage.js +93 -40
  4. package/dist/eventfullymanaged/pages/dashboard/DashboardPage.js.map +1 -1
  5. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js +32 -29
  6. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
  7. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js +85 -50
  8. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js.map +1 -1
  9. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js +49 -50
  10. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js.map +1 -1
  11. package/dist/eventfullymanaged/pages/modules/EntityListSection.js +57 -25
  12. package/dist/eventfullymanaged/pages/modules/EntityListSection.js.map +1 -1
  13. package/dist/eventfullymanaged/pages/modules/EventsPage.js +93 -66
  14. package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
  15. package/dist/eventfullymanaged/pages/modules/KioskPage.js +18 -19
  16. package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
  17. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +60 -30
  18. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
  19. package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js +146 -108
  20. package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js.map +1 -1
  21. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +67 -38
  22. package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
  23. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +84 -49
  24. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
  25. package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js +57 -28
  26. package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js.map +1 -1
  27. package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js +106 -72
  28. package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js.map +1 -1
  29. package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js +84 -68
  30. package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js.map +1 -1
  31. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +202 -204
  32. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
  33. package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js +58 -39
  34. package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js.map +1 -1
  35. package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js +53 -46
  36. package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js.map +1 -1
  37. package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js +109 -63
  38. package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
  39. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +193 -197
  40. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
  41. package/dist/eventfullymanaged/pages/venues/VenueListPage.js +65 -36
  42. package/dist/eventfullymanaged/pages/venues/VenueListPage.js.map +1 -1
  43. package/package.json +2 -2
@@ -1,89 +1,124 @@
1
- import { useAttendeesQuery as e, useRegistrationsQuery as t } from "../../api/eventApi.js";
2
- import { EntityListSection as n } from "./EntityListSection.js";
3
- import { useMemo as r } from "react";
4
- import { useParams as i } from "react-router-dom";
5
- import { jsx as a, jsxs as o } from "react/jsx-runtime";
1
+ import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
2
+ import { useAttendeesQuery as t, useRegistrationsQuery as n } from "../../api/eventApi.js";
3
+ import { EntityListSection as r } from "./EntityListSection.js";
4
+ import { useMemo as i } from "react";
5
+ import { useParams as a } from "react-router-dom";
6
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ import { Megaphone as c, Ticket as l, Users as u } from "lucide-react";
8
+ import { EmphasisPanel as d, GlassCard as f, GradientText as p, NextSteps as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
6
9
  //#region src/eventfullymanaged/pages/modules/AttendeeProfilePage.tsx
7
- function s() {
8
- let { id: s = "" } = i(), c = e({
10
+ function g() {
11
+ let { id: g = "" } = a(), { navigate: _ } = e(), v = t({
9
12
  limit: 100,
10
13
  offset: 0
11
- }), l = t({
14
+ }), y = n({
12
15
  limit: 100,
13
16
  offset: 0
14
- }), u = r(() => (c.data?.attendees.items ?? []).find((e) => e.id === s), [s, c.data]), d = r(() => (l.data?.registrations.items ?? []).filter((e) => e.attendeeId === s), [s, l.data]);
15
- return /* @__PURE__ */ o("div", {
17
+ }), b = i(() => (v.data?.attendees.items ?? []).find((e) => e.id === g), [g, v.data]), x = i(() => (y.data?.registrations.items ?? []).filter((e) => e.attendeeId === g), [g, y.data]);
18
+ return /* @__PURE__ */ s("div", {
16
19
  className: "space-y-6 p-6",
17
- children: [/* @__PURE__ */ o("section", {
18
- className: "rounded-lg border border-border-default bg-bg-surface p-5",
19
- children: [
20
- /* @__PURE__ */ a("h1", {
20
+ children: [
21
+ /* @__PURE__ */ o(h, { children: "A single view of one attendee — who they are and everything they have registered for. Use this when you need to look someone up: verify their ticket, answer a support question, or understand their history with your events before reaching out." }),
22
+ /* @__PURE__ */ s(d, { children: [
23
+ /* @__PURE__ */ s("h1", {
21
24
  className: "text-2xl font-bold text-text-primary",
22
- children: "Attendee Profile"
25
+ children: [/* @__PURE__ */ o(p, { children: "Attendee" }), " Profile"]
23
26
  }),
24
- /* @__PURE__ */ a("p", {
27
+ /* @__PURE__ */ o("p", {
25
28
  className: "mt-1 text-sm text-text-secondary",
26
- children: c.loading ? "Loading attendee profile..." : u ? `${u.fullName ?? u.id} profile from registration and attendee APIs.` : "Attendee not found in current query scope."
29
+ children: v.loading ? "Loading attendee profile..." : b ? `${b.fullName ?? b.id} profile from registration and attendee APIs.` : "Attendee not found in current query scope."
27
30
  }),
28
- u ? /* @__PURE__ */ o("div", {
31
+ b ? /* @__PURE__ */ s("div", {
29
32
  className: "mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4",
30
33
  children: [
31
- /* @__PURE__ */ o("div", {
32
- className: "rounded-md border border-border-default p-3",
33
- children: [/* @__PURE__ */ a("p", {
34
+ /* @__PURE__ */ s(f, {
35
+ treatment: "metric",
36
+ className: "p-3",
37
+ children: [/* @__PURE__ */ o("p", {
34
38
  className: "text-xs uppercase tracking-wide text-text-secondary",
35
39
  children: "Name"
36
- }), /* @__PURE__ */ a("p", {
40
+ }), /* @__PURE__ */ o("p", {
37
41
  className: "mt-1 font-medium text-text-primary",
38
- children: u.fullName ?? u.id
42
+ children: b.fullName ?? b.id
39
43
  })]
40
44
  }),
41
- /* @__PURE__ */ o("div", {
42
- className: "rounded-md border border-border-default p-3",
43
- children: [/* @__PURE__ */ a("p", {
45
+ /* @__PURE__ */ s(f, {
46
+ treatment: "metric",
47
+ className: "p-3",
48
+ children: [/* @__PURE__ */ o("p", {
44
49
  className: "text-xs uppercase tracking-wide text-text-secondary",
45
50
  children: "Email"
46
- }), /* @__PURE__ */ a("p", {
51
+ }), /* @__PURE__ */ o("p", {
47
52
  className: "mt-1 font-medium text-text-primary",
48
- children: u.email ?? "Unavailable"
53
+ children: b.email ?? "Unavailable"
49
54
  })]
50
55
  }),
51
- /* @__PURE__ */ o("div", {
52
- className: "rounded-md border border-border-default p-3",
53
- children: [/* @__PURE__ */ a("p", {
56
+ /* @__PURE__ */ s(f, {
57
+ treatment: "metric",
58
+ className: "p-3",
59
+ children: [/* @__PURE__ */ o("p", {
54
60
  className: "text-xs uppercase tracking-wide text-text-secondary",
55
61
  children: "Company"
56
- }), /* @__PURE__ */ a("p", {
62
+ }), /* @__PURE__ */ o("p", {
57
63
  className: "mt-1 font-medium text-text-primary",
58
- children: u.company ?? "Unavailable"
64
+ children: b.company ?? "Unavailable"
59
65
  })]
60
66
  }),
61
- /* @__PURE__ */ o("div", {
62
- className: "rounded-md border border-border-default p-3",
63
- children: [/* @__PURE__ */ a("p", {
67
+ /* @__PURE__ */ s(f, {
68
+ treatment: "metric",
69
+ className: "p-3",
70
+ children: [/* @__PURE__ */ o("p", {
64
71
  className: "text-xs uppercase tracking-wide text-text-secondary",
65
72
  children: "Role"
66
- }), /* @__PURE__ */ a("p", {
73
+ }), /* @__PURE__ */ o("p", {
67
74
  className: "mt-1 font-medium text-text-primary",
68
- children: u.role ?? "Unavailable"
75
+ children: b.role ?? "Unavailable"
69
76
  })]
70
77
  })
71
78
  ]
72
79
  }) : null
73
- ]
74
- }), /* @__PURE__ */ a(n, {
75
- heading: l.loading ? "Loading attendee registrations..." : `Registrations (${d.length})`,
76
- emptyLabel: "No registrations linked to this attendee.",
77
- rows: d.map((e) => ({
78
- id: e.id,
79
- title: `Registration ${e.id}`,
80
- subtitle: [e.quantity ? `Qty ${e.quantity}` : void 0, e.totalAmount ? `${e.totalAmount} ${e.currency ?? ""}` : void 0].filter(Boolean).join(" • "),
81
- status: e.status
82
- }))
83
- })]
80
+ ] }),
81
+ /* @__PURE__ */ o(r, {
82
+ heading: y.loading ? "Loading attendee registrations..." : `Registrations (${x.length})`,
83
+ emptyLabel: "No registrations linked to this attendee.",
84
+ rows: x.map((e) => ({
85
+ id: e.id,
86
+ title: `Registration ${e.id}`,
87
+ subtitle: [e.quantity ? `Qty ${e.quantity}` : void 0, e.totalAmount ? `${e.totalAmount} ${e.currency ?? ""}` : void 0].filter(Boolean).join(" • "),
88
+ status: e.status
89
+ }))
90
+ }),
91
+ /* @__PURE__ */ o(m, {
92
+ storageKey: "eventfullymanaged-attendee-profile",
93
+ title: "Act on this attendee",
94
+ steps: [
95
+ {
96
+ id: "view-registrations",
97
+ label: "Review all registrations",
98
+ description: "See the full registration list to manage tickets and payments.",
99
+ icon: /* @__PURE__ */ o(l, { className: "h-4 w-4" }),
100
+ onClick: () => _("/registration")
101
+ },
102
+ {
103
+ id: "networking",
104
+ label: "Find networking matches",
105
+ description: "Connect this attendee with relevant people and meetings.",
106
+ icon: /* @__PURE__ */ o(u, { className: "h-4 w-4" }),
107
+ onClick: () => _("/networking")
108
+ },
109
+ {
110
+ id: "reach-out",
111
+ label: "Send a message",
112
+ description: "Reach this attendee through an announcement or campaign.",
113
+ icon: /* @__PURE__ */ o(c, { className: "h-4 w-4" }),
114
+ onClick: () => _("/communication")
115
+ }
116
+ ]
117
+ })
118
+ ]
84
119
  });
85
120
  }
86
121
  //#endregion
87
- export { s as default };
122
+ export { g as default };
88
123
 
89
124
  //# sourceMappingURL=AttendeeProfilePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AttendeeProfilePage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/AttendeeProfilePage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { useAttendeesQuery, useRegistrationsQuery } from '../../api/eventApi';\nimport { EntityListSection } from './EntityListSection';\n\ntype AttendeeRow = {\n id: string;\n fullName?: string;\n email?: string;\n company?: string;\n role?: string;\n};\n\ntype RegistrationRow = {\n id: string;\n attendeeId?: string;\n status?: string;\n quantity?: number;\n currency?: string;\n totalAmount?: string;\n};\n\nexport default function AttendeeProfilePage() {\n const { id = '' } = useParams();\n const attendeesQuery = useAttendeesQuery({ limit: 100, offset: 0 });\n const registrationsQuery = useRegistrationsQuery({ limit: 100, offset: 0 });\n\n const attendee = useMemo(\n () => ((attendeesQuery.data?.attendees.items ?? []) as AttendeeRow[]).find((item) => item.id === id),\n [id, attendeesQuery.data]\n );\n const registrations = useMemo(\n () =>\n ((registrationsQuery.data?.registrations.items ?? []) as RegistrationRow[]).filter(\n (registration) => registration.attendeeId === id\n ),\n [id, registrationsQuery.data]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <section className=\"rounded-lg border border-border-default bg-bg-surface p-5\">\n <h1 className=\"text-2xl font-bold text-text-primary\">Attendee Profile</h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {attendeesQuery.loading\n ? 'Loading attendee profile...'\n : attendee\n ? `${attendee.fullName ?? attendee.id} profile from registration and attendee APIs.`\n : 'Attendee not found in current query scope.'}\n </p>\n {attendee ? (\n <div className=\"mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <div className=\"rounded-md border border-border-default p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Name</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.fullName ?? attendee.id}</p>\n </div>\n <div className=\"rounded-md border border-border-default p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Email</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.email ?? 'Unavailable'}</p>\n </div>\n <div className=\"rounded-md border border-border-default p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Company</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.company ?? 'Unavailable'}</p>\n </div>\n <div className=\"rounded-md border border-border-default p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Role</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.role ?? 'Unavailable'}</p>\n </div>\n </div>\n ) : null}\n </section>\n\n <EntityListSection\n heading={\n registrationsQuery.loading ? 'Loading attendee registrations...' : `Registrations (${registrations.length})`\n }\n emptyLabel=\"No registrations linked to this attendee.\"\n rows={registrations.map((registration) => ({\n id: registration.id,\n title: `Registration ${registration.id}`,\n subtitle: [\n registration.quantity ? `Qty ${registration.quantity}` : undefined,\n registration.totalAmount ? `${registration.totalAmount} ${registration.currency ?? ''}` : undefined,\n ]\n .filter(Boolean)\n .join(' • '),\n status: registration.status,\n }))}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;AAuBA,SAAwB,IAAsB;CAC5C,IAAM,EAAE,QAAK,OAAO,GAAW,EACzB,IAAiB,EAAkB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC7D,IAAqB,EAAsB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAErE,IAAW,SACP,EAAe,MAAM,UAAU,SAAS,EAAE,EAAoB,MAAM,MAAS,EAAK,OAAO,EAAG,EACpG,CAAC,GAAI,EAAe,KAAK,CAC1B,EACK,IAAgB,SAEhB,EAAmB,MAAM,cAAc,SAAS,EAAE,EAAwB,QACzE,MAAiB,EAAa,eAAe,EAC/C,EACH,CAAC,GAAI,EAAmB,KAAK,CAC9B;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,WAAD;GAAS,WAAU;aAAnB;IACE,kBAAC,MAAD;KAAI,WAAU;eAAuC;KAAqB,CAAA;IAC1E,kBAAC,KAAD;KAAG,WAAU;eACV,EAAe,UACZ,gCACA,IACE,GAAG,EAAS,YAAY,EAAS,GAAG,iDACpC;KACJ,CAAA;IACH,IACC,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAQ,CAAA,EAC3E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,YAAY,EAAS;QAAO,CAAA,CACpF;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAS,CAAA,EAC5E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,SAAS;QAAkB,CAAA,CACnF;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAW,CAAA,EAC9E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,WAAW;QAAkB,CAAA,CACrF;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAQ,CAAA,EAC3E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,QAAQ;QAAkB,CAAA,CAClF;;MACF;SACJ;IACI;MAEV,kBAAC,GAAD;GACE,SACE,EAAmB,UAAU,sCAAsC,kBAAkB,EAAc,OAAO;GAE5G,YAAW;GACX,MAAM,EAAc,KAAK,OAAkB;IACzC,IAAI,EAAa;IACjB,OAAO,gBAAgB,EAAa;IACpC,UAAU,CACR,EAAa,WAAW,OAAO,EAAa,aAAa,KAAA,GACzD,EAAa,cAAc,GAAG,EAAa,YAAY,GAAG,EAAa,YAAY,OAAO,KAAA,EAC3F,CACE,OAAO,QAAQ,CACf,KAAK,MAAM;IACd,QAAQ,EAAa;IACtB,EAAE;GACH,CAAA,CACE"}
1
+ {"version":3,"file":"AttendeeProfilePage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/AttendeeProfilePage.tsx"],"sourcesContent":["import { Megaphone, Ticket, Users } from 'lucide-react';\nimport { EmphasisPanel, GlassCard, GradientText, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { useAttendeesQuery, useRegistrationsQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { EntityListSection } from './EntityListSection';\n\ntype AttendeeRow = {\n id: string;\n fullName?: string;\n email?: string;\n company?: string;\n role?: string;\n};\n\ntype RegistrationRow = {\n id: string;\n attendeeId?: string;\n status?: string;\n quantity?: number;\n currency?: string;\n totalAmount?: string;\n};\n\nexport default function AttendeeProfilePage() {\n const { id = '' } = useParams();\n const { navigate } = useEventfullyManaged();\n const attendeesQuery = useAttendeesQuery({ limit: 100, offset: 0 });\n const registrationsQuery = useRegistrationsQuery({ limit: 100, offset: 0 });\n\n const attendee = useMemo(\n () => ((attendeesQuery.data?.attendees.items ?? []) as AttendeeRow[]).find((item) => item.id === id),\n [id, attendeesQuery.data]\n );\n const registrations = useMemo(\n () =>\n ((registrationsQuery.data?.registrations.items ?? []) as RegistrationRow[]).filter(\n (registration) => registration.attendeeId === id\n ),\n [id, registrationsQuery.data]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n A single view of one attendee — who they are and everything they have registered for. Use this when you need\n to look someone up: verify their ticket, answer a support question, or understand their history with your\n events before reaching out.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Attendee</GradientText> Profile\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {attendeesQuery.loading\n ? 'Loading attendee profile...'\n : attendee\n ? `${attendee.fullName ?? attendee.id} profile from registration and attendee APIs.`\n : 'Attendee not found in current query scope.'}\n </p>\n {attendee ? (\n <div className=\"mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Name</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.fullName ?? attendee.id}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Email</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.email ?? 'Unavailable'}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Company</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.company ?? 'Unavailable'}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Role</p>\n <p className=\"mt-1 font-medium text-text-primary\">{attendee.role ?? 'Unavailable'}</p>\n </GlassCard>\n </div>\n ) : null}\n </EmphasisPanel>\n\n <EntityListSection\n heading={\n registrationsQuery.loading ? 'Loading attendee registrations...' : `Registrations (${registrations.length})`\n }\n emptyLabel=\"No registrations linked to this attendee.\"\n rows={registrations.map((registration) => ({\n id: registration.id,\n title: `Registration ${registration.id}`,\n subtitle: [\n registration.quantity ? `Qty ${registration.quantity}` : undefined,\n registration.totalAmount ? `${registration.totalAmount} ${registration.currency ?? ''}` : undefined,\n ]\n .filter(Boolean)\n .join(' • '),\n status: registration.status,\n }))}\n />\n\n <NextSteps\n storageKey=\"eventfullymanaged-attendee-profile\"\n title=\"Act on this attendee\"\n steps={[\n {\n id: 'view-registrations',\n label: 'Review all registrations',\n description: 'See the full registration list to manage tickets and payments.',\n icon: <Ticket className=\"h-4 w-4\" />,\n onClick: () => navigate('/registration'),\n },\n {\n id: 'networking',\n label: 'Find networking matches',\n description: 'Connect this attendee with relevant people and meetings.',\n icon: <Users className=\"h-4 w-4\" />,\n onClick: () => navigate('/networking'),\n },\n {\n id: 'reach-out',\n label: 'Send a message',\n description: 'Reach this attendee through an announcement or campaign.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AA0BA,SAAwB,IAAsB;CAC5C,IAAM,EAAE,QAAK,OAAO,GAAW,EACzB,EAAE,gBAAa,GAAsB,EACrC,IAAiB,EAAkB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC7D,IAAqB,EAAsB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAErE,IAAW,SACP,EAAe,MAAM,UAAU,SAAS,EAAE,EAAoB,MAAM,MAAS,EAAK,OAAO,EAAG,EACpG,CAAC,GAAI,EAAe,KAAK,CAC1B,EACK,IAAgB,SAEhB,EAAmB,MAAM,cAAc,SAAS,EAAE,EAAwB,QACzE,MAAiB,EAAa,eAAe,EAC/C,EACH,CAAC,GAAI,EAAmB,KAAK,CAC9B;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UAAa,sPAIC,CAAA;GAEd,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAA,UAAc,YAAuB,CAAA,EAAA,WAClC;;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAe,UACZ,gCACA,IACE,GAAG,EAAS,YAAY,EAAS,GAAG,iDACpC;KACJ,CAAA;IACH,IACC,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAQ,CAAA,EAC3E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,YAAY,EAAS;QAAO,CAAA,CAC9E;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAS,CAAA,EAC5E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,SAAS;QAAkB,CAAA,CAC7E;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAW,CAAA,EAC9E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,WAAW;QAAkB,CAAA,CAC/E;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAQ,CAAA,EAC3E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAS,QAAQ;QAAkB,CAAA,CAC5E;;MACR;SACJ;IACU,EAAA,CAAA;GAEhB,kBAAC,GAAD;IACE,SACE,EAAmB,UAAU,sCAAsC,kBAAkB,EAAc,OAAO;IAE5G,YAAW;IACX,MAAM,EAAc,KAAK,OAAkB;KACzC,IAAI,EAAa;KACjB,OAAO,gBAAgB,EAAa;KACpC,UAAU,CACR,EAAa,WAAW,OAAO,EAAa,aAAa,KAAA,GACzD,EAAa,cAAc,GAAG,EAAa,YAAY,GAAG,EAAa,YAAY,OAAO,KAAA,EAC3F,CACE,OAAO,QAAQ,CACf,KAAK,MAAM;KACd,QAAQ,EAAa;KACtB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,YAAW;IACX,OAAM;IACN,OAAO;KACL;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;MACpC,eAAe,EAAS,gBAAgB;MACzC;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;MACnC,eAAe,EAAS,cAAc;MACvC;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MACvC,eAAe,EAAS,iBAAiB;MAC1C;KACF;IACD,CAAA;GACE"}
@@ -4,71 +4,70 @@ import { useMemo as i, useState as a } from "react";
4
4
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
5
  import { Megaphone as c } from "lucide-react";
6
6
  import { useI18n as l } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
+ import { Button as u, EmphasisPanel as d, GradientText as f, Input as p, PagePurpose as m } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/eventfullymanaged/pages/modules/CommunicationPage.tsx
8
- function u() {
9
- let { t: u } = l(), d = (e, t) => {
10
- let n = u(e);
9
+ function h() {
10
+ let { t: h } = l(), g = (e, t) => {
11
+ let n = h(e);
11
12
  return n === e ? t : n;
12
- }, f = e({
13
+ }, _ = e({
13
14
  limit: 100,
14
15
  offset: 0
15
- }), p = t({
16
+ }), v = t({
16
17
  limit: 100,
17
18
  offset: 0
18
- }), [m, { loading: h }] = n(), [g, _] = a(""), v = i(() => f.data?.announcements.items ?? [], [f.data]), y = i(() => p.data?.communicationCampaigns.items ?? [], [p.data]);
19
+ }), [y, { loading: b }] = n(), [x, S] = a(""), C = i(() => _.data?.announcements.items ?? [], [_.data]), w = i(() => v.data?.communicationCampaigns.items ?? [], [v.data]);
19
20
  return /* @__PURE__ */ s("div", {
20
21
  className: "space-y-6 p-6",
21
22
  children: [
22
- /* @__PURE__ */ s("section", {
23
- className: "rounded-lg border border-border-default bg-bg-surface p-5",
24
- children: [
25
- /* @__PURE__ */ o("h1", {
26
- className: "text-2xl font-bold text-text-primary",
27
- children: d("eventfullymanaged.communication.title", "Communication")
28
- }),
29
- /* @__PURE__ */ o("p", {
30
- className: "mt-1 text-sm text-text-secondary",
31
- children: d("eventfullymanaged.communication.description", "Announcements and campaigns managed via workspace APIs.")
32
- }),
33
- /* @__PURE__ */ s("div", {
34
- className: "mt-4 flex flex-col gap-3 sm:flex-row",
35
- children: [/* @__PURE__ */ o("input", {
36
- value: g,
37
- onChange: (e) => _(e.target.value),
38
- placeholder: d("eventfullymanaged.communication.inputPlaceholder", "Emergency schedule update"),
39
- className: "flex-1 rounded-md border border-border-default px-3 py-2"
40
- }), /* @__PURE__ */ s("button", {
41
- type: "button",
42
- disabled: h,
43
- onClick: async () => {
44
- g.trim() && (await m({ variables: { input: {
45
- title: g,
46
- name: g,
47
- status: "draft",
48
- metadata: {}
49
- } } }), _(""));
50
- },
51
- className: "inline-flex items-center rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-60",
52
- children: [/* @__PURE__ */ o(c, { className: "mr-2 h-4 w-4" }), h ? d("eventfullymanaged.communication.actions.creating", "Creating...") : d("eventfullymanaged.communication.actions.createAnnouncement", "Create Announcement")]
53
- })]
54
- })
55
- ]
56
- }),
23
+ /* @__PURE__ */ o(m, { children: g("eventfullymanaged.communication.purpose", "Keep attendees informed and engaged. Announcements are one-off broadcasts (a schedule change, a welcome message); campaigns are scheduled, multi-step outreach (reminder emails, follow-ups). Use this page to draft and publish everything you need to say before, during and after an event.") }),
24
+ /* @__PURE__ */ s(d, { children: [
25
+ /* @__PURE__ */ o("h1", {
26
+ className: "text-2xl font-bold text-text-primary",
27
+ children: /* @__PURE__ */ o(f, { children: g("eventfullymanaged.communication.title", "Communication") })
28
+ }),
29
+ /* @__PURE__ */ o("p", {
30
+ className: "mt-1 text-sm text-text-secondary",
31
+ children: g("eventfullymanaged.communication.description", "Announcements and campaigns managed via workspace APIs.")
32
+ }),
33
+ /* @__PURE__ */ s("div", {
34
+ className: "mt-4 flex flex-col gap-3 sm:flex-row",
35
+ children: [/* @__PURE__ */ o(p, {
36
+ value: x,
37
+ onChange: (e) => S(e.target.value),
38
+ placeholder: g("eventfullymanaged.communication.inputPlaceholder", "Emergency schedule update"),
39
+ "aria-label": g("eventfullymanaged.communication.inputPlaceholder", "Emergency schedule update"),
40
+ className: "flex-1"
41
+ }), /* @__PURE__ */ s(u, {
42
+ type: "button",
43
+ disabled: b,
44
+ onClick: async () => {
45
+ x.trim() && (await y({ variables: { input: {
46
+ title: x,
47
+ name: x,
48
+ status: "draft",
49
+ metadata: {}
50
+ } } }), S(""));
51
+ },
52
+ children: [/* @__PURE__ */ o(c, { className: "h-4 w-4" }), b ? g("eventfullymanaged.communication.actions.creating", "Creating...") : g("eventfullymanaged.communication.actions.createAnnouncement", "Create Announcement")]
53
+ })]
54
+ })
55
+ ] }),
57
56
  /* @__PURE__ */ o(r, {
58
- heading: f.loading ? d("eventfullymanaged.communication.announcements.loading", "Loading announcements...") : `${d("eventfullymanaged.communication.announcements.heading", "Announcements")} (${v.length})`,
59
- emptyLabel: d("eventfullymanaged.communication.announcements.empty", "No announcements published yet."),
60
- rows: v.map((e) => ({
57
+ heading: _.loading ? g("eventfullymanaged.communication.announcements.loading", "Loading announcements...") : `${g("eventfullymanaged.communication.announcements.heading", "Announcements")} (${C.length})`,
58
+ emptyLabel: g("eventfullymanaged.communication.announcements.empty", "No announcements published yet."),
59
+ rows: C.map((e) => ({
61
60
  id: e.id,
62
- title: e.title ?? e.name ?? `${d("eventfullymanaged.communication.announcements.itemPrefix", "Announcement")} ${e.id}`,
61
+ title: e.title ?? e.name ?? `${g("eventfullymanaged.communication.announcements.itemPrefix", "Announcement")} ${e.id}`,
63
62
  status: e.status ?? void 0
64
63
  }))
65
64
  }),
66
65
  /* @__PURE__ */ o(r, {
67
- heading: p.loading ? d("eventfullymanaged.communication.campaigns.loading", "Loading campaigns...") : `${d("eventfullymanaged.communication.campaigns.heading", "Campaigns")} (${y.length})`,
68
- emptyLabel: d("eventfullymanaged.communication.campaigns.empty", "No communication campaigns created yet."),
69
- rows: y.map((e) => ({
66
+ heading: v.loading ? g("eventfullymanaged.communication.campaigns.loading", "Loading campaigns...") : `${g("eventfullymanaged.communication.campaigns.heading", "Campaigns")} (${w.length})`,
67
+ emptyLabel: g("eventfullymanaged.communication.campaigns.empty", "No communication campaigns created yet."),
68
+ rows: w.map((e) => ({
70
69
  id: e.id,
71
- title: e.title ?? e.name ?? `${d("eventfullymanaged.communication.campaigns.itemPrefix", "Campaign")} ${e.id}`,
70
+ title: e.title ?? e.name ?? `${g("eventfullymanaged.communication.campaigns.itemPrefix", "Campaign")} ${e.id}`,
72
71
  status: e.status ?? void 0
73
72
  }))
74
73
  })
@@ -76,6 +75,6 @@ function u() {
76
75
  });
77
76
  }
78
77
  //#endregion
79
- export { u as default };
78
+ export { h as default };
80
79
 
81
80
  //# sourceMappingURL=CommunicationPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommunicationPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/CommunicationPage.tsx"],"sourcesContent":["import { Megaphone } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useMemo, useState } from 'react';\n\nimport {\n useAnnouncementsQuery,\n useCommunicationCampaignsQuery,\n useUpsertAnnouncementMutation,\n} from '../../api/eventApi';\nimport { EntityListSection } from './EntityListSection';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function CommunicationPage() {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const announcementsQuery = useAnnouncementsQuery({ limit: 100, offset: 0 });\n const campaignsQuery = useCommunicationCampaignsQuery({ limit: 100, offset: 0 });\n const [createAnnouncement, { loading: creating }] = useUpsertAnnouncementMutation();\n const [announcementTitle, setAnnouncementTitle] = useState('');\n\n const announcements = useMemo(\n () => (announcementsQuery.data?.announcements.items ?? []) as SimpleRow[],\n [announcementsQuery.data]\n );\n const campaigns = useMemo(\n () => (campaignsQuery.data?.communicationCampaigns.items ?? []) as SimpleRow[],\n [campaignsQuery.data]\n );\n\n const onCreate = async () => {\n if (!announcementTitle.trim()) return;\n await createAnnouncement({\n variables: {\n input: {\n title: announcementTitle,\n name: announcementTitle,\n status: 'draft',\n metadata: {},\n },\n },\n });\n setAnnouncementTitle('');\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <section className=\"rounded-lg border border-border-default bg-bg-surface p-5\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n {t('eventfullymanaged.communication.title', 'Communication')}\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t('eventfullymanaged.communication.description', 'Announcements and campaigns managed via workspace APIs.')}\n </p>\n <div className=\"mt-4 flex flex-col gap-3 sm:flex-row\">\n <input\n value={announcementTitle}\n onChange={(e) => setAnnouncementTitle(e.target.value)}\n placeholder={t('eventfullymanaged.communication.inputPlaceholder', 'Emergency schedule update')}\n className=\"flex-1 rounded-md border border-border-default px-3 py-2\"\n />\n <button\n type=\"button\"\n disabled={creating}\n onClick={onCreate}\n className=\"inline-flex items-center rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-60\"\n >\n <Megaphone className=\"mr-2 h-4 w-4\" />\n {creating\n ? t('eventfullymanaged.communication.actions.creating', 'Creating...')\n : t('eventfullymanaged.communication.actions.createAnnouncement', 'Create Announcement')}\n </button>\n </div>\n </section>\n\n <EntityListSection\n heading={\n announcementsQuery.loading\n ? t('eventfullymanaged.communication.announcements.loading', 'Loading announcements...')\n : `${t('eventfullymanaged.communication.announcements.heading', 'Announcements')} (${announcements.length})`\n }\n emptyLabel={t('eventfullymanaged.communication.announcements.empty', 'No announcements published yet.')}\n rows={announcements.map((row) => ({\n id: row.id,\n title:\n row.title ??\n row.name ??\n `${t('eventfullymanaged.communication.announcements.itemPrefix', 'Announcement')} ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={\n campaignsQuery.loading\n ? t('eventfullymanaged.communication.campaigns.loading', 'Loading campaigns...')\n : `${t('eventfullymanaged.communication.campaigns.heading', 'Campaigns')} (${campaigns.length})`\n }\n emptyLabel={t('eventfullymanaged.communication.campaigns.empty', 'No communication campaigns created yet.')}\n rows={campaigns.map((row) => ({\n id: row.id,\n title:\n row.title ??\n row.name ??\n `${t('eventfullymanaged.communication.campaigns.itemPrefix', 'Campaign')} ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;AAkBA,SAAwB,IAAoB;CAC1C,IAAM,EAAE,GAAG,MAAc,GAAS,EAC5B,KAAK,GAAa,MAAqB;EAC3C,IAAM,IAAQ,EAAU,EAAI;AAC5B,SAAO,MAAU,IAAM,IAAW;IAE9B,IAAqB,EAAsB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EACrE,IAAiB,EAA+B;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC1E,CAAC,GAAoB,EAAE,SAAS,OAAc,GAA+B,EAC7E,CAAC,GAAmB,KAAwB,EAAS,GAAG,EAExD,IAAgB,QACb,EAAmB,MAAM,cAAc,SAAS,EAAE,EACzD,CAAC,EAAmB,KAAK,CAC1B,EACK,IAAY,QACT,EAAe,MAAM,uBAAuB,SAAS,EAAE,EAC9D,CAAC,EAAe,KAAK,CACtB;AAiBD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,WAAD;IAAS,WAAU;cAAnB;KACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAE,yCAAyC,gBAAgB;MACzD,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAE,+CAA+C,0DAA0D;MAC1G,CAAA;KACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAqB,EAAE,OAAO,MAAM;OACrD,aAAa,EAAE,oDAAoD,4BAA4B;OAC/F,WAAU;OACV,CAAA,EACF,kBAAC,UAAD;OACE,MAAK;OACL,UAAU;OACV,SAlCO,YAAY;AACtB,UAAkB,MAAM,KAC7B,MAAM,EAAmB,EACvB,WAAW,EACT,OAAO;SACL,OAAO;SACP,MAAM;SACN,QAAQ;SACR,UAAU,EAAE;SACb,EACF,EACF,CAAC,EACF,EAAqB,GAAG;;OAuBhB,WAAU;iBAJZ,CAME,kBAAC,GAAD,EAAW,WAAU,gBAAiB,CAAA,EACrC,IACG,EAAE,oDAAoD,cAAc,GACpE,EAAE,8DAA8D,sBAAsB,CACnF;SACL;;KACE;;GAEV,kBAAC,GAAD;IACE,SACE,EAAmB,UACf,EAAE,yDAAyD,2BAA2B,GACtF,GAAG,EAAE,yDAAyD,gBAAgB,CAAC,IAAI,EAAc,OAAO;IAE9G,YAAY,EAAE,uDAAuD,kCAAkC;IACvG,MAAM,EAAc,KAAK,OAAS;KAChC,IAAI,EAAI;KACR,OACE,EAAI,SACJ,EAAI,QACJ,GAAG,EAAE,4DAA4D,eAAe,CAAC,GAAG,EAAI;KAC1F,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,SACE,EAAe,UACX,EAAE,qDAAqD,uBAAuB,GAC9E,GAAG,EAAE,qDAAqD,YAAY,CAAC,IAAI,EAAU,OAAO;IAElG,YAAY,EAAE,mDAAmD,0CAA0C;IAC3G,MAAM,EAAU,KAAK,OAAS;KAC5B,IAAI,EAAI;KACR,OACE,EAAI,SACJ,EAAI,QACJ,GAAG,EAAE,wDAAwD,WAAW,CAAC,GAAG,EAAI;KAClF,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GACE"}
1
+ {"version":3,"file":"CommunicationPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/CommunicationPage.tsx"],"sourcesContent":["import { Megaphone } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Button, EmphasisPanel, GradientText, Input, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\n\nimport {\n useAnnouncementsQuery,\n useCommunicationCampaignsQuery,\n useUpsertAnnouncementMutation,\n} from '../../api/eventApi';\nimport { EntityListSection } from './EntityListSection';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function CommunicationPage() {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string) => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const announcementsQuery = useAnnouncementsQuery({ limit: 100, offset: 0 });\n const campaignsQuery = useCommunicationCampaignsQuery({ limit: 100, offset: 0 });\n const [createAnnouncement, { loading: creating }] = useUpsertAnnouncementMutation();\n const [announcementTitle, setAnnouncementTitle] = useState('');\n\n const announcements = useMemo(\n () => (announcementsQuery.data?.announcements.items ?? []) as SimpleRow[],\n [announcementsQuery.data]\n );\n const campaigns = useMemo(\n () => (campaignsQuery.data?.communicationCampaigns.items ?? []) as SimpleRow[],\n [campaignsQuery.data]\n );\n\n const onCreate = async () => {\n if (!announcementTitle.trim()) return;\n await createAnnouncement({\n variables: {\n input: {\n title: announcementTitle,\n name: announcementTitle,\n status: 'draft',\n metadata: {},\n },\n },\n });\n setAnnouncementTitle('');\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n {t(\n 'eventfullymanaged.communication.purpose',\n 'Keep attendees informed and engaged. Announcements are one-off broadcasts (a schedule change, a welcome message); campaigns are scheduled, multi-step outreach (reminder emails, follow-ups). Use this page to draft and publish everything you need to say before, during and after an event.'\n )}\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>{t('eventfullymanaged.communication.title', 'Communication')}</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t('eventfullymanaged.communication.description', 'Announcements and campaigns managed via workspace APIs.')}\n </p>\n <div className=\"mt-4 flex flex-col gap-3 sm:flex-row\">\n <Input\n value={announcementTitle}\n onChange={(e) => setAnnouncementTitle(e.target.value)}\n placeholder={t('eventfullymanaged.communication.inputPlaceholder', 'Emergency schedule update')}\n aria-label={t('eventfullymanaged.communication.inputPlaceholder', 'Emergency schedule update')}\n className=\"flex-1\"\n />\n <Button type=\"button\" disabled={creating} onClick={onCreate}>\n <Megaphone className=\"h-4 w-4\" />\n {creating\n ? t('eventfullymanaged.communication.actions.creating', 'Creating...')\n : t('eventfullymanaged.communication.actions.createAnnouncement', 'Create Announcement')}\n </Button>\n </div>\n </EmphasisPanel>\n\n <EntityListSection\n heading={\n announcementsQuery.loading\n ? t('eventfullymanaged.communication.announcements.loading', 'Loading announcements...')\n : `${t('eventfullymanaged.communication.announcements.heading', 'Announcements')} (${announcements.length})`\n }\n emptyLabel={t('eventfullymanaged.communication.announcements.empty', 'No announcements published yet.')}\n rows={announcements.map((row) => ({\n id: row.id,\n title:\n row.title ??\n row.name ??\n `${t('eventfullymanaged.communication.announcements.itemPrefix', 'Announcement')} ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={\n campaignsQuery.loading\n ? t('eventfullymanaged.communication.campaigns.loading', 'Loading campaigns...')\n : `${t('eventfullymanaged.communication.campaigns.heading', 'Campaigns')} (${campaigns.length})`\n }\n emptyLabel={t('eventfullymanaged.communication.campaigns.empty', 'No communication campaigns created yet.')}\n rows={campaigns.map((row) => ({\n id: row.id,\n title:\n row.title ??\n row.name ??\n `${t('eventfullymanaged.communication.campaigns.itemPrefix', 'Campaign')} ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAmBA,SAAwB,IAAoB;CAC1C,IAAM,EAAE,GAAG,MAAc,GAAS,EAC5B,KAAK,GAAa,MAAqB;EAC3C,IAAM,IAAQ,EAAU,EAAI;AAC5B,SAAO,MAAU,IAAM,IAAW;IAE9B,IAAqB,EAAsB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EACrE,IAAiB,EAA+B;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC1E,CAAC,GAAoB,EAAE,SAAS,OAAc,GAA+B,EAC7E,CAAC,GAAmB,KAAwB,EAAS,GAAG,EAExD,IAAgB,QACb,EAAmB,MAAM,cAAc,SAAS,EAAE,EACzD,CAAC,EAAmB,KAAK,CAC1B,EACK,IAAY,QACT,EAAe,MAAM,uBAAuB,SAAS,EAAE,EAC9D,CAAC,EAAe,KAAK,CACtB;AAiBD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UACG,EACC,2CACA,iSACD,EACW,CAAA;GAEd,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAe,EAAE,yCAAyC,gBAAgB,EAAgB,CAAA;KACvF,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAE,+CAA+C,0DAA0D;KAC1G,CAAA;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAqB,EAAE,OAAO,MAAM;MACrD,aAAa,EAAE,oDAAoD,4BAA4B;MAC/F,cAAY,EAAE,oDAAoD,4BAA4B;MAC9F,WAAU;MACV,CAAA,EACF,kBAAC,GAAD;MAAQ,MAAK;MAAS,UAAU;MAAU,SAvCjC,YAAY;AACtB,SAAkB,MAAM,KAC7B,MAAM,EAAmB,EACvB,WAAW,EACT,OAAO;QACL,OAAO;QACP,MAAM;QACN,QAAQ;QACR,UAAU,EAAE;QACb,EACF,EACF,CAAC,EACF,EAAqB,GAAG;;gBA2BlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAChC,IACG,EAAE,oDAAoD,cAAc,GACpE,EAAE,8DAA8D,sBAAsB,CACnF;QACL;;IACQ,EAAA,CAAA;GAEhB,kBAAC,GAAD;IACE,SACE,EAAmB,UACf,EAAE,yDAAyD,2BAA2B,GACtF,GAAG,EAAE,yDAAyD,gBAAgB,CAAC,IAAI,EAAc,OAAO;IAE9G,YAAY,EAAE,uDAAuD,kCAAkC;IACvG,MAAM,EAAc,KAAK,OAAS;KAChC,IAAI,EAAI;KACR,OACE,EAAI,SACJ,EAAI,QACJ,GAAG,EAAE,4DAA4D,eAAe,CAAC,GAAG,EAAI;KAC1F,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,SACE,EAAe,UACX,EAAE,qDAAqD,uBAAuB,GAC9E,GAAG,EAAE,qDAAqD,YAAY,CAAC,IAAI,EAAU,OAAO;IAElG,YAAY,EAAE,mDAAmD,0CAA0C;IAC3G,MAAM,EAAU,KAAK,OAAS;KAC5B,IAAI,EAAI;KACR,OACE,EAAI,SACJ,EAAI,QACJ,GAAG,EAAE,wDAAwD,WAAW,CAAC,GAAG,EAAI;KAClF,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GACE"}
@@ -1,36 +1,68 @@
1
1
  import { jsx as e, jsxs as t } from "react/jsx-runtime";
2
+ import { Badge as n, GlassCard as r, IllustratedEmptyState as i } from "@burdenoff/fe-libs/ui";
2
3
  //#region src/eventfullymanaged/pages/modules/EntityListSection.tsx
3
- function n({ heading: n, rows: r, emptyLabel: i }) {
4
- return /* @__PURE__ */ t("section", {
5
- className: "rounded-lg border border-border-default bg-bg-surface p-5",
4
+ function a(e) {
5
+ let t = e.toLowerCase();
6
+ return [
7
+ "active",
8
+ "published",
9
+ "live",
10
+ "confirmed",
11
+ "completed",
12
+ "approved"
13
+ ].includes(t) ? "success" : [
14
+ "inactive",
15
+ "cancelled",
16
+ "archived",
17
+ "closed",
18
+ "expired"
19
+ ].includes(t) ? "warning" : [
20
+ "draft",
21
+ "created",
22
+ "pending",
23
+ "scheduled"
24
+ ].includes(t) ? "info" : "secondary";
25
+ }
26
+ function o({ heading: o, rows: s, emptyLabel: c, emptyIllustration: l = "empty-data" }) {
27
+ return /* @__PURE__ */ t(r, {
28
+ treatment: "plain",
29
+ className: "border-border-seam p-5",
6
30
  children: [/* @__PURE__ */ e("h2", {
7
31
  className: "text-lg font-semibold text-text-primary",
8
- children: n
32
+ children: o
9
33
  }), /* @__PURE__ */ e("div", {
10
- className: "mt-4 space-y-3",
11
- children: r.length === 0 ? /* @__PURE__ */ e("p", {
12
- className: "text-sm text-text-secondary",
13
- children: i
14
- }) : r.map((n) => /* @__PURE__ */ e("div", {
15
- className: "rounded-md border border-border-default p-3",
16
- children: /* @__PURE__ */ t("div", {
17
- className: "flex items-center justify-between gap-3",
18
- children: [/* @__PURE__ */ t("div", { children: [/* @__PURE__ */ e("p", {
19
- className: "font-medium text-text-primary",
20
- children: n.title
21
- }), n.subtitle ? /* @__PURE__ */ e("p", {
22
- className: "text-sm text-text-secondary",
23
- children: n.subtitle
24
- }) : null] }), n.status ? /* @__PURE__ */ e("span", {
25
- className: "rounded-full bg-gray-100 px-2 py-1 text-xs font-medium uppercase text-text-primary",
26
- children: n.status
27
- }) : null]
28
- })
29
- }, n.id))
34
+ className: "mt-4",
35
+ children: s.length === 0 ? /* @__PURE__ */ e(i, {
36
+ illustration: l,
37
+ title: c,
38
+ className: "py-8"
39
+ }) : /* @__PURE__ */ e("ul", {
40
+ className: "space-y-2.5",
41
+ children: s.map((r) => /* @__PURE__ */ e("li", {
42
+ 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",
43
+ children: /* @__PURE__ */ t("div", {
44
+ className: "flex items-center justify-between gap-3",
45
+ children: [/* @__PURE__ */ t("div", {
46
+ className: "min-w-0",
47
+ children: [/* @__PURE__ */ e("p", {
48
+ className: "truncate font-medium text-text-primary",
49
+ children: r.title
50
+ }), r.subtitle ? /* @__PURE__ */ e("p", {
51
+ className: "mt-0.5 truncate text-sm text-text-secondary",
52
+ children: r.subtitle
53
+ }) : null]
54
+ }), r.status ? /* @__PURE__ */ e(n, {
55
+ variant: a(r.status),
56
+ className: "shrink-0 uppercase",
57
+ children: r.status
58
+ }) : null]
59
+ })
60
+ }, r.id))
61
+ })
30
62
  })]
31
63
  });
32
64
  }
33
65
  //#endregion
34
- export { n as EntityListSection };
66
+ export { o as EntityListSection };
35
67
 
36
68
  //# sourceMappingURL=EntityListSection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EntityListSection.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/EntityListSection.tsx"],"sourcesContent":["type EntityRow = {\n id: string;\n title: string;\n subtitle?: string;\n status?: string;\n};\n\ninterface EntityListSectionProps {\n heading: string;\n rows: EntityRow[];\n emptyLabel: string;\n}\n\nexport function EntityListSection({ heading, rows, emptyLabel }: EntityListSectionProps) {\n return (\n <section className=\"rounded-lg border border-border-default bg-bg-surface p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{heading}</h2>\n <div className=\"mt-4 space-y-3\">\n {rows.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">{emptyLabel}</p>\n ) : (\n rows.map((row) => (\n <div key={row.id} className=\"rounded-md border border-border-default p-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <p className=\"font-medium text-text-primary\">{row.title}</p>\n {row.subtitle ? <p className=\"text-sm text-text-secondary\">{row.subtitle}</p> : null}\n </div>\n {row.status ? (\n <span className=\"rounded-full bg-gray-100 px-2 py-1 text-xs font-medium uppercase text-text-primary\">\n {row.status}\n </span>\n ) : null}\n </div>\n </div>\n ))\n )}\n </div>\n </section>\n );\n}\n"],"mappings":";;AAaA,SAAgB,EAAkB,EAAE,YAAS,SAAM,iBAAsC;AACvF,QACE,kBAAC,WAAD;EAAS,WAAU;YAAnB,CACE,kBAAC,MAAD;GAAI,WAAU;aAA2C;GAAa,CAAA,EACtE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAK,WAAW,IACf,kBAAC,KAAD;IAAG,WAAU;cAA+B;IAAe,CAAA,GAE3D,EAAK,KAAK,MACR,kBAAC,OAAD;IAAkB,WAAU;cAC1B,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAiC,EAAI;MAAU,CAAA,EAC3D,EAAI,WAAW,kBAAC,KAAD;MAAG,WAAU;gBAA+B,EAAI;MAAa,CAAA,GAAG,KAC5E,EAAA,CAAA,EACL,EAAI,SACH,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAI;MACA,CAAA,GACL,KACA;;IACF,EAZI,EAAI,GAYR,CACN;GAEA,CAAA,CACE"}
1
+ {"version":3,"file":"EntityListSection.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/EntityListSection.tsx"],"sourcesContent":["import { Badge, GlassCard, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\n\ntype EntityRow = {\n id: string;\n title: string;\n subtitle?: string;\n status?: string;\n};\n\ninterface EntityListSectionProps {\n heading: string;\n rows: EntityRow[];\n emptyLabel: string;\n /** Illustration used for the zero-state. Defaults to a generic data illustration. */\n emptyIllustration?: string;\n}\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\nexport function EntityListSection({\n heading,\n rows,\n emptyLabel,\n emptyIllustration = 'empty-data',\n}: EntityListSectionProps) {\n return (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{heading}</h2>\n <div className=\"mt-4\">\n {rows.length === 0 ? (\n <IllustratedEmptyState illustration={emptyIllustration} title={emptyLabel} className=\"py-8\" />\n ) : (\n <ul className=\"space-y-2.5\">\n {rows.map((row) => (\n <li\n key={row.id}\n className=\"rounded-card border border-border-seam bg-bg-surface p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1\"\n >\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{row.title}</p>\n {row.subtitle ? (\n <p className=\"mt-0.5 truncate text-sm text-text-secondary\">{row.subtitle}</p>\n ) : null}\n </div>\n {row.status ? (\n <Badge variant={statusVariant(row.status)} className=\"shrink-0 uppercase\">\n {row.status}\n </Badge>\n ) : null}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n );\n}\n"],"mappings":";;;AAiBA,SAAS,EAAc,GAA8D;CACnF,IAAM,IAAQ,EAAO,aAAa;AAUlC,QATI;EAAC;EAAU;EAAa;EAAQ;EAAa;EAAa;EAAW,CAAC,SAAS,EAAM,GAChF,YAEL;EAAC;EAAY;EAAa;EAAY;EAAU;EAAU,CAAC,SAAS,EAAM,GACrE,YAEL;EAAC;EAAS;EAAW;EAAW;EAAY,CAAC,SAAS,EAAM,GACvD,SAEF;;AAGT,SAAgB,EAAkB,EAChC,YACA,SACA,eACA,uBAAoB,gBACK;AACzB,QACE,kBAAC,GAAD;EAAW,WAAU;EAAQ,WAAU;YAAvC,CACE,kBAAC,MAAD;GAAI,WAAU;aAA2C;GAAa,CAAA,EACtE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAK,WAAW,IACf,kBAAC,GAAD;IAAuB,cAAc;IAAmB,OAAO;IAAY,WAAU;IAAS,CAAA,GAE9F,kBAAC,MAAD;IAAI,WAAU;cACX,EAAK,KAAK,MACT,kBAAC,MAAD;KAEE,WAAU;eAEV,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAA0C,EAAI;QAAU,CAAA,EACpE,EAAI,WACH,kBAAC,KAAD;QAAG,WAAU;kBAA+C,EAAI;QAAa,CAAA,GAC3E,KACA;UACL,EAAI,SACH,kBAAC,GAAD;OAAO,SAAS,EAAc,EAAI,OAAO;OAAE,WAAU;iBAClD,EAAI;OACC,CAAA,GACN,KACA;;KACH,EAhBE,EAAI,GAgBN,CACL;IACC,CAAA;GAEH,CAAA,CACI"}