@burdenoff/microfe-eventfullymanaged 2026.625.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.
- package/dist/eventfullymanaged/pages/dashboard/DashboardPage.js +88 -47
- package/dist/eventfullymanaged/pages/dashboard/DashboardPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js +49 -45
- package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js +111 -78
- package/dist/eventfullymanaged/pages/modules/AttendeeProfilePage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/CommunicationPage.js +29 -28
- package/dist/eventfullymanaged/pages/modules/CommunicationPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/EventsPage.js +71 -42
- package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/KioskPage.js +11 -10
- package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +54 -24
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js +135 -105
- package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +63 -33
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +110 -77
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js +54 -23
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js +67 -37
- package/dist/eventfullymanaged/pages/modules/VenueResourcesPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js +61 -42
- package/dist/eventfullymanaged/pages/modules/WorkflowsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +85 -85
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js +22 -21
- package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js +37 -40
- package/dist/eventfullymanaged/pages/venues/FloorPlansPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js +67 -38
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +99 -99
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueListPage.js +23 -22
- package/dist/eventfullymanaged/pages/venues/VenueListPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -4,9 +4,9 @@ import { useEffect as a, useMemo as o, useState as s } from "react";
|
|
|
4
4
|
import { useParams as c } from "react-router-dom";
|
|
5
5
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
6
6
|
import { ArrowLeft as d, Save as f } from "lucide-react";
|
|
7
|
-
import { Button as p,
|
|
7
|
+
import { Button as p, EmphasisPanel as m, Input as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
|
|
8
8
|
//#region src/eventfullymanaged/pages/sponsors/SponsorFormPage.tsx
|
|
9
|
-
var
|
|
9
|
+
var _ = {
|
|
10
10
|
eventId: "",
|
|
11
11
|
name: "",
|
|
12
12
|
level: "BRONZE",
|
|
@@ -17,83 +17,83 @@ var g = {
|
|
|
17
17
|
value: "0",
|
|
18
18
|
leads: "0"
|
|
19
19
|
};
|
|
20
|
-
function
|
|
21
|
-
let { id:
|
|
20
|
+
function v() {
|
|
21
|
+
let { id: v = "" } = c(), y = o(() => !!v, [v]), { navigate: b } = e(), { data: x } = n({
|
|
22
22
|
limit: 100,
|
|
23
23
|
offset: 0
|
|
24
|
-
}), { data:
|
|
24
|
+
}), { data: S } = r({
|
|
25
25
|
limit: 100,
|
|
26
26
|
offset: 0
|
|
27
|
-
}),
|
|
28
|
-
eventId:
|
|
29
|
-
name:
|
|
30
|
-
level:
|
|
31
|
-
website:
|
|
32
|
-
contactName:
|
|
33
|
-
contactEmail:
|
|
34
|
-
contactPhone:
|
|
35
|
-
value: String(
|
|
36
|
-
leads: String(
|
|
37
|
-
} :
|
|
27
|
+
}), C = o(() => (S?.sponsors?.items ?? []).find((e) => e.id === v), [v, S]), [w, { loading: T }] = t(), [E, { loading: D }] = i(), [O, k] = s(() => C ? {
|
|
28
|
+
eventId: C.eventId ?? "",
|
|
29
|
+
name: C.name ?? "",
|
|
30
|
+
level: C.level ?? "BRONZE",
|
|
31
|
+
website: C.website ?? "",
|
|
32
|
+
contactName: C.contactName ?? "",
|
|
33
|
+
contactEmail: C.contactEmail ?? "",
|
|
34
|
+
contactPhone: C.contactPhone ?? "",
|
|
35
|
+
value: String(C.metrics?.value ?? 0),
|
|
36
|
+
leads: String(C.metrics?.leads ?? 0)
|
|
37
|
+
} : _);
|
|
38
38
|
a(() => {
|
|
39
|
-
|
|
40
|
-
eventId:
|
|
41
|
-
name:
|
|
42
|
-
level:
|
|
43
|
-
website:
|
|
44
|
-
contactName:
|
|
45
|
-
contactEmail:
|
|
46
|
-
contactPhone:
|
|
47
|
-
value: String(
|
|
48
|
-
leads: String(
|
|
39
|
+
C && k({
|
|
40
|
+
eventId: C.eventId ?? "",
|
|
41
|
+
name: C.name ?? "",
|
|
42
|
+
level: C.level ?? "BRONZE",
|
|
43
|
+
website: C.website ?? "",
|
|
44
|
+
contactName: C.contactName ?? "",
|
|
45
|
+
contactEmail: C.contactEmail ?? "",
|
|
46
|
+
contactPhone: C.contactPhone ?? "",
|
|
47
|
+
value: String(C.metrics?.value ?? 0),
|
|
48
|
+
leads: String(C.metrics?.leads ?? 0)
|
|
49
49
|
});
|
|
50
|
-
}, [
|
|
51
|
-
let
|
|
52
|
-
|
|
50
|
+
}, [C]);
|
|
51
|
+
let A = (e, t) => {
|
|
52
|
+
k((n) => ({
|
|
53
53
|
...n,
|
|
54
54
|
[e]: t
|
|
55
55
|
}));
|
|
56
|
-
},
|
|
56
|
+
}, j = async (e) => {
|
|
57
57
|
e.preventDefault();
|
|
58
58
|
let t = {
|
|
59
|
-
eventId:
|
|
60
|
-
name:
|
|
61
|
-
level:
|
|
62
|
-
website:
|
|
63
|
-
contactName:
|
|
64
|
-
contactEmail:
|
|
65
|
-
contactPhone:
|
|
59
|
+
eventId: O.eventId,
|
|
60
|
+
name: O.name,
|
|
61
|
+
level: O.level,
|
|
62
|
+
website: O.website,
|
|
63
|
+
contactName: O.contactName,
|
|
64
|
+
contactEmail: O.contactEmail,
|
|
65
|
+
contactPhone: O.contactPhone,
|
|
66
66
|
metrics: {
|
|
67
|
-
value: Number(
|
|
68
|
-
leads: Number(
|
|
67
|
+
value: Number(O.value || 0),
|
|
68
|
+
leads: Number(O.leads || 0)
|
|
69
69
|
},
|
|
70
70
|
metadata: {}
|
|
71
71
|
};
|
|
72
|
-
if (
|
|
73
|
-
await
|
|
74
|
-
id:
|
|
72
|
+
if (y) {
|
|
73
|
+
await E({ variables: {
|
|
74
|
+
id: v,
|
|
75
75
|
input: t
|
|
76
|
-
} }),
|
|
76
|
+
} }), b("/sponsors");
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
await
|
|
80
|
-
},
|
|
79
|
+
await w({ variables: { input: t } }), b("/sponsors");
|
|
80
|
+
}, M = T || D, N = x?.events?.items ?? [], P = "w-full rounded-input border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary transition-colors focus-visible:border-border-focus focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)] focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]";
|
|
81
81
|
return /* @__PURE__ */ u("div", {
|
|
82
82
|
className: "space-y-6 p-6",
|
|
83
|
-
children: [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
children: /* @__PURE__ */ u("form", {
|
|
96
|
-
onSubmit:
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ u(p, {
|
|
85
|
+
type: "button",
|
|
86
|
+
variant: "ghost",
|
|
87
|
+
size: "sm",
|
|
88
|
+
onClick: () => b("/sponsors"),
|
|
89
|
+
children: [/* @__PURE__ */ l(d, { className: "h-4 w-4" }), "Back to Sponsors"]
|
|
90
|
+
}), /* @__PURE__ */ l("h1", {
|
|
91
|
+
className: "mt-3 text-2xl font-bold text-text-primary",
|
|
92
|
+
children: y ? "Edit Sponsor" : "Create Sponsor"
|
|
93
|
+
})] }),
|
|
94
|
+
/* @__PURE__ */ l(g, { children: "Capture a sponsor and the deal behind it. Link them to an event, set their tier, and record the contract value and leads target so you can measure ROI later. The contact fields are who you will work with day to day, so keep them accurate." }),
|
|
95
|
+
/* @__PURE__ */ l(m, { children: /* @__PURE__ */ u("form", {
|
|
96
|
+
onSubmit: j,
|
|
97
97
|
className: "space-y-4",
|
|
98
98
|
children: [
|
|
99
99
|
/* @__PURE__ */ u("div", {
|
|
@@ -104,14 +104,14 @@ function _() {
|
|
|
104
104
|
className: "font-medium text-text-primary",
|
|
105
105
|
children: "Event"
|
|
106
106
|
}), /* @__PURE__ */ u("select", {
|
|
107
|
-
value:
|
|
108
|
-
onChange: (e) =>
|
|
107
|
+
value: O.eventId,
|
|
108
|
+
onChange: (e) => A("eventId", e.target.value),
|
|
109
109
|
required: !0,
|
|
110
|
-
className:
|
|
110
|
+
className: P,
|
|
111
111
|
children: [/* @__PURE__ */ l("option", {
|
|
112
112
|
value: "",
|
|
113
113
|
children: "Select Event"
|
|
114
|
-
}),
|
|
114
|
+
}), N.map((e) => /* @__PURE__ */ l("option", {
|
|
115
115
|
value: e.id,
|
|
116
116
|
children: e.name
|
|
117
117
|
}, e.id))]
|
|
@@ -122,8 +122,8 @@ function _() {
|
|
|
122
122
|
className: "font-medium text-text-primary",
|
|
123
123
|
children: "Sponsor Name"
|
|
124
124
|
}), /* @__PURE__ */ l(h, {
|
|
125
|
-
value:
|
|
126
|
-
onChange: (e) =>
|
|
125
|
+
value: O.name,
|
|
126
|
+
onChange: (e) => A("name", e.target.value),
|
|
127
127
|
required: !0
|
|
128
128
|
})]
|
|
129
129
|
})]
|
|
@@ -137,9 +137,9 @@ function _() {
|
|
|
137
137
|
className: "font-medium text-text-primary",
|
|
138
138
|
children: "Level"
|
|
139
139
|
}), /* @__PURE__ */ u("select", {
|
|
140
|
-
value:
|
|
141
|
-
onChange: (e) =>
|
|
142
|
-
className:
|
|
140
|
+
value: O.level,
|
|
141
|
+
onChange: (e) => A("level", e.target.value),
|
|
142
|
+
className: P,
|
|
143
143
|
children: [
|
|
144
144
|
/* @__PURE__ */ l("option", {
|
|
145
145
|
value: "PLATINUM",
|
|
@@ -172,8 +172,8 @@ function _() {
|
|
|
172
172
|
}), /* @__PURE__ */ l(h, {
|
|
173
173
|
type: "number",
|
|
174
174
|
min: "0",
|
|
175
|
-
value:
|
|
176
|
-
onChange: (e) =>
|
|
175
|
+
value: O.value,
|
|
176
|
+
onChange: (e) => A("value", e.target.value)
|
|
177
177
|
})]
|
|
178
178
|
}),
|
|
179
179
|
/* @__PURE__ */ u("label", {
|
|
@@ -184,8 +184,8 @@ function _() {
|
|
|
184
184
|
}), /* @__PURE__ */ l(h, {
|
|
185
185
|
type: "number",
|
|
186
186
|
min: "0",
|
|
187
|
-
value:
|
|
188
|
-
onChange: (e) =>
|
|
187
|
+
value: O.leads,
|
|
188
|
+
onChange: (e) => A("leads", e.target.value)
|
|
189
189
|
})]
|
|
190
190
|
})
|
|
191
191
|
]
|
|
@@ -196,8 +196,8 @@ function _() {
|
|
|
196
196
|
className: "font-medium text-text-primary",
|
|
197
197
|
children: "Website"
|
|
198
198
|
}), /* @__PURE__ */ l(h, {
|
|
199
|
-
value:
|
|
200
|
-
onChange: (e) =>
|
|
199
|
+
value: O.website,
|
|
200
|
+
onChange: (e) => A("website", e.target.value)
|
|
201
201
|
})]
|
|
202
202
|
}),
|
|
203
203
|
/* @__PURE__ */ u("div", {
|
|
@@ -209,8 +209,8 @@ function _() {
|
|
|
209
209
|
className: "font-medium text-text-primary",
|
|
210
210
|
children: "Contact Name"
|
|
211
211
|
}), /* @__PURE__ */ l(h, {
|
|
212
|
-
value:
|
|
213
|
-
onChange: (e) =>
|
|
212
|
+
value: O.contactName,
|
|
213
|
+
onChange: (e) => A("contactName", e.target.value)
|
|
214
214
|
})]
|
|
215
215
|
}),
|
|
216
216
|
/* @__PURE__ */ u("label", {
|
|
@@ -220,8 +220,8 @@ function _() {
|
|
|
220
220
|
children: "Contact Email"
|
|
221
221
|
}), /* @__PURE__ */ l(h, {
|
|
222
222
|
type: "email",
|
|
223
|
-
value:
|
|
224
|
-
onChange: (e) =>
|
|
223
|
+
value: O.contactEmail,
|
|
224
|
+
onChange: (e) => A("contactEmail", e.target.value)
|
|
225
225
|
})]
|
|
226
226
|
}),
|
|
227
227
|
/* @__PURE__ */ u("label", {
|
|
@@ -230,8 +230,8 @@ function _() {
|
|
|
230
230
|
className: "font-medium text-text-primary",
|
|
231
231
|
children: "Contact Phone"
|
|
232
232
|
}), /* @__PURE__ */ l(h, {
|
|
233
|
-
value:
|
|
234
|
-
onChange: (e) =>
|
|
233
|
+
value: O.contactPhone,
|
|
234
|
+
onChange: (e) => A("contactPhone", e.target.value)
|
|
235
235
|
})]
|
|
236
236
|
})
|
|
237
237
|
]
|
|
@@ -240,16 +240,16 @@ function _() {
|
|
|
240
240
|
className: "flex justify-end",
|
|
241
241
|
children: /* @__PURE__ */ u(p, {
|
|
242
242
|
type: "submit",
|
|
243
|
-
disabled:
|
|
244
|
-
children: [/* @__PURE__ */ l(f, { className: "h-4 w-4" }),
|
|
243
|
+
disabled: M,
|
|
244
|
+
children: [/* @__PURE__ */ l(f, { className: "h-4 w-4" }), M ? "Saving..." : "Save Sponsor"]
|
|
245
245
|
})
|
|
246
246
|
})
|
|
247
247
|
]
|
|
248
|
-
})
|
|
249
|
-
|
|
248
|
+
}) })
|
|
249
|
+
]
|
|
250
250
|
});
|
|
251
251
|
}
|
|
252
252
|
//#endregion
|
|
253
|
-
export {
|
|
253
|
+
export { v as default };
|
|
254
254
|
|
|
255
255
|
//# sourceMappingURL=SponsorFormPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SponsorFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/sponsors/SponsorFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { ArrowLeft, Save } from 'lucide-react';\nimport { Button, GlassCard, Input } from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateSponsorMutation,\n useEventsQuery,\n useSponsorsQuery,\n useUpdateSponsorMutation,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\n\ntype SponsorFormState = {\n eventId: string;\n name: string;\n level: string;\n website: string;\n contactName: string;\n contactEmail: string;\n contactPhone: string;\n value: string;\n leads: string;\n};\n\nconst initialState: SponsorFormState = {\n eventId: '',\n name: '',\n level: 'BRONZE',\n website: '',\n contactName: '',\n contactEmail: '',\n contactPhone: '',\n value: '0',\n leads: '0',\n};\n\nexport default function SponsorFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventsData } = useEventsQuery({ limit: 100, offset: 0 });\n const { data: sponsorsData } = useSponsorsQuery({ limit: 100, offset: 0 });\n\n const existingSponsor = useMemo(\n () => (sponsorsData?.sponsors?.items ?? []).find((item: { id: string }) => item.id === id),\n [id, sponsorsData]\n );\n\n const [createSponsor, { loading: creating }] = useCreateSponsorMutation();\n const [updateSponsor, { loading: updating }] = useUpdateSponsorMutation();\n const [form, setForm] = useState<SponsorFormState>(() => {\n if (!existingSponsor) {\n return initialState;\n }\n return {\n eventId: existingSponsor.eventId ?? '',\n name: existingSponsor.name ?? '',\n level: existingSponsor.level ?? 'BRONZE',\n website: existingSponsor.website ?? '',\n contactName: existingSponsor.contactName ?? '',\n contactEmail: existingSponsor.contactEmail ?? '',\n contactPhone: existingSponsor.contactPhone ?? '',\n value: String(existingSponsor.metrics?.value ?? 0),\n leads: String(existingSponsor.metrics?.leads ?? 0),\n };\n });\n\n useEffect(() => {\n if (!existingSponsor) {\n return;\n }\n setForm({\n eventId: existingSponsor.eventId ?? '',\n name: existingSponsor.name ?? '',\n level: existingSponsor.level ?? 'BRONZE',\n website: existingSponsor.website ?? '',\n contactName: existingSponsor.contactName ?? '',\n contactEmail: existingSponsor.contactEmail ?? '',\n contactPhone: existingSponsor.contactPhone ?? '',\n value: String(existingSponsor.metrics?.value ?? 0),\n leads: String(existingSponsor.metrics?.leads ?? 0),\n });\n }, [existingSponsor]);\n\n const onChange = (field: keyof SponsorFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const input = {\n eventId: form.eventId,\n name: form.name,\n level: form.level,\n website: form.website,\n contactName: form.contactName,\n contactEmail: form.contactEmail,\n contactPhone: form.contactPhone,\n metrics: {\n value: Number(form.value || 0),\n leads: Number(form.leads || 0),\n },\n metadata: {},\n };\n\n if (isEdit) {\n await updateSponsor({ variables: { id, input } });\n navigate('/sponsors');\n return;\n }\n\n await createSponsor({ variables: { input } });\n navigate('/sponsors');\n };\n\n const saving = creating || updating;\n const events = eventsData?.events?.items ?? [];\n const selectClass =\n 'w-full rounded-input border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary transition-colors focus-visible:border-border-focus focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)] focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]';\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/sponsors')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Sponsors\n </Button>\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">{isEdit ? 'Edit Sponsor' : 'Create Sponsor'}</h1>\n </div>\n\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <form onSubmit={onSubmit} className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Event</span>\n <select\n value={form.eventId}\n onChange={(e) => onChange('eventId', e.target.value)}\n required\n className={selectClass}\n >\n <option value=\"\">Select Event</option>\n {events.map((eventItem: { id: string; name: string }) => (\n <option key={eventItem.id} value={eventItem.id}>\n {eventItem.name}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Sponsor Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Level</span>\n <select value={form.level} onChange={(e) => onChange('level', e.target.value)} className={selectClass}>\n <option value=\"PLATINUM\">Platinum</option>\n <option value=\"GOLD\">Gold</option>\n <option value=\"SILVER\">Silver</option>\n <option value=\"BRONZE\">Bronze</option>\n <option value=\"COMMUNITY\">Community</option>\n </select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Value</span>\n <Input type=\"number\" min=\"0\" value={form.value} onChange={(e) => onChange('value', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Leads</span>\n <Input type=\"number\" min=\"0\" value={form.leads} onChange={(e) => onChange('leads', 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\">Website</span>\n <Input value={form.website} onChange={(e) => onChange('website', e.target.value)} />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Name</span>\n <Input value={form.contactName} onChange={(e) => onChange('contactName', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Email</span>\n <Input\n type=\"email\"\n value={form.contactEmail}\n onChange={(e) => onChange('contactEmail', e.target.value)}\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Phone</span>\n <Input value={form.contactPhone} onChange={(e) => onChange('contactPhone', e.target.value)} />\n </label>\n </div>\n\n <div className=\"flex justify-end\">\n <Button type=\"submit\" disabled={saving}>\n <Save className=\"h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Sponsor'}\n </Button>\n </div>\n </form>\n </GlassCard>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SponsorFormPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/sponsors/SponsorFormPage.tsx"],"sourcesContent":["/* eslint-disable react-hooks/set-state-in-effect */\nimport { ArrowLeft, Save } from 'lucide-react';\nimport { Button, EmphasisPanel, Input, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateSponsorMutation,\n useEventsQuery,\n useSponsorsQuery,\n useUpdateSponsorMutation,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\n\ntype SponsorFormState = {\n eventId: string;\n name: string;\n level: string;\n website: string;\n contactName: string;\n contactEmail: string;\n contactPhone: string;\n value: string;\n leads: string;\n};\n\nconst initialState: SponsorFormState = {\n eventId: '',\n name: '',\n level: 'BRONZE',\n website: '',\n contactName: '',\n contactEmail: '',\n contactPhone: '',\n value: '0',\n leads: '0',\n};\n\nexport default function SponsorFormPage() {\n const { id = '' } = useParams<{ id: string }>();\n const isEdit = useMemo(() => Boolean(id), [id]);\n const { navigate } = useEventfullyManaged();\n\n const { data: eventsData } = useEventsQuery({ limit: 100, offset: 0 });\n const { data: sponsorsData } = useSponsorsQuery({ limit: 100, offset: 0 });\n\n const existingSponsor = useMemo(\n () => (sponsorsData?.sponsors?.items ?? []).find((item: { id: string }) => item.id === id),\n [id, sponsorsData]\n );\n\n const [createSponsor, { loading: creating }] = useCreateSponsorMutation();\n const [updateSponsor, { loading: updating }] = useUpdateSponsorMutation();\n const [form, setForm] = useState<SponsorFormState>(() => {\n if (!existingSponsor) {\n return initialState;\n }\n return {\n eventId: existingSponsor.eventId ?? '',\n name: existingSponsor.name ?? '',\n level: existingSponsor.level ?? 'BRONZE',\n website: existingSponsor.website ?? '',\n contactName: existingSponsor.contactName ?? '',\n contactEmail: existingSponsor.contactEmail ?? '',\n contactPhone: existingSponsor.contactPhone ?? '',\n value: String(existingSponsor.metrics?.value ?? 0),\n leads: String(existingSponsor.metrics?.leads ?? 0),\n };\n });\n\n useEffect(() => {\n if (!existingSponsor) {\n return;\n }\n setForm({\n eventId: existingSponsor.eventId ?? '',\n name: existingSponsor.name ?? '',\n level: existingSponsor.level ?? 'BRONZE',\n website: existingSponsor.website ?? '',\n contactName: existingSponsor.contactName ?? '',\n contactEmail: existingSponsor.contactEmail ?? '',\n contactPhone: existingSponsor.contactPhone ?? '',\n value: String(existingSponsor.metrics?.value ?? 0),\n leads: String(existingSponsor.metrics?.leads ?? 0),\n });\n }, [existingSponsor]);\n\n const onChange = (field: keyof SponsorFormState, value: string) => {\n setForm((prev) => ({ ...prev, [field]: value }));\n };\n\n const onSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const input = {\n eventId: form.eventId,\n name: form.name,\n level: form.level,\n website: form.website,\n contactName: form.contactName,\n contactEmail: form.contactEmail,\n contactPhone: form.contactPhone,\n metrics: {\n value: Number(form.value || 0),\n leads: Number(form.leads || 0),\n },\n metadata: {},\n };\n\n if (isEdit) {\n await updateSponsor({ variables: { id, input } });\n navigate('/sponsors');\n return;\n }\n\n await createSponsor({ variables: { input } });\n navigate('/sponsors');\n };\n\n const saving = creating || updating;\n const events = eventsData?.events?.items ?? [];\n const selectClass =\n 'w-full rounded-input border border-border-default bg-bg-surface px-3 py-2 text-sm text-text-primary transition-colors focus-visible:border-border-focus focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)] focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]';\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/sponsors')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Sponsors\n </Button>\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">{isEdit ? 'Edit Sponsor' : 'Create Sponsor'}</h1>\n </div>\n\n <PagePurpose>\n Capture a sponsor and the deal behind it. Link them to an event, set their tier, and record the contract value\n and leads target so you can measure ROI later. The contact fields are who you will work with day to day, so\n keep them accurate.\n </PagePurpose>\n\n <EmphasisPanel>\n <form onSubmit={onSubmit} className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Event</span>\n <select\n value={form.eventId}\n onChange={(e) => onChange('eventId', e.target.value)}\n required\n className={selectClass}\n >\n <option value=\"\">Select Event</option>\n {events.map((eventItem: { id: string; name: string }) => (\n <option key={eventItem.id} value={eventItem.id}>\n {eventItem.name}\n </option>\n ))}\n </select>\n </label>\n\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Sponsor Name</span>\n <Input value={form.name} onChange={(e) => onChange('name', e.target.value)} required />\n </label>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Level</span>\n <select value={form.level} onChange={(e) => onChange('level', e.target.value)} className={selectClass}>\n <option value=\"PLATINUM\">Platinum</option>\n <option value=\"GOLD\">Gold</option>\n <option value=\"SILVER\">Silver</option>\n <option value=\"BRONZE\">Bronze</option>\n <option value=\"COMMUNITY\">Community</option>\n </select>\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Value</span>\n <Input type=\"number\" min=\"0\" value={form.value} onChange={(e) => onChange('value', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Leads</span>\n <Input type=\"number\" min=\"0\" value={form.leads} onChange={(e) => onChange('leads', 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\">Website</span>\n <Input value={form.website} onChange={(e) => onChange('website', e.target.value)} />\n </label>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Name</span>\n <Input value={form.contactName} onChange={(e) => onChange('contactName', e.target.value)} />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Email</span>\n <Input\n type=\"email\"\n value={form.contactEmail}\n onChange={(e) => onChange('contactEmail', e.target.value)}\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Contact Phone</span>\n <Input value={form.contactPhone} onChange={(e) => onChange('contactPhone', e.target.value)} />\n </label>\n </div>\n\n <div className=\"flex justify-end\">\n <Button type=\"submit\" disabled={saving}>\n <Save className=\"h-4 w-4\" />\n {saving ? 'Saving...' : 'Save Sponsor'}\n </Button>\n </div>\n </form>\n </EmphasisPanel>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -3,17 +3,18 @@ import { useSponsorsQuery as t } from "../../api/eventApi.js";
|
|
|
3
3
|
import { useMemo as n, useState as r } from "react";
|
|
4
4
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
5
5
|
import { Building2 as o, Mail as s, Phone as c, Plus as l, Search as u } from "lucide-react";
|
|
6
|
-
import { Badge as d, Button as f, GlassCard as p, IllustratedEmptyState as m, Input as h } from "@burdenoff/fe-libs/ui";
|
|
6
|
+
import { Badge as d, Button as f, GlassCard as p, IllustratedEmptyState as m, Input as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
|
|
7
7
|
//#region src/eventfullymanaged/pages/sponsors/SponsorsListPage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { navigate:
|
|
10
|
-
search:
|
|
8
|
+
function _() {
|
|
9
|
+
let { navigate: _ } = e(), [v, y] = r(""), { data: b, loading: x } = t({
|
|
10
|
+
search: v,
|
|
11
11
|
limit: 100,
|
|
12
12
|
offset: 0
|
|
13
|
-
}),
|
|
13
|
+
}), S = n(() => b?.sponsors?.items ?? [], [b]), C = S.reduce((e, t) => e + Number(t.metrics?.value ?? 0), 0), w = S.reduce((e, t) => e + Number(t.metrics?.leads ?? 0), 0);
|
|
14
14
|
return /* @__PURE__ */ a("div", {
|
|
15
15
|
className: "space-y-6 p-6",
|
|
16
16
|
children: [
|
|
17
|
+
/* @__PURE__ */ i(g, { children: "Sponsors fund your event in exchange for visibility and leads. Track each one here — their tier, the contract value they bring, and the leads they generate — so you can prove ROI and keep the relationship warm for next time. The highlighted cards summarize your sponsor portfolio at a glance." }),
|
|
17
18
|
/* @__PURE__ */ a("div", {
|
|
18
19
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
19
20
|
children: [/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("h1", {
|
|
@@ -24,7 +25,7 @@ function g() {
|
|
|
24
25
|
children: "Manage event sponsors with live API data."
|
|
25
26
|
})] }), /* @__PURE__ */ a(f, {
|
|
26
27
|
type: "button",
|
|
27
|
-
onClick: () =>
|
|
28
|
+
onClick: () => _("/sponsors/create"),
|
|
28
29
|
children: [/* @__PURE__ */ i(l, { className: "h-4 w-4" }), "Add Sponsor"]
|
|
29
30
|
})]
|
|
30
31
|
}),
|
|
@@ -40,7 +41,7 @@ function g() {
|
|
|
40
41
|
children: "Total Sponsors"
|
|
41
42
|
}), /* @__PURE__ */ i("p", {
|
|
42
43
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
43
|
-
children:
|
|
44
|
+
children: S.length
|
|
44
45
|
})]
|
|
45
46
|
}),
|
|
46
47
|
/* @__PURE__ */ a(p, {
|
|
@@ -51,7 +52,7 @@ function g() {
|
|
|
51
52
|
children: "Total Contract Value"
|
|
52
53
|
}), /* @__PURE__ */ a("p", {
|
|
53
54
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
54
|
-
children: ["$",
|
|
55
|
+
children: ["$", C.toLocaleString()]
|
|
55
56
|
})]
|
|
56
57
|
}),
|
|
57
58
|
/* @__PURE__ */ a(p, {
|
|
@@ -62,7 +63,7 @@ function g() {
|
|
|
62
63
|
children: "Total Leads"
|
|
63
64
|
}), /* @__PURE__ */ i("p", {
|
|
64
65
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
65
|
-
children:
|
|
66
|
+
children: w.toLocaleString()
|
|
66
67
|
})]
|
|
67
68
|
})
|
|
68
69
|
]
|
|
@@ -71,40 +72,40 @@ function g() {
|
|
|
71
72
|
className: "relative",
|
|
72
73
|
children: [/* @__PURE__ */ i(u, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-muted" }), /* @__PURE__ */ i(h, {
|
|
73
74
|
type: "text",
|
|
74
|
-
value:
|
|
75
|
-
onChange: (e) =>
|
|
75
|
+
value: v,
|
|
76
|
+
onChange: (e) => y(e.target.value),
|
|
76
77
|
placeholder: "Search sponsors",
|
|
77
78
|
"aria-label": "Search sponsors",
|
|
78
79
|
className: "pl-10"
|
|
79
80
|
})]
|
|
80
81
|
}),
|
|
81
|
-
|
|
82
|
+
x ? /* @__PURE__ */ i(p, {
|
|
82
83
|
treatment: "plain",
|
|
83
84
|
className: "border-border-seam p-8 text-center text-sm text-text-secondary",
|
|
84
85
|
children: "Loading sponsors..."
|
|
85
|
-
}) :
|
|
86
|
+
}) : S.length === 0 ? /* @__PURE__ */ i(p, {
|
|
86
87
|
treatment: "plain",
|
|
87
88
|
className: "border-border-seam",
|
|
88
89
|
children: /* @__PURE__ */ i(m, {
|
|
89
|
-
illustration:
|
|
90
|
-
title:
|
|
91
|
-
description:
|
|
92
|
-
action:
|
|
90
|
+
illustration: v ? "empty-search" : "empty-people",
|
|
91
|
+
title: v ? "No sponsors match your search." : "No sponsors yet.",
|
|
92
|
+
description: v ? "Try a different name." : "Add your first sponsor to start tracking value and leads.",
|
|
93
|
+
action: v ? void 0 : /* @__PURE__ */ a(f, {
|
|
93
94
|
type: "button",
|
|
94
|
-
onClick: () =>
|
|
95
|
+
onClick: () => _("/sponsors/create"),
|
|
95
96
|
children: [/* @__PURE__ */ i(l, { className: "h-4 w-4" }), "Add Sponsor"]
|
|
96
97
|
})
|
|
97
98
|
})
|
|
98
99
|
}) : /* @__PURE__ */ i("div", {
|
|
99
100
|
className: "space-y-4",
|
|
100
|
-
children:
|
|
101
|
+
children: S.map((e) => /* @__PURE__ */ a(p, {
|
|
101
102
|
treatment: "plain",
|
|
102
103
|
className: "border-border-seam p-5",
|
|
103
104
|
children: [/* @__PURE__ */ a("div", {
|
|
104
105
|
className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
|
|
105
106
|
children: [/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("button", {
|
|
106
107
|
type: "button",
|
|
107
|
-
onClick: () =>
|
|
108
|
+
onClick: () => _(`/sponsors/${e.id}/edit`),
|
|
108
109
|
className: "rounded-button text-left text-lg font-semibold text-text-primary transition-colors hover:text-text-link focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]",
|
|
109
110
|
children: e.name
|
|
110
111
|
}), /* @__PURE__ */ a("div", {
|
|
@@ -144,6 +145,6 @@ function g() {
|
|
|
144
145
|
});
|
|
145
146
|
}
|
|
146
147
|
//#endregion
|
|
147
|
-
export {
|
|
148
|
+
export { _ as default };
|
|
148
149
|
|
|
149
150
|
//# sourceMappingURL=SponsorsListPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SponsorsListPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/sponsors/SponsorsListPage.tsx"],"sourcesContent":["import { Building2, Mail, Phone, Plus, Search } from 'lucide-react';\nimport { Badge, Button, GlassCard, IllustratedEmptyState, Input } from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\n\nimport { useSponsorsQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\n\ntype SponsorItem = {\n id: string;\n eventId: string;\n name: string;\n level: string;\n website?: string | null;\n contactName?: string | null;\n contactEmail?: string | null;\n contactPhone?: string | null;\n metrics?: { value?: number; leads?: number } | null;\n};\n\nexport default function SponsorsListPage() {\n const { navigate } = useEventfullyManaged();\n const [search, setSearch] = useState('');\n const { data, loading } = useSponsorsQuery({ search, limit: 100, offset: 0 });\n\n const sponsors = useMemo(() => (data?.sponsors?.items ?? []) as SponsorItem[], [data]);\n\n const totalValue = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.value ?? 0), 0);\n const totalLeads = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.leads ?? 0), 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">Sponsors</h1>\n <p className=\"mt-1 text-sm text-text-secondary\">Manage event sponsors with live API data.</p>\n </div>\n <Button type=\"button\" onClick={() => navigate('/sponsors/create')}>\n <Plus className=\"h-4 w-4\" />\n Add Sponsor\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Sponsors</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">{sponsors.length}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Contract Value</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">${totalValue.toLocaleString()}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Leads</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">{totalLeads.toLocaleString()}</p>\n </GlassCard>\n </div>\n\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-muted\" />\n <Input\n type=\"text\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n placeholder=\"Search sponsors\"\n aria-label=\"Search sponsors\"\n className=\"pl-10\"\n />\n </div>\n\n {loading ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-8 text-center text-sm text-text-secondary\">\n Loading sponsors...\n </GlassCard>\n ) : sponsors.length === 0 ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <IllustratedEmptyState\n illustration={search ? 'empty-search' : 'empty-people'}\n title={search ? 'No sponsors match your search.' : 'No sponsors yet.'}\n description={search ? 'Try a different name.' : 'Add your first sponsor to start tracking value and leads.'}\n action={\n !search ? (\n <Button type=\"button\" onClick={() => navigate('/sponsors/create')}>\n <Plus className=\"h-4 w-4\" />\n Add Sponsor\n </Button>\n ) : undefined\n }\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-4\">\n {sponsors.map((sponsor) => (\n <GlassCard key={sponsor.id} treatment=\"plain\" className=\"border-border-seam p-5\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <button\n type=\"button\"\n onClick={() => navigate(`/sponsors/${sponsor.id}/edit`)}\n className=\"rounded-button text-left text-lg font-semibold text-text-primary transition-colors hover:text-text-link focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {sponsor.name}\n </button>\n <div className=\"mt-1 flex items-center gap-2 text-sm text-text-secondary\">\n <Building2 className=\"h-4 w-4\" />\n <Badge variant=\"secondary\" className=\"uppercase\">\n {sponsor.level}\n </Badge>\n </div>\n </div>\n <div className=\"text-sm tabular-nums text-text-secondary\">\n <p>Value: ${Number(sponsor.metrics?.value ?? 0).toLocaleString()}</p>\n <p>Leads: {Number(sponsor.metrics?.leads ?? 0).toLocaleString()}</p>\n </div>\n </div>\n\n <div className=\"mt-4 grid grid-cols-1 gap-2 text-sm text-text-secondary sm:grid-cols-3\">\n <div className=\"flex items-center gap-2\">\n <Mail className=\"h-4 w-4\" />\n <span>{sponsor.contactEmail ?? 'No email'}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <Phone className=\"h-4 w-4\" />\n <span>{sponsor.contactPhone ?? 'No phone'}</span>\n </div>\n <div>\n {sponsor.website ? (\n <a\n href={sponsor.website}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-text-link hover:underline\"\n >\n {sponsor.website}\n </a>\n ) : (\n 'No website'\n )}\n </div>\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SponsorsListPage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/sponsors/SponsorsListPage.tsx"],"sourcesContent":["import { Building2, Mail, Phone, Plus, Search } from 'lucide-react';\nimport { Badge, Button, GlassCard, IllustratedEmptyState, Input, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMemo, useState } from 'react';\n\nimport { useSponsorsQuery } from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\n\ntype SponsorItem = {\n id: string;\n eventId: string;\n name: string;\n level: string;\n website?: string | null;\n contactName?: string | null;\n contactEmail?: string | null;\n contactPhone?: string | null;\n metrics?: { value?: number; leads?: number } | null;\n};\n\nexport default function SponsorsListPage() {\n const { navigate } = useEventfullyManaged();\n const [search, setSearch] = useState('');\n const { data, loading } = useSponsorsQuery({ search, limit: 100, offset: 0 });\n\n const sponsors = useMemo(() => (data?.sponsors?.items ?? []) as SponsorItem[], [data]);\n\n const totalValue = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.value ?? 0), 0);\n const totalLeads = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.leads ?? 0), 0);\n\n return (\n <div className=\"space-y-6 p-6\">\n <PagePurpose>\n Sponsors fund your event in exchange for visibility and leads. Track each one here — their tier, the contract\n value they bring, and the leads they generate — so you can prove ROI and keep the relationship warm for next\n time. The highlighted cards summarize your sponsor portfolio at a glance.\n </PagePurpose>\n\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">Sponsors</h1>\n <p className=\"mt-1 text-sm text-text-secondary\">Manage event sponsors with live API data.</p>\n </div>\n <Button type=\"button\" onClick={() => navigate('/sponsors/create')}>\n <Plus className=\"h-4 w-4\" />\n Add Sponsor\n </Button>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n <GlassCard treatment=\"glass\" glow className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Sponsors</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">{sponsors.length}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Contract Value</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">${totalValue.toLocaleString()}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Total Leads</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">{totalLeads.toLocaleString()}</p>\n </GlassCard>\n </div>\n\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-muted\" />\n <Input\n type=\"text\"\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n placeholder=\"Search sponsors\"\n aria-label=\"Search sponsors\"\n className=\"pl-10\"\n />\n </div>\n\n {loading ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-8 text-center text-sm text-text-secondary\">\n Loading sponsors...\n </GlassCard>\n ) : sponsors.length === 0 ? (\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <IllustratedEmptyState\n illustration={search ? 'empty-search' : 'empty-people'}\n title={search ? 'No sponsors match your search.' : 'No sponsors yet.'}\n description={search ? 'Try a different name.' : 'Add your first sponsor to start tracking value and leads.'}\n action={\n !search ? (\n <Button type=\"button\" onClick={() => navigate('/sponsors/create')}>\n <Plus className=\"h-4 w-4\" />\n Add Sponsor\n </Button>\n ) : undefined\n }\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-4\">\n {sponsors.map((sponsor) => (\n <GlassCard key={sponsor.id} treatment=\"plain\" className=\"border-border-seam p-5\">\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between\">\n <div>\n <button\n type=\"button\"\n onClick={() => navigate(`/sponsors/${sponsor.id}/edit`)}\n className=\"rounded-button text-left text-lg font-semibold text-text-primary transition-colors hover:text-text-link focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n {sponsor.name}\n </button>\n <div className=\"mt-1 flex items-center gap-2 text-sm text-text-secondary\">\n <Building2 className=\"h-4 w-4\" />\n <Badge variant=\"secondary\" className=\"uppercase\">\n {sponsor.level}\n </Badge>\n </div>\n </div>\n <div className=\"text-sm tabular-nums text-text-secondary\">\n <p>Value: ${Number(sponsor.metrics?.value ?? 0).toLocaleString()}</p>\n <p>Leads: {Number(sponsor.metrics?.leads ?? 0).toLocaleString()}</p>\n </div>\n </div>\n\n <div className=\"mt-4 grid grid-cols-1 gap-2 text-sm text-text-secondary sm:grid-cols-3\">\n <div className=\"flex items-center gap-2\">\n <Mail className=\"h-4 w-4\" />\n <span>{sponsor.contactEmail ?? 'No email'}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <Phone className=\"h-4 w-4\" />\n <span>{sponsor.contactPhone ?? 'No phone'}</span>\n </div>\n <div>\n {sponsor.website ? (\n <a\n href={sponsor.website}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-text-link hover:underline\"\n >\n {sponsor.website}\n </a>\n ) : (\n 'No website'\n )}\n </div>\n </div>\n </GlassCard>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|