@burdenoff/microfe-eventfullymanaged 2026.625.2 → 2026.703.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/api/eventApi.js +83 -39
  2. package/dist/eventfullymanaged/api/eventApi.js.map +1 -1
  3. package/dist/eventfullymanaged/components/ImageUploadField.js +98 -0
  4. package/dist/eventfullymanaged/components/ImageUploadField.js.map +1 -0
  5. package/dist/eventfullymanaged/lib/mutationResult.js +12 -0
  6. package/dist/eventfullymanaged/lib/mutationResult.js.map +1 -0
  7. package/dist/eventfullymanaged/lib/toast.js +36 -0
  8. package/dist/eventfullymanaged/lib/toast.js.map +1 -0
  9. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js +40 -32
  10. package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
  11. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js +71 -45
  12. package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js.map +1 -1
  13. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js +56 -46
  14. package/dist/eventfullymanaged/pages/modules/CommunicationPage.js.map +1 -1
  15. package/dist/eventfullymanaged/pages/modules/EventsPage.js +75 -67
  16. package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
  17. package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
  18. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +30 -11
  19. package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
  20. package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js.map +1 -1
  21. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +35 -13
  22. package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
  23. package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js +68 -54
  24. package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js.map +1 -1
  25. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +153 -125
  26. package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
  27. package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js +107 -62
  28. package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js.map +1 -1
  29. package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
  30. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +144 -135
  31. package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
  32. package/dist/eventfullymanaged/pages/venues/VenueListPage.js.map +1 -1
  33. package/dist/node_modules/@apollo/client/react/context/ApolloContext.js.map +1 -1
  34. package/dist/node_modules/@apollo/client/react/hooks/internal/useDeepMemo.js.map +1 -1
  35. package/dist/node_modules/@apollo/client/react/hooks/internal/useIsomorphicLayoutEffect.js.map +1 -1
  36. package/dist/node_modules/@apollo/client/react/hooks/internal/wrapHook.js.map +1 -1
  37. package/dist/node_modules/@apollo/client/react/hooks/useApolloClient.js.map +1 -1
  38. package/dist/node_modules/@apollo/client/react/hooks/useMutation.js.map +1 -1
  39. package/dist/node_modules/@apollo/client/react/hooks/useQuery.js.map +1 -1
  40. package/dist/node_modules/@apollo/client/react/hooks/useSyncExternalStore.js.map +1 -1
  41. package/dist/node_modules/sonner/dist/index.js +163 -0
  42. package/dist/node_modules/sonner/dist/index.js.map +1 -0
  43. package/package.json +1 -1
@@ -6,15 +6,24 @@ import { useParams as a } from "react-router-dom";
6
6
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
7
  import { Megaphone as c, Pencil as l, TrendingUp as u } from "lucide-react";
8
8
  import { EmphasisPanel as d, GlassCard as f, GradientText as p, NextSteps as m, PagePurpose as h } from "@burdenoff/fe-libs/ui";
9
+ import { ContextConversationWidget as g } from "@burdenoff/fe-libs/shared";
10
+ import { useRegisterPageConversationContext as _ } from "@burdenoff/fe-libs/shared/providers/shell";
9
11
  //#region src/eventfullymanaged/pages/modules/SponsorDetailsPage.tsx
10
- function g() {
11
- let { id: g = "" } = a(), { navigate: _ } = e(), v = n({
12
+ function v({ sponsorId: e, sponsorName: t }) {
13
+ return _({
14
+ entityType: "EVENTFULLYMANAGED_SPONSOR",
15
+ entityId: e,
16
+ contextTitle: `Sponsor · ${t}`
17
+ }), /* @__PURE__ */ o(g, { widgetKey: "sponsor-message" });
18
+ }
19
+ function y() {
20
+ let { id: g = "" } = a(), { navigate: _ } = e(), y = n({
12
21
  limit: 100,
13
22
  offset: 0
14
- }), y = t({
23
+ }), b = t({
15
24
  limit: 100,
16
25
  offset: 0
17
- }), b = i(() => (v.data?.sponsors.items ?? []).find((e) => e.id === g), [g, v.data]), x = i(() => y.data?.communicationCampaigns.items ?? [], [y.data]);
26
+ }), x = i(() => (y.data?.sponsors.items ?? []).find((e) => e.id === g), [g, y.data]), S = i(() => b.data?.communicationCampaigns.items ?? [], [b.data]);
18
27
  return /* @__PURE__ */ s("div", {
19
28
  className: "space-y-6 p-6",
20
29
  children: [
@@ -26,9 +35,9 @@ function g() {
26
35
  }),
27
36
  /* @__PURE__ */ o("p", {
28
37
  className: "mt-1 text-sm text-text-secondary",
29
- children: v.loading ? "Loading sponsor details..." : b ? `Live sponsor profile for ${b.name}.` : "Sponsor not found in current query scope."
38
+ children: y.loading ? "Loading sponsor details..." : x ? `Live sponsor profile for ${x.name}.` : "Sponsor not found in current query scope."
30
39
  }),
31
- b ? /* @__PURE__ */ s("div", {
40
+ x ? /* @__PURE__ */ s("div", {
32
41
  className: "mt-4 grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4",
33
42
  children: [
34
43
  /* @__PURE__ */ s(f, {
@@ -39,7 +48,7 @@ function g() {
39
48
  children: "Level"
40
49
  }), /* @__PURE__ */ o("p", {
41
50
  className: "mt-1 font-medium text-text-primary",
42
- children: b.level
51
+ children: x.level
43
52
  })]
44
53
  }),
45
54
  /* @__PURE__ */ s(f, {
@@ -50,7 +59,7 @@ function g() {
50
59
  children: "Contact"
51
60
  }), /* @__PURE__ */ o("p", {
52
61
  className: "mt-1 font-medium text-text-primary",
53
- children: b.contactName ?? "Unassigned"
62
+ children: x.contactName ?? "Unassigned"
54
63
  })]
55
64
  }),
56
65
  /* @__PURE__ */ s(f, {
@@ -61,7 +70,7 @@ function g() {
61
70
  children: "Email"
62
71
  }), /* @__PURE__ */ o("p", {
63
72
  className: "mt-1 font-medium text-text-primary",
64
- children: b.contactEmail ?? "Unavailable"
73
+ children: x.contactEmail ?? "Unavailable"
65
74
  })]
66
75
  }),
67
76
  /* @__PURE__ */ s(f, {
@@ -72,21 +81,34 @@ function g() {
72
81
  children: "Website"
73
82
  }), /* @__PURE__ */ o("p", {
74
83
  className: "mt-1 truncate font-medium text-text-primary",
75
- children: b.website ?? "Unavailable"
84
+ children: x.website ?? "Unavailable"
76
85
  })]
77
86
  })
78
87
  ]
79
88
  }) : null
80
89
  ] }),
81
90
  /* @__PURE__ */ o(r, {
82
- heading: y.loading ? "Loading campaigns..." : `Campaign Activity (${x.length})`,
91
+ heading: b.loading ? "Loading campaigns..." : `Campaign Activity (${S.length})`,
83
92
  emptyLabel: "No communication campaigns available for sponsor tracking.",
84
- rows: x.map((e) => ({
93
+ rows: S.map((e) => ({
85
94
  id: e.id,
86
95
  title: e.title ?? e.name ?? `Campaign ${e.id}`,
87
96
  status: e.status
88
97
  }))
89
98
  }),
99
+ x ? /* @__PURE__ */ s("div", {
100
+ className: "space-y-3",
101
+ children: [/* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("h2", {
102
+ className: "text-lg font-semibold text-text-primary",
103
+ children: "Sponsor messages"
104
+ }), /* @__PURE__ */ o("p", {
105
+ className: "mt-1 text-sm text-text-secondary",
106
+ children: "Coordinate with this sponsor in a dedicated thread, backed by the conversations service."
107
+ })] }), /* @__PURE__ */ o(v, {
108
+ sponsorId: x.id,
109
+ sponsorName: x.name
110
+ })]
111
+ }) : null,
90
112
  /* @__PURE__ */ o(m, {
91
113
  storageKey: "eventfullymanaged-sponsor-details",
92
114
  title: "Grow this partnership",
@@ -118,6 +140,6 @@ function g() {
118
140
  });
119
141
  }
120
142
  //#endregion
121
- export { g as default };
143
+ export { y as default };
122
144
 
123
145
  //# sourceMappingURL=SponsorDetailsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SponsorDetailsPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/SponsorDetailsPage.tsx"],"sourcesContent":["import { Megaphone, Pencil, TrendingUp } 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 { useCommunicationCampaignsQuery, useSponsorsQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { EntityListSection } from './EntityListSection';\n\ntype SponsorRow = {\n id: string;\n name: string;\n level: string;\n website?: string | null;\n contactName?: string | null;\n contactEmail?: string | null;\n};\n\ntype CampaignRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function SponsorDetailsPage() {\n const { id = '' } = useParams();\n const { navigate } = useEventfullyManaged();\n const sponsorsQuery = useSponsorsQuery({ limit: 100, offset: 0 });\n const campaignsQuery = useCommunicationCampaignsQuery({ limit: 100, offset: 0 });\n\n const sponsor = useMemo(\n () => ((sponsorsQuery.data?.sponsors.items ?? []) as SponsorRow[]).find((item) => item.id === id),\n [id, sponsorsQuery.data]\n );\n const campaigns = useMemo(\n () => (campaignsQuery.data?.communicationCampaigns.items ?? []) as CampaignRow[],\n [campaignsQuery.data]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Everything about one sponsor in one place — their tier, contacts, and the campaigns they appear in. Use this\n to prep for a sponsor conversation, confirm their contact details, or check how their branded campaigns are\n performing.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Sponsor</GradientText> Details\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {sponsorsQuery.loading\n ? 'Loading sponsor details...'\n : sponsor\n ? `Live sponsor profile for ${sponsor.name}.`\n : 'Sponsor not found in current query scope.'}\n </p>\n {sponsor ? (\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\">Level</p>\n <p className=\"mt-1 font-medium text-text-primary\">{sponsor.level}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Contact</p>\n <p className=\"mt-1 font-medium text-text-primary\">{sponsor.contactName ?? 'Unassigned'}</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\">{sponsor.contactEmail ?? 'Unavailable'}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Website</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">{sponsor.website ?? 'Unavailable'}</p>\n </GlassCard>\n </div>\n ) : null}\n </EmphasisPanel>\n\n <EntityListSection\n heading={campaignsQuery.loading ? 'Loading campaigns...' : `Campaign Activity (${campaigns.length})`}\n emptyLabel=\"No communication campaigns available for sponsor tracking.\"\n rows={campaigns.map((campaign) => ({\n id: campaign.id,\n title: campaign.title ?? campaign.name ?? `Campaign ${campaign.id}`,\n status: campaign.status,\n }))}\n />\n\n <NextSteps\n storageKey=\"eventfullymanaged-sponsor-details\"\n title=\"Grow this partnership\"\n steps={[\n {\n id: 'edit-sponsor',\n label: 'Update sponsor details',\n description: 'Keep tier, contacts and contract value current.',\n icon: <Pencil className=\"h-4 w-4\" />,\n onClick: () => navigate(id ? `/sponsors/${id}/edit` : '/sponsors'),\n },\n {\n id: 'track-leads',\n label: 'Track sponsor leads',\n description: 'See the leads this sponsor is generating at the event.',\n icon: <TrendingUp className=\"h-4 w-4\" />,\n onClick: () => navigate(id ? `/sponsors/${id}/leads` : '/sponsors'),\n },\n {\n id: 'run-campaign',\n label: 'Run a co-branded campaign',\n description: 'Promote this sponsor through a communication campaign.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAyBA,SAAwB,IAAqB;CAC3C,IAAM,EAAE,QAAK,OAAO,GAAW,EACzB,EAAE,gBAAa,GAAsB,EACrC,IAAgB,EAAiB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC3D,IAAiB,EAA+B;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAE1E,IAAU,SACN,EAAc,MAAM,SAAS,SAAS,EAAE,EAAmB,MAAM,MAAS,EAAK,OAAO,EAAG,EACjG,CAAC,GAAI,EAAc,KAAK,CACzB,EACK,IAAY,QACT,EAAe,MAAM,uBAAuB,SAAS,EAAE,EAC9D,CAAC,EAAe,KAAK,CACtB;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UAAa,wOAIC,CAAA;GAEd,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAA,UAAc,WAAsB,CAAA,EAAA,WACjC;;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,EAAc,UACX,+BACA,IACE,4BAA4B,EAAQ,KAAK,KACzC;KACJ,CAAA;IACH,IACC,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAS,CAAA,EAC5E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAQ;QAAU,CAAA,CAC3D;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAW,CAAA,EAC9E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAQ,eAAe;QAAiB,CAAA,CACjF;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAS,CAAA,EAC5E,kBAAC,KAAD;QAAG,WAAU;kBAAsC,EAAQ,gBAAgB;QAAkB,CAAA,CACnF;;MACZ,kBAAC,GAAD;OAAW,WAAU;OAAS,WAAU;iBAAxC,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAsD;QAAW,CAAA,EAC9E,kBAAC,KAAD;QAAG,WAAU;kBAA+C,EAAQ,WAAW;QAAkB,CAAA,CACvF;;MACR;SACJ;IACU,EAAA,CAAA;GAEhB,kBAAC,GAAD;IACE,SAAS,EAAe,UAAU,yBAAyB,sBAAsB,EAAU,OAAO;IAClG,YAAW;IACX,MAAM,EAAU,KAAK,OAAc;KACjC,IAAI,EAAS;KACb,OAAO,EAAS,SAAS,EAAS,QAAQ,YAAY,EAAS;KAC/D,QAAQ,EAAS;KAClB,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,IAAK,aAAa,EAAG,SAAS,YAAY;MACnE;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;MACxC,eAAe,EAAS,IAAK,aAAa,EAAG,UAAU,YAAY;MACpE;KACD;MACE,IAAI;MACJ,OAAO;MACP,aAAa;MACb,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;MACvC,eAAe,EAAS,iBAAiB;MAC1C;KACF;IACD,CAAA;GACE"}
1
+ {"version":3,"file":"SponsorDetailsPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/SponsorDetailsPage.tsx"],"sourcesContent":["import { Megaphone, Pencil, TrendingUp } from 'lucide-react';\nimport { ContextConversationWidget } from '@burdenoff/fe-libs/shared';\nimport { useRegisterPageConversationContext } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { EmphasisPanel, GlassCard, GradientText, NextSteps, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport { useCommunicationCampaignsQuery, useSponsorsQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { EntityListSection } from './EntityListSection';\n\n/**\n * Sponsor ↔ organizer message thread, backed by wspace-conversations-svc and\n * scoped to this sponsor so the conversation follows the partnership.\n */\nfunction SponsorConversation({ sponsorId, sponsorName }: { sponsorId: string; sponsorName: string }) {\n useRegisterPageConversationContext({\n entityType: 'EVENTFULLYMANAGED_SPONSOR',\n entityId: sponsorId,\n contextTitle: `Sponsor · ${sponsorName}`,\n });\n return <ContextConversationWidget widgetKey=\"sponsor-message\" />;\n}\n\ntype SponsorRow = {\n id: string;\n name: string;\n level: string;\n website?: string | null;\n contactName?: string | null;\n contactEmail?: string | null;\n};\n\ntype CampaignRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function SponsorDetailsPage() {\n const { id = '' } = useParams();\n const { navigate } = useEventfullyManaged();\n const sponsorsQuery = useSponsorsQuery({ limit: 100, offset: 0 });\n const campaignsQuery = useCommunicationCampaignsQuery({ limit: 100, offset: 0 });\n\n const sponsor = useMemo(\n () => ((sponsorsQuery.data?.sponsors.items ?? []) as SponsorRow[]).find((item) => item.id === id),\n [id, sponsorsQuery.data]\n );\n const campaigns = useMemo(\n () => (campaignsQuery.data?.communicationCampaigns.items ?? []) as CampaignRow[],\n [campaignsQuery.data]\n );\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Everything about one sponsor in one place — their tier, contacts, and the campaigns they appear in. Use this to\n prep for a sponsor conversation, confirm their contact details, or check how their branded campaigns are\n performing.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Sponsor</GradientText> Details\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {sponsorsQuery.loading\n ? 'Loading sponsor details...'\n : sponsor\n ? `Live sponsor profile for ${sponsor.name}.`\n : 'Sponsor not found in current query scope.'}\n </p>\n {sponsor ? (\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\">Level</p>\n <p className=\"mt-1 font-medium text-text-primary\">{sponsor.level}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Contact</p>\n <p className=\"mt-1 font-medium text-text-primary\">{sponsor.contactName ?? 'Unassigned'}</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\">{sponsor.contactEmail ?? 'Unavailable'}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-3\">\n <p className=\"text-xs uppercase tracking-wide text-text-secondary\">Website</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">{sponsor.website ?? 'Unavailable'}</p>\n </GlassCard>\n </div>\n ) : null}\n </EmphasisPanel>\n\n <EntityListSection\n heading={campaignsQuery.loading ? 'Loading campaigns...' : `Campaign Activity (${campaigns.length})`}\n emptyLabel=\"No communication campaigns available for sponsor tracking.\"\n rows={campaigns.map((campaign) => ({\n id: campaign.id,\n title: campaign.title ?? campaign.name ?? `Campaign ${campaign.id}`,\n status: campaign.status,\n }))}\n />\n\n {sponsor ? (\n <div className=\"space-y-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Sponsor messages</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Coordinate with this sponsor in a dedicated thread, backed by the conversations service.\n </p>\n </div>\n <SponsorConversation sponsorId={sponsor.id} sponsorName={sponsor.name} />\n </div>\n ) : null}\n\n <NextSteps\n storageKey=\"eventfullymanaged-sponsor-details\"\n title=\"Grow this partnership\"\n steps={[\n {\n id: 'edit-sponsor',\n label: 'Update sponsor details',\n description: 'Keep tier, contacts and contract value current.',\n icon: <Pencil className=\"h-4 w-4\" />,\n onClick: () => navigate(id ? `/sponsors/${id}/edit` : '/sponsors'),\n },\n {\n id: 'track-leads',\n label: 'Track sponsor leads',\n description: 'See the leads this sponsor is generating at the event.',\n icon: <TrendingUp className=\"h-4 w-4\" />,\n onClick: () => navigate(id ? `/sponsors/${id}/leads` : '/sponsors'),\n },\n {\n id: 'run-campaign',\n label: 'Run a co-branded campaign',\n description: 'Promote this sponsor through a communication campaign.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,109 +1,123 @@
1
1
  import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
2
- import { useAutomationRulesQuery as t, useUpsertAutomationRuleMutation as n, useUpsertWorkflowTemplateMutation as r, useWorkflowTemplatesQuery as i } from "../../api/eventApi.js";
3
- import { EntityListSection as a } from "./EntityListSection.js";
4
- import { useMemo as o, useState as s } from "react";
5
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
- import { Megaphone as u, Play as d, Ticket as f } from "lucide-react";
7
- import { Button as p, CTAOverflowMenu as m, EmphasisPanel as h, GradientText as g, Input as _, NextSteps as v, PagePurpose as y } from "@burdenoff/fe-libs/ui";
2
+ import { notify as t } from "../../lib/toast.js";
3
+ import { useAutomationRulesQuery as n, useUpsertAutomationRuleMutation as r, useUpsertWorkflowTemplateMutation as i, useWorkflowTemplatesQuery as a } from "../../api/eventApi.js";
4
+ import { describeError as o, mutationSucceeded as s } from "../../lib/mutationResult.js";
5
+ import { EntityListSection as c } from "./EntityListSection.js";
6
+ import { useMemo as l, useState as u } from "react";
7
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
8
+ import { Megaphone as p, Play as m, Ticket as h } from "lucide-react";
9
+ import { Button as g, CTAOverflowMenu as _, EmphasisPanel as v, GradientText as y, Input as b, NextSteps as x, PagePurpose as S } from "@burdenoff/fe-libs/ui";
8
10
  //#region src/eventfullymanaged/pages/modules/WorkflowsPage.tsx
9
- function b() {
10
- let { navigate: b } = e(), x = i({
11
+ function C() {
12
+ let { navigate: C } = e(), w = a({
11
13
  limit: 100,
12
14
  offset: 0
13
- }), S = t({
15
+ }), T = n({
14
16
  limit: 100,
15
17
  offset: 0
16
- }), [C, { loading: w }] = r(), [T, { loading: E }] = n(), [D, O] = s("Post-event follow-up"), k = o(() => x.data?.workflowTemplates.items ?? [], [x.data]), A = o(() => S.data?.automationRules.items ?? [], [S.data]), j = async () => {
17
- D.trim() && await C({ variables: { input: {
18
- name: D,
19
- title: D,
20
- status: "active",
21
- metadata: {}
22
- } } });
23
- }, M = async () => {
24
- await T({ variables: { input: {
25
- name: `${D} Rule`,
26
- title: `${D} Rule`,
27
- status: "active",
28
- metadata: {}
29
- } } });
18
+ }), [E, { loading: D }] = i(), [O, { loading: k }] = r(), [A, j] = u("Post-event follow-up"), M = l(() => w.data?.workflowTemplates.items ?? [], [w.data]), N = l(() => T.data?.automationRules.items ?? [], [T.data]), P = async () => {
19
+ if (A.trim()) try {
20
+ let e = await E({ variables: { input: {
21
+ name: A,
22
+ title: A,
23
+ status: "active",
24
+ metadata: {}
25
+ } } });
26
+ if (!s(e, e.data?.upsertWorkflowTemplate?.id, "Could not save workflow template")) return;
27
+ t.success("Workflow template saved");
28
+ } catch (e) {
29
+ t.error("Could not save workflow template", o(e));
30
+ }
31
+ }, F = async () => {
32
+ if (A.trim()) try {
33
+ let e = await O({ variables: { input: {
34
+ name: `${A} Rule`,
35
+ title: `${A} Rule`,
36
+ status: "active",
37
+ metadata: {}
38
+ } } });
39
+ if (!s(e, e.data?.upsertAutomationRule?.id, "Could not save automation rule")) return;
40
+ t.success("Automation rule saved");
41
+ } catch (e) {
42
+ t.error("Could not save automation rule", o(e));
43
+ }
30
44
  };
31
- return /* @__PURE__ */ l("div", {
45
+ return /* @__PURE__ */ f("div", {
32
46
  className: "space-y-6 p-6",
33
47
  children: [
34
- /* @__PURE__ */ c(y, { children: "Workflows automate the repetitive parts of running an event. A template is a reusable recipe (e.g. a post-event follow-up sequence); an automation rule is a trigger that fires it (e.g. “when an attendee checks in, send a welcome message”). Build them here so the platform handles routine work for you while execution is delegated to the workflow services." }),
35
- /* @__PURE__ */ l(h, { children: [
36
- /* @__PURE__ */ c("h1", {
48
+ /* @__PURE__ */ d(S, { children: "Workflows automate the repetitive parts of running an event. A template is a reusable recipe (e.g. a post-event follow-up sequence); an automation rule is a trigger that fires it (e.g. “when an attendee checks in, send a welcome message”). Build them here so the platform handles routine work for you while execution is delegated to the workflow services." }),
49
+ /* @__PURE__ */ f(v, { children: [
50
+ /* @__PURE__ */ d("h1", {
37
51
  className: "text-2xl font-bold text-text-primary",
38
- children: /* @__PURE__ */ c(g, { children: "Workflows" })
52
+ children: /* @__PURE__ */ d(y, { children: "Workflows" })
39
53
  }),
40
- /* @__PURE__ */ c("p", {
54
+ /* @__PURE__ */ d("p", {
41
55
  className: "mt-1 text-sm text-text-secondary",
42
56
  children: "Manage event workflow templates and automation rules. Execution is delegated to workflow services."
43
57
  }),
44
- /* @__PURE__ */ l("div", {
58
+ /* @__PURE__ */ f("div", {
45
59
  className: "mt-4 flex flex-col gap-3 sm:flex-row sm:items-center",
46
- children: [/* @__PURE__ */ c(_, {
47
- value: D,
48
- onChange: (e) => O(e.target.value),
60
+ children: [/* @__PURE__ */ d(b, {
61
+ value: A,
62
+ onChange: (e) => j(e.target.value),
49
63
  "aria-label": "Workflow template name",
50
64
  className: "flex-1"
51
- }), /* @__PURE__ */ l("div", {
65
+ }), /* @__PURE__ */ f("div", {
52
66
  className: "flex items-center gap-2",
53
- children: [/* @__PURE__ */ l(p, {
67
+ children: [/* @__PURE__ */ f(g, {
54
68
  type: "button",
55
- onClick: j,
56
- disabled: w,
57
- children: [/* @__PURE__ */ c(d, { className: "h-4 w-4" }), w ? "Saving..." : "Add Template"]
58
- }), /* @__PURE__ */ c(m, { actions: [{
59
- label: E ? "Saving rule..." : "Add Rule",
69
+ onClick: P,
70
+ disabled: D,
71
+ children: [/* @__PURE__ */ d(m, { className: "h-4 w-4" }), D ? "Saving..." : "Add Template"]
72
+ }), /* @__PURE__ */ d(_, { actions: [{
73
+ label: k ? "Saving rule..." : "Add Rule",
60
74
  onSelect: () => {
61
- M();
75
+ F();
62
76
  },
63
- disabled: E
77
+ disabled: k
64
78
  }] })]
65
79
  })]
66
80
  })
67
81
  ] }),
68
- /* @__PURE__ */ c(a, {
69
- heading: x.loading ? "Loading templates..." : `Templates (${k.length})`,
82
+ /* @__PURE__ */ d(c, {
83
+ heading: w.loading ? "Loading templates..." : `Templates (${M.length})`,
70
84
  emptyLabel: "No workflow templates configured.",
71
- rows: k.map((e) => ({
85
+ rows: M.map((e) => ({
72
86
  id: e.id,
73
87
  title: e.name ?? e.title ?? `Template ${e.id}`,
74
88
  status: e.status ?? void 0
75
89
  }))
76
90
  }),
77
- /* @__PURE__ */ c(a, {
78
- heading: S.loading ? "Loading automation rules..." : `Automation Rules (${A.length})`,
91
+ /* @__PURE__ */ d(c, {
92
+ heading: T.loading ? "Loading automation rules..." : `Automation Rules (${N.length})`,
79
93
  emptyLabel: "No automation rules configured.",
80
- rows: A.map((e) => ({
94
+ rows: N.map((e) => ({
81
95
  id: e.id,
82
96
  title: e.name ?? e.title ?? `Rule ${e.id}`,
83
97
  status: e.status ?? void 0
84
98
  }))
85
99
  }),
86
- /* @__PURE__ */ c(v, {
100
+ /* @__PURE__ */ d(x, {
87
101
  storageKey: "eventfullymanaged-workflows",
88
102
  title: "Put your automations to work",
89
103
  steps: [{
90
104
  id: "wire-communication",
91
105
  label: "Connect a communication campaign",
92
106
  description: "Have a rule fire announcements or reminders automatically.",
93
- icon: /* @__PURE__ */ c(u, { className: "h-4 w-4" }),
94
- onClick: () => b("/communication")
107
+ icon: /* @__PURE__ */ d(p, { className: "h-4 w-4" }),
108
+ onClick: () => C("/communication")
95
109
  }, {
96
110
  id: "automate-checkin",
97
111
  label: "Automate around check-in",
98
112
  description: "Trigger welcome flows when attendees register or arrive.",
99
- icon: /* @__PURE__ */ c(f, { className: "h-4 w-4" }),
100
- onClick: () => b("/registration")
113
+ icon: /* @__PURE__ */ d(h, { className: "h-4 w-4" }),
114
+ onClick: () => C("/registration")
101
115
  }]
102
116
  })
103
117
  ]
104
118
  });
105
119
  }
106
120
  //#endregion
107
- export { b as default };
121
+ export { C as default };
108
122
 
109
123
  //# sourceMappingURL=WorkflowsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/WorkflowsPage.tsx"],"sourcesContent":["import { Megaphone, Play, Ticket } from 'lucide-react';\nimport {\n Button,\n CTAOverflowMenu,\n EmphasisPanel,\n GradientText,\n Input,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\n\nimport {\n useAutomationRulesQuery,\n useUpsertAutomationRuleMutation,\n useUpsertWorkflowTemplateMutation,\n useWorkflowTemplatesQuery,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { EntityListSection } from './EntityListSection';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function WorkflowsPage() {\n const { navigate } = useEventfullyManaged();\n const templatesQuery = useWorkflowTemplatesQuery({ limit: 100, offset: 0 });\n const rulesQuery = useAutomationRulesQuery({ limit: 100, offset: 0 });\n const [upsertTemplate, { loading: creatingTemplate }] = useUpsertWorkflowTemplateMutation();\n const [upsertRule, { loading: creatingRule }] = useUpsertAutomationRuleMutation();\n const [templateName, setTemplateName] = useState('Post-event follow-up');\n\n const templates = useMemo(\n () => (templatesQuery.data?.workflowTemplates.items ?? []) as SimpleRow[],\n [templatesQuery.data]\n );\n const rules = useMemo(() => (rulesQuery.data?.automationRules.items ?? []) as SimpleRow[], [rulesQuery.data]);\n\n const onCreateTemplate = async () => {\n if (!templateName.trim()) return;\n await upsertTemplate({\n variables: {\n input: {\n name: templateName,\n title: templateName,\n status: 'active',\n metadata: {},\n },\n },\n });\n };\n\n const onCreateRule = async () => {\n await upsertRule({\n variables: {\n input: {\n name: `${templateName} Rule`,\n title: `${templateName} Rule`,\n status: 'active',\n metadata: {},\n },\n },\n });\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Workflows automate the repetitive parts of running an event. A template is a reusable recipe (e.g. a\n post-event follow-up sequence); an automation rule is a trigger that fires it (e.g. &ldquo;when an attendee\n checks in, send a welcome message&rdquo;). Build them here so the platform handles routine work for you while\n execution is delegated to the workflow services.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Workflows</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Manage event workflow templates and automation rules. Execution is delegated to workflow services.\n </p>\n <div className=\"mt-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <Input\n value={templateName}\n onChange={(e) => setTemplateName(e.target.value)}\n aria-label=\"Workflow template name\"\n className=\"flex-1\"\n />\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" onClick={onCreateTemplate} disabled={creatingTemplate}>\n <Play className=\"h-4 w-4\" />\n {creatingTemplate ? 'Saving...' : 'Add Template'}\n </Button>\n <CTAOverflowMenu\n actions={[\n {\n label: creatingRule ? 'Saving rule...' : 'Add Rule',\n onSelect: () => {\n void onCreateRule();\n },\n disabled: creatingRule,\n },\n ]}\n />\n </div>\n </div>\n </EmphasisPanel>\n\n <EntityListSection\n heading={templatesQuery.loading ? 'Loading templates...' : `Templates (${templates.length})`}\n emptyLabel=\"No workflow templates configured.\"\n rows={templates.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Template ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={rulesQuery.loading ? 'Loading automation rules...' : `Automation Rules (${rules.length})`}\n emptyLabel=\"No automation rules configured.\"\n rows={rules.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Rule ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <NextSteps\n storageKey=\"eventfullymanaged-workflows\"\n title=\"Put your automations to work\"\n steps={[\n {\n id: 'wire-communication',\n label: 'Connect a communication campaign',\n description: 'Have a rule fire announcements or reminders automatically.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n {\n id: 'automate-checkin',\n label: 'Automate around check-in',\n description: 'Trigger welcome flows when attendees register or arrive.',\n icon: <Ticket className=\"h-4 w-4\" />,\n onClick: () => navigate('/registration'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;AA4BA,SAAwB,IAAgB;CACtC,IAAM,EAAE,gBAAa,GAAsB,EACrC,IAAiB,EAA0B;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EACrE,IAAa,EAAwB;EAAE,OAAO;EAAK,QAAQ;EAAG,CAAC,EAC/D,CAAC,GAAgB,EAAE,SAAS,OAAsB,GAAmC,EACrF,CAAC,GAAY,EAAE,SAAS,OAAkB,GAAiC,EAC3E,CAAC,GAAc,KAAmB,EAAS,uBAAuB,EAElE,IAAY,QACT,EAAe,MAAM,kBAAkB,SAAS,EAAE,EACzD,CAAC,EAAe,KAAK,CACtB,EACK,IAAQ,QAAe,EAAW,MAAM,gBAAgB,SAAS,EAAE,EAAkB,CAAC,EAAW,KAAK,CAAC,EAEvG,IAAmB,YAAY;AAC9B,IAAa,MAAM,IACxB,MAAM,EAAe,EACnB,WAAW,EACT,OAAO;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,UAAU,EAAE;GACb,EACF,EACF,CAAC;IAGE,IAAe,YAAY;AAC/B,QAAM,EAAW,EACf,WAAW,EACT,OAAO;GACL,MAAM,GAAG,EAAa;GACtB,OAAO,GAAG,EAAa;GACvB,QAAQ;GACR,UAAU,EAAE;GACb,EACF,EACF,CAAC;;AAGJ,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UAAa,uWAKC,CAAA;GAEd,kBAAC,GAAD,EAAA,UAAA;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAc,aAAwB,CAAA;KACnC,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAAmC;KAE5C,CAAA;IACJ,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAgB,EAAE,OAAO,MAAM;MAChD,cAAW;MACX,WAAU;MACV,CAAA,EACF,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OAAQ,MAAK;OAAS,SAAS;OAAkB,UAAU;iBAA3D,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,IAAmB,cAAc,eAC3B;UACT,kBAAC,GAAD,EACE,SAAS,CACP;OACE,OAAO,IAAe,mBAAmB;OACzC,gBAAgB;AACT,WAAc;;OAErB,UAAU;OACX,CACF,EACD,CAAA,CACE;QACF;;IACQ,EAAA,CAAA;GAEhB,kBAAC,GAAD;IACE,SAAS,EAAe,UAAU,yBAAyB,cAAc,EAAU,OAAO;IAC1F,YAAW;IACX,MAAM,EAAU,KAAK,OAAS;KAC5B,IAAI,EAAI;KACR,OAAO,EAAI,QAAQ,EAAI,SAAS,YAAY,EAAI;KAChD,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,SAAS,EAAW,UAAU,gCAAgC,qBAAqB,EAAM,OAAO;IAChG,YAAW;IACX,MAAM,EAAM,KAAK,OAAS;KACxB,IAAI,EAAI;KACR,OAAO,EAAI,QAAQ,EAAI,SAAS,QAAQ,EAAI;KAC5C,QAAQ,EAAI,UAAU,KAAA;KACvB,EAAE;IACH,CAAA;GAEF,kBAAC,GAAD;IACE,YAAW;IACX,OAAM;IACN,OAAO,CACL;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,eAAe,EAAS,iBAAiB;KAC1C,EACD;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,eAAe,EAAS,gBAAgB;KACzC,CACF;IACD,CAAA;GACE"}
1
+ {"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/modules/WorkflowsPage.tsx"],"sourcesContent":["import { Megaphone, Play, Ticket } from 'lucide-react';\nimport {\n Button,\n CTAOverflowMenu,\n EmphasisPanel,\n GradientText,\n Input,\n NextSteps,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\n\nimport {\n useAutomationRulesQuery,\n useUpsertAutomationRuleMutation,\n useUpsertWorkflowTemplateMutation,\n useWorkflowTemplatesQuery,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\nimport { EntityListSection } from './EntityListSection';\n\ntype SimpleRow = {\n id: string;\n name?: string;\n title?: string;\n status?: string;\n};\n\nexport default function WorkflowsPage() {\n const { navigate } = useEventfullyManaged();\n const templatesQuery = useWorkflowTemplatesQuery({ limit: 100, offset: 0 });\n const rulesQuery = useAutomationRulesQuery({ limit: 100, offset: 0 });\n const [upsertTemplate, { loading: creatingTemplate }] = useUpsertWorkflowTemplateMutation();\n const [upsertRule, { loading: creatingRule }] = useUpsertAutomationRuleMutation();\n const [templateName, setTemplateName] = useState('Post-event follow-up');\n\n const templates = useMemo(\n () => (templatesQuery.data?.workflowTemplates.items ?? []) as SimpleRow[],\n [templatesQuery.data]\n );\n const rules = useMemo(() => (rulesQuery.data?.automationRules.items ?? []) as SimpleRow[], [rulesQuery.data]);\n\n const onCreateTemplate = async () => {\n if (!templateName.trim()) return;\n try {\n const response = await upsertTemplate({\n variables: {\n input: {\n name: templateName,\n title: templateName,\n status: 'active',\n metadata: {},\n },\n },\n });\n if (!mutationSucceeded(response, response.data?.upsertWorkflowTemplate?.id, 'Could not save workflow template')) {\n return;\n }\n notify.success('Workflow template saved');\n } catch (error) {\n notify.error('Could not save workflow template', describeError(error));\n }\n };\n\n const onCreateRule = async () => {\n if (!templateName.trim()) return;\n try {\n const response = await upsertRule({\n variables: {\n input: {\n name: `${templateName} Rule`,\n title: `${templateName} Rule`,\n status: 'active',\n metadata: {},\n },\n },\n });\n if (!mutationSucceeded(response, response.data?.upsertAutomationRule?.id, 'Could not save automation rule')) {\n return;\n }\n notify.success('Automation rule saved');\n } catch (error) {\n notify.error('Could not save automation rule', describeError(error));\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Workflows automate the repetitive parts of running an event. A template is a reusable recipe (e.g. a post-event\n follow-up sequence); an automation rule is a trigger that fires it (e.g. &ldquo;when an attendee checks in, send\n a welcome message&rdquo;). Build them here so the platform handles routine work for you while execution is\n delegated to the workflow services.\n </PagePurpose>\n\n <EmphasisPanel>\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>Workflows</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Manage event workflow templates and automation rules. Execution is delegated to workflow services.\n </p>\n <div className=\"mt-4 flex flex-col gap-3 sm:flex-row sm:items-center\">\n <Input\n value={templateName}\n onChange={(e) => setTemplateName(e.target.value)}\n aria-label=\"Workflow template name\"\n className=\"flex-1\"\n />\n <div className=\"flex items-center gap-2\">\n <Button type=\"button\" onClick={onCreateTemplate} disabled={creatingTemplate}>\n <Play className=\"h-4 w-4\" />\n {creatingTemplate ? 'Saving...' : 'Add Template'}\n </Button>\n <CTAOverflowMenu\n actions={[\n {\n label: creatingRule ? 'Saving rule...' : 'Add Rule',\n onSelect: () => {\n void onCreateRule();\n },\n disabled: creatingRule,\n },\n ]}\n />\n </div>\n </div>\n </EmphasisPanel>\n\n <EntityListSection\n heading={templatesQuery.loading ? 'Loading templates...' : `Templates (${templates.length})`}\n emptyLabel=\"No workflow templates configured.\"\n rows={templates.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Template ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <EntityListSection\n heading={rulesQuery.loading ? 'Loading automation rules...' : `Automation Rules (${rules.length})`}\n emptyLabel=\"No automation rules configured.\"\n rows={rules.map((row) => ({\n id: row.id,\n title: row.name ?? row.title ?? `Rule ${row.id}`,\n status: row.status ?? undefined,\n }))}\n />\n\n <NextSteps\n storageKey=\"eventfullymanaged-workflows\"\n title=\"Put your automations to work\"\n steps={[\n {\n id: 'wire-communication',\n label: 'Connect a communication campaign',\n description: 'Have a rule fire announcements or reminders automatically.',\n icon: <Megaphone className=\"h-4 w-4\" />,\n onClick: () => navigate('/communication'),\n },\n {\n id: 'automate-checkin',\n label: 'Automate around check-in',\n description: 'Trigger welcome flows when attendees register or arrive.',\n icon: <Ticket className=\"h-4 w-4\" />,\n onClick: () => navigate('/registration'),\n },\n ]}\n />\n </div>\n );\n}\n"],"mappings":"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"}