@burdenoff/microfe-eventfullymanaged 2026.703.1 → 2026.704.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/eventfullymanaged/EventfullyManagedRoutes.js +154 -66
- package/dist/eventfullymanaged/EventfullyManagedRoutes.js.map +1 -1
- package/dist/eventfullymanaged/api/eventApi.js +546 -68
- package/dist/eventfullymanaged/api/eventApi.js.map +1 -1
- package/dist/eventfullymanaged/components/ActionMenu.js +113 -0
- package/dist/eventfullymanaged/components/ActionMenu.js.map +1 -0
- package/dist/eventfullymanaged/components/EntityFormShell.js +51 -0
- package/dist/eventfullymanaged/components/EntityFormShell.js.map +1 -0
- package/dist/eventfullymanaged/components/EntityTagsField.js +146 -0
- package/dist/eventfullymanaged/components/EntityTagsField.js.map +1 -0
- package/dist/eventfullymanaged/components/Pagination.js +84 -0
- package/dist/eventfullymanaged/components/Pagination.js.map +1 -0
- package/dist/eventfullymanaged/components/SafeLink.js +32 -0
- package/dist/eventfullymanaged/components/SafeLink.js.map +1 -0
- package/dist/eventfullymanaged/components/index.js +7 -0
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js +458 -0
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/events/EventFormPage.js +267 -0
- package/dist/eventfullymanaged/pages/events/EventFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js +308 -0
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js +214 -0
- package/dist/eventfullymanaged/pages/events/TicketTypeFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/events/eventFormUtils.js +128 -0
- package/dist/eventfullymanaged/pages/events/eventFormUtils.js.map +1 -0
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js +233 -0
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorsPage.js +165 -0
- package/dist/eventfullymanaged/pages/exhibitors/ExhibitorsPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/leads/LeadCaptureDialog.js +141 -0
- package/dist/eventfullymanaged/pages/leads/LeadCaptureDialog.js.map +1 -0
- package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js +178 -45
- package/dist/eventfullymanaged/pages/modules/AnalyticsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/CommunicationPage.js +240 -70
- package/dist/eventfullymanaged/pages/modules/CommunicationPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/EventsPage.js +133 -97
- package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/KioskPage.js +746 -36
- package/dist/eventfullymanaged/pages/modules/KioskPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +210 -69
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/OperationsHubPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +289 -77
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/RoadmapPanel.js +95 -0
- package/dist/eventfullymanaged/pages/modules/RoadmapPanel.js.map +1 -0
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js +77 -56
- package/dist/eventfullymanaged/pages/modules/SponsorDetailsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js +70 -36
- package/dist/eventfullymanaged/pages/modules/SponsorLeadsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js +343 -0
- package/dist/eventfullymanaged/pages/networking/MeetingFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js +236 -0
- package/dist/eventfullymanaged/pages/networking/NetworkingProfileFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js +181 -0
- package/dist/eventfullymanaged/pages/registration/AttendeeFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js +262 -0
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js +414 -0
- package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js.map +1 -0
- package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js +224 -0
- package/dist/eventfullymanaged/pages/speakers/SpeakerFormPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/speakers/SpeakersPage.js +96 -0
- package/dist/eventfullymanaged/pages/speakers/SpeakersPage.js.map +1 -0
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js +149 -140
- package/dist/eventfullymanaged/pages/sponsors/SponsorFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js +97 -67
- package/dist/eventfullymanaged/pages/sponsors/SponsorsListPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js +93 -72
- package/dist/eventfullymanaged/pages/venues/VenueDetailPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js +91 -89
- package/dist/eventfullymanaged/pages/venues/VenueFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/venues/VenueListPage.js +83 -53
- package/dist/eventfullymanaged/pages/venues/VenueListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,14 +2,15 @@ import { useEventfullyManaged as e } from "../../context/EventfullyManagedContex
|
|
|
2
2
|
import { notify as t } from "../../lib/toast.js";
|
|
3
3
|
import { useCreateSponsorMutation as n, useEventsQuery as r, useSponsorsQuery as i, useUpdateSponsorMutation as a } from "../../api/eventApi.js";
|
|
4
4
|
import { describeError as o, mutationSucceeded as s } from "../../lib/mutationResult.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
5
|
+
import { safeUrl as c } from "../../components/SafeLink.js";
|
|
6
|
+
import { ImageUploadField as l } from "../../components/ImageUploadField.js";
|
|
7
|
+
import { useEffect as u, useMemo as d, useState as f } from "react";
|
|
8
|
+
import { useParams as p } from "react-router-dom";
|
|
9
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
10
|
+
import { ArrowLeft as g, Save as _ } from "lucide-react";
|
|
11
|
+
import { Button as v, EmphasisPanel as y, Input as b, PagePurpose as x, Select as S, SelectContent as C, SelectItem as w, SelectTrigger as T, SelectValue as E } from "@burdenoff/fe-libs/ui";
|
|
11
12
|
//#region src/eventfullymanaged/pages/sponsors/SponsorFormPage.tsx
|
|
12
|
-
var
|
|
13
|
+
var D = {
|
|
13
14
|
eventId: "",
|
|
14
15
|
name: "",
|
|
15
16
|
level: "BRONZE",
|
|
@@ -21,255 +22,263 @@ var x = {
|
|
|
21
22
|
value: "0",
|
|
22
23
|
leads: "0"
|
|
23
24
|
};
|
|
24
|
-
function
|
|
25
|
-
let { id:
|
|
25
|
+
function O() {
|
|
26
|
+
let { id: O = "" } = p(), k = d(() => !!O, [O]), { navigate: A } = e(), { data: j } = r({
|
|
26
27
|
limit: 100,
|
|
27
28
|
offset: 0
|
|
28
|
-
}), { data:
|
|
29
|
+
}), { data: M } = i({
|
|
29
30
|
limit: 100,
|
|
30
31
|
offset: 0
|
|
31
|
-
}),
|
|
32
|
-
eventId:
|
|
33
|
-
name:
|
|
34
|
-
level:
|
|
35
|
-
logoUrl:
|
|
36
|
-
website:
|
|
37
|
-
contactName:
|
|
38
|
-
contactEmail:
|
|
39
|
-
contactPhone:
|
|
40
|
-
value: String(
|
|
41
|
-
leads: String(
|
|
42
|
-
} :
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
eventId:
|
|
46
|
-
name:
|
|
47
|
-
level:
|
|
48
|
-
logoUrl:
|
|
49
|
-
website:
|
|
50
|
-
contactName:
|
|
51
|
-
contactEmail:
|
|
52
|
-
contactPhone:
|
|
53
|
-
value: String(
|
|
54
|
-
leads: String(
|
|
32
|
+
}), N = d(() => (M?.sponsors?.items ?? []).find((e) => e.id === O), [O, M]), [P, { loading: F }] = n(), [I, { loading: L }] = a(), [R, z] = f(() => N ? {
|
|
33
|
+
eventId: N.eventId ?? "",
|
|
34
|
+
name: N.name ?? "",
|
|
35
|
+
level: N.level ?? "BRONZE",
|
|
36
|
+
logoUrl: N.logoUrl ?? "",
|
|
37
|
+
website: N.website ?? "",
|
|
38
|
+
contactName: N.contactName ?? "",
|
|
39
|
+
contactEmail: N.contactEmail ?? "",
|
|
40
|
+
contactPhone: N.contactPhone ?? "",
|
|
41
|
+
value: String(N.metrics?.value ?? 0),
|
|
42
|
+
leads: String(N.metrics?.leads ?? 0)
|
|
43
|
+
} : D);
|
|
44
|
+
u(() => {
|
|
45
|
+
N && z({
|
|
46
|
+
eventId: N.eventId ?? "",
|
|
47
|
+
name: N.name ?? "",
|
|
48
|
+
level: N.level ?? "BRONZE",
|
|
49
|
+
logoUrl: N.logoUrl ?? "",
|
|
50
|
+
website: N.website ?? "",
|
|
51
|
+
contactName: N.contactName ?? "",
|
|
52
|
+
contactEmail: N.contactEmail ?? "",
|
|
53
|
+
contactPhone: N.contactPhone ?? "",
|
|
54
|
+
value: String(N.metrics?.value ?? 0),
|
|
55
|
+
leads: String(N.metrics?.leads ?? 0)
|
|
55
56
|
});
|
|
56
|
-
}, [
|
|
57
|
-
let
|
|
58
|
-
|
|
57
|
+
}, [N]);
|
|
58
|
+
let B = (e, t) => {
|
|
59
|
+
z((n) => ({
|
|
59
60
|
...n,
|
|
60
61
|
[e]: t
|
|
61
62
|
}));
|
|
62
|
-
},
|
|
63
|
-
e.preventDefault()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
website
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
}, V = async (e) => {
|
|
64
|
+
if (e.preventDefault(), !R.eventId) {
|
|
65
|
+
t.error("Event required", "Choose the event this sponsor belongs to.");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
let n = c(R.website);
|
|
69
|
+
if (R.website.trim() && !n) {
|
|
70
|
+
t.error("Invalid website", "Enter a valid http(s) URL, or leave it blank.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
let r = {
|
|
74
|
+
eventId: R.eventId,
|
|
75
|
+
name: R.name,
|
|
76
|
+
level: R.level,
|
|
77
|
+
logoUrl: R.logoUrl,
|
|
78
|
+
website: n ?? "",
|
|
79
|
+
contactName: R.contactName,
|
|
80
|
+
contactEmail: R.contactEmail,
|
|
81
|
+
contactPhone: R.contactPhone,
|
|
73
82
|
metrics: {
|
|
74
|
-
value: Number(
|
|
75
|
-
leads: Number(
|
|
83
|
+
value: Number(R.value || 0),
|
|
84
|
+
leads: Number(R.leads || 0)
|
|
76
85
|
},
|
|
77
86
|
metadata: {}
|
|
78
87
|
};
|
|
79
88
|
try {
|
|
80
|
-
if (
|
|
81
|
-
let e = await
|
|
82
|
-
id:
|
|
83
|
-
input:
|
|
89
|
+
if (k) {
|
|
90
|
+
let e = await I({ variables: {
|
|
91
|
+
id: O,
|
|
92
|
+
input: r
|
|
84
93
|
} });
|
|
85
94
|
if (!s(e, e.data?.updateSponsor?.id, "Could not update sponsor")) return;
|
|
86
|
-
|
|
95
|
+
A("/sponsors");
|
|
87
96
|
return;
|
|
88
97
|
}
|
|
89
|
-
let e = await
|
|
98
|
+
let e = await P({ variables: { input: r } });
|
|
90
99
|
if (!s(e, e.data?.createSponsor?.id, "Could not create sponsor")) return;
|
|
91
|
-
|
|
100
|
+
A("/sponsors");
|
|
92
101
|
} catch (e) {
|
|
93
102
|
t.error("Could not save sponsor", o(e));
|
|
94
103
|
}
|
|
95
|
-
},
|
|
96
|
-
return /* @__PURE__ */
|
|
104
|
+
}, H = F || L, U = j?.events?.items ?? [];
|
|
105
|
+
return /* @__PURE__ */ h("div", {
|
|
97
106
|
className: "space-y-6 p-6",
|
|
98
107
|
children: [
|
|
99
|
-
/* @__PURE__ */
|
|
108
|
+
/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h(v, {
|
|
100
109
|
type: "button",
|
|
101
110
|
variant: "ghost",
|
|
102
111
|
size: "sm",
|
|
103
|
-
onClick: () =>
|
|
104
|
-
children: [/* @__PURE__ */
|
|
105
|
-
}), /* @__PURE__ */
|
|
112
|
+
onClick: () => A("/sponsors"),
|
|
113
|
+
children: [/* @__PURE__ */ m(g, { className: "h-4 w-4" }), "Back to Sponsors"]
|
|
114
|
+
}), /* @__PURE__ */ m("h1", {
|
|
106
115
|
className: "mt-3 text-2xl font-bold text-text-primary",
|
|
107
|
-
children:
|
|
116
|
+
children: k ? "Edit Sponsor" : "Create Sponsor"
|
|
108
117
|
})] }),
|
|
109
|
-
/* @__PURE__ */
|
|
110
|
-
/* @__PURE__ */
|
|
111
|
-
onSubmit:
|
|
118
|
+
/* @__PURE__ */ m(x, { 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." }),
|
|
119
|
+
/* @__PURE__ */ m(y, { children: /* @__PURE__ */ h("form", {
|
|
120
|
+
onSubmit: V,
|
|
112
121
|
className: "space-y-4",
|
|
113
122
|
children: [
|
|
114
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ h("div", {
|
|
115
124
|
className: "grid grid-cols-1 gap-4 md:grid-cols-2",
|
|
116
|
-
children: [/* @__PURE__ */
|
|
125
|
+
children: [/* @__PURE__ */ h("label", {
|
|
117
126
|
className: "space-y-1 text-sm",
|
|
118
|
-
children: [/* @__PURE__ */
|
|
127
|
+
children: [/* @__PURE__ */ m("span", {
|
|
119
128
|
className: "font-medium text-text-primary",
|
|
120
129
|
children: "Event"
|
|
121
|
-
}), /* @__PURE__ */
|
|
122
|
-
value:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
children: "Select Event"
|
|
129
|
-
}), L.map((e) => /* @__PURE__ */ p("option", {
|
|
130
|
+
}), /* @__PURE__ */ h(S, {
|
|
131
|
+
value: R.eventId,
|
|
132
|
+
onValueChange: (e) => B("eventId", e),
|
|
133
|
+
children: [/* @__PURE__ */ m(T, {
|
|
134
|
+
"aria-label": "Event",
|
|
135
|
+
children: /* @__PURE__ */ m(E, { placeholder: "Select Event" })
|
|
136
|
+
}), /* @__PURE__ */ m(C, { children: U.map((e) => /* @__PURE__ */ m(w, {
|
|
130
137
|
value: e.id,
|
|
131
138
|
children: e.name
|
|
132
|
-
}, e.id))]
|
|
139
|
+
}, e.id)) })]
|
|
133
140
|
})]
|
|
134
|
-
}), /* @__PURE__ */
|
|
141
|
+
}), /* @__PURE__ */ h("label", {
|
|
135
142
|
className: "space-y-1 text-sm",
|
|
136
|
-
children: [/* @__PURE__ */
|
|
143
|
+
children: [/* @__PURE__ */ m("span", {
|
|
137
144
|
className: "font-medium text-text-primary",
|
|
138
145
|
children: "Sponsor Name"
|
|
139
|
-
}), /* @__PURE__ */
|
|
140
|
-
value:
|
|
141
|
-
onChange: (e) =>
|
|
146
|
+
}), /* @__PURE__ */ m(b, {
|
|
147
|
+
value: R.name,
|
|
148
|
+
onChange: (e) => B("name", e.target.value),
|
|
142
149
|
required: !0
|
|
143
150
|
})]
|
|
144
151
|
})]
|
|
145
152
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ h("div", {
|
|
147
154
|
className: "grid grid-cols-1 gap-4 md:grid-cols-3",
|
|
148
155
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
156
|
+
/* @__PURE__ */ h("label", {
|
|
150
157
|
className: "space-y-1 text-sm",
|
|
151
|
-
children: [/* @__PURE__ */
|
|
158
|
+
children: [/* @__PURE__ */ m("span", {
|
|
152
159
|
className: "font-medium text-text-primary",
|
|
153
160
|
children: "Level"
|
|
154
|
-
}), /* @__PURE__ */
|
|
155
|
-
value:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
/* @__PURE__ */
|
|
161
|
+
}), /* @__PURE__ */ h(S, {
|
|
162
|
+
value: R.level,
|
|
163
|
+
onValueChange: (e) => B("level", e),
|
|
164
|
+
children: [/* @__PURE__ */ m(T, {
|
|
165
|
+
"aria-label": "Level",
|
|
166
|
+
children: /* @__PURE__ */ m(E, {})
|
|
167
|
+
}), /* @__PURE__ */ h(C, { children: [
|
|
168
|
+
/* @__PURE__ */ m(w, {
|
|
160
169
|
value: "PLATINUM",
|
|
161
170
|
children: "Platinum"
|
|
162
171
|
}),
|
|
163
|
-
/* @__PURE__ */
|
|
172
|
+
/* @__PURE__ */ m(w, {
|
|
164
173
|
value: "GOLD",
|
|
165
174
|
children: "Gold"
|
|
166
175
|
}),
|
|
167
|
-
/* @__PURE__ */
|
|
176
|
+
/* @__PURE__ */ m(w, {
|
|
168
177
|
value: "SILVER",
|
|
169
178
|
children: "Silver"
|
|
170
179
|
}),
|
|
171
|
-
/* @__PURE__ */
|
|
180
|
+
/* @__PURE__ */ m(w, {
|
|
172
181
|
value: "BRONZE",
|
|
173
182
|
children: "Bronze"
|
|
174
183
|
}),
|
|
175
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ m(w, {
|
|
176
185
|
value: "COMMUNITY",
|
|
177
186
|
children: "Community"
|
|
178
187
|
})
|
|
179
|
-
]
|
|
188
|
+
] })]
|
|
180
189
|
})]
|
|
181
190
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ h("label", {
|
|
183
192
|
className: "space-y-1 text-sm",
|
|
184
|
-
children: [/* @__PURE__ */
|
|
193
|
+
children: [/* @__PURE__ */ m("span", {
|
|
185
194
|
className: "font-medium text-text-primary",
|
|
186
195
|
children: "Value"
|
|
187
|
-
}), /* @__PURE__ */
|
|
196
|
+
}), /* @__PURE__ */ m(b, {
|
|
188
197
|
type: "number",
|
|
189
198
|
min: "0",
|
|
190
|
-
value:
|
|
191
|
-
onChange: (e) =>
|
|
199
|
+
value: R.value,
|
|
200
|
+
onChange: (e) => B("value", e.target.value)
|
|
192
201
|
})]
|
|
193
202
|
}),
|
|
194
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ h("label", {
|
|
195
204
|
className: "space-y-1 text-sm",
|
|
196
|
-
children: [/* @__PURE__ */
|
|
205
|
+
children: [/* @__PURE__ */ m("span", {
|
|
197
206
|
className: "font-medium text-text-primary",
|
|
198
207
|
children: "Leads"
|
|
199
|
-
}), /* @__PURE__ */
|
|
208
|
+
}), /* @__PURE__ */ m(b, {
|
|
200
209
|
type: "number",
|
|
201
210
|
min: "0",
|
|
202
|
-
value:
|
|
203
|
-
onChange: (e) =>
|
|
211
|
+
value: R.leads,
|
|
212
|
+
onChange: (e) => B("leads", e.target.value)
|
|
204
213
|
})]
|
|
205
214
|
})
|
|
206
215
|
]
|
|
207
216
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
217
|
+
/* @__PURE__ */ h("label", {
|
|
209
218
|
className: "block space-y-1 text-sm",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
219
|
+
children: [/* @__PURE__ */ m("span", {
|
|
211
220
|
className: "font-medium text-text-primary",
|
|
212
221
|
children: "Website"
|
|
213
|
-
}), /* @__PURE__ */
|
|
214
|
-
value:
|
|
215
|
-
onChange: (e) =>
|
|
222
|
+
}), /* @__PURE__ */ m(b, {
|
|
223
|
+
value: R.website,
|
|
224
|
+
onChange: (e) => B("website", e.target.value)
|
|
216
225
|
})]
|
|
217
226
|
}),
|
|
218
|
-
/* @__PURE__ */
|
|
227
|
+
/* @__PURE__ */ h("div", {
|
|
219
228
|
className: "space-y-1 text-sm",
|
|
220
|
-
children: [/* @__PURE__ */
|
|
229
|
+
children: [/* @__PURE__ */ m("span", {
|
|
221
230
|
className: "font-medium text-text-primary",
|
|
222
231
|
children: "Logo"
|
|
223
|
-
}), /* @__PURE__ */
|
|
232
|
+
}), /* @__PURE__ */ m(l, {
|
|
224
233
|
label: "Upload logo",
|
|
225
234
|
folderPath: "/EventfullyManaged/Sponsors",
|
|
226
|
-
value:
|
|
227
|
-
onUploaded: (e) =>
|
|
235
|
+
value: R.logoUrl || null,
|
|
236
|
+
onUploaded: (e) => B("logoUrl", e),
|
|
228
237
|
hint: "Stored securely in Files. Shown across sponsor listings and detail pages."
|
|
229
238
|
})]
|
|
230
239
|
}),
|
|
231
|
-
/* @__PURE__ */
|
|
240
|
+
/* @__PURE__ */ h("div", {
|
|
232
241
|
className: "grid grid-cols-1 gap-4 md:grid-cols-3",
|
|
233
242
|
children: [
|
|
234
|
-
/* @__PURE__ */
|
|
243
|
+
/* @__PURE__ */ h("label", {
|
|
235
244
|
className: "space-y-1 text-sm",
|
|
236
|
-
children: [/* @__PURE__ */
|
|
245
|
+
children: [/* @__PURE__ */ m("span", {
|
|
237
246
|
className: "font-medium text-text-primary",
|
|
238
247
|
children: "Contact Name"
|
|
239
|
-
}), /* @__PURE__ */
|
|
240
|
-
value:
|
|
241
|
-
onChange: (e) =>
|
|
248
|
+
}), /* @__PURE__ */ m(b, {
|
|
249
|
+
value: R.contactName,
|
|
250
|
+
onChange: (e) => B("contactName", e.target.value)
|
|
242
251
|
})]
|
|
243
252
|
}),
|
|
244
|
-
/* @__PURE__ */
|
|
253
|
+
/* @__PURE__ */ h("label", {
|
|
245
254
|
className: "space-y-1 text-sm",
|
|
246
|
-
children: [/* @__PURE__ */
|
|
255
|
+
children: [/* @__PURE__ */ m("span", {
|
|
247
256
|
className: "font-medium text-text-primary",
|
|
248
257
|
children: "Contact Email"
|
|
249
|
-
}), /* @__PURE__ */
|
|
258
|
+
}), /* @__PURE__ */ m(b, {
|
|
250
259
|
type: "email",
|
|
251
|
-
value:
|
|
252
|
-
onChange: (e) =>
|
|
260
|
+
value: R.contactEmail,
|
|
261
|
+
onChange: (e) => B("contactEmail", e.target.value)
|
|
253
262
|
})]
|
|
254
263
|
}),
|
|
255
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ h("label", {
|
|
256
265
|
className: "space-y-1 text-sm",
|
|
257
|
-
children: [/* @__PURE__ */
|
|
266
|
+
children: [/* @__PURE__ */ m("span", {
|
|
258
267
|
className: "font-medium text-text-primary",
|
|
259
268
|
children: "Contact Phone"
|
|
260
|
-
}), /* @__PURE__ */
|
|
261
|
-
value:
|
|
262
|
-
onChange: (e) =>
|
|
269
|
+
}), /* @__PURE__ */ m(b, {
|
|
270
|
+
value: R.contactPhone,
|
|
271
|
+
onChange: (e) => B("contactPhone", e.target.value)
|
|
263
272
|
})]
|
|
264
273
|
})
|
|
265
274
|
]
|
|
266
275
|
}),
|
|
267
|
-
/* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ m("div", {
|
|
268
277
|
className: "flex justify-end",
|
|
269
|
-
children: /* @__PURE__ */
|
|
278
|
+
children: /* @__PURE__ */ h(v, {
|
|
270
279
|
type: "submit",
|
|
271
|
-
disabled:
|
|
272
|
-
children: [/* @__PURE__ */
|
|
280
|
+
disabled: H,
|
|
281
|
+
children: [/* @__PURE__ */ m(_, { className: "h-4 w-4" }), H ? "Saving..." : "Save Sponsor"]
|
|
273
282
|
})
|
|
274
283
|
})
|
|
275
284
|
]
|
|
@@ -278,6 +287,6 @@ function S() {
|
|
|
278
287
|
});
|
|
279
288
|
}
|
|
280
289
|
//#endregion
|
|
281
|
-
export {
|
|
290
|
+
export { O as default };
|
|
282
291
|
|
|
283
292
|
//# 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, 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 { ImageUploadField } from '../../components/ImageUploadField';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype SponsorFormState = {\n eventId: string;\n name: string;\n level: string;\n logoUrl: 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 logoUrl: '',\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 logoUrl: existingSponsor.logoUrl ?? '',\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 logoUrl: existingSponsor.logoUrl ?? '',\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 logoUrl: form.logoUrl,\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 try {\n if (isEdit) {\n const response = await updateSponsor({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateSponsor?.id, 'Could not update sponsor')) {\n return;\n }\n navigate('/sponsors');\n return;\n }\n\n const response = await createSponsor({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createSponsor?.id, 'Could not create sponsor')) {\n return;\n }\n navigate('/sponsors');\n } catch (error) {\n notify.error('Could not save sponsor', describeError(error));\n }\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 keep\n 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=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Logo</span>\n <ImageUploadField\n label=\"Upload logo\"\n folderPath=\"/EventfullyManaged/Sponsors\"\n value={form.logoUrl || null}\n onUploaded={(url) => onChange('logoUrl', url)}\n hint=\"Stored securely in Files. Shown across sponsor listings and detail pages.\"\n />\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\">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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"}
|
|
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 {\n Button,\n EmphasisPanel,\n Input,\n PagePurpose,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { useEffect, useMemo, useState } from 'react';\nimport { useParams } from 'react-router-dom';\n\nimport {\n useCreateSponsorMutation,\n useEventsQuery,\n useSponsorsQuery,\n useUpdateSponsorMutation,\n} from '../../api/eventApi';\nimport { ImageUploadField } from '../../components/ImageUploadField';\nimport { safeUrl } from '../../components/SafeLink';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype SponsorFormState = {\n eventId: string;\n name: string;\n level: string;\n logoUrl: 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 logoUrl: '',\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 logoUrl: existingSponsor.logoUrl ?? '',\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 logoUrl: existingSponsor.logoUrl ?? '',\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\n // Reject/normalise the free-text website before it is persisted so a hostile\n // value (e.g. javascript:) can never be stored and later rendered as a link.\n if (!form.eventId) {\n notify.error('Event required', 'Choose the event this sponsor belongs to.');\n return;\n }\n\n const normalizedWebsite = safeUrl(form.website);\n if (form.website.trim() && !normalizedWebsite) {\n notify.error('Invalid website', 'Enter a valid http(s) URL, or leave it blank.');\n return;\n }\n\n const input = {\n eventId: form.eventId,\n name: form.name,\n level: form.level,\n logoUrl: form.logoUrl,\n website: normalizedWebsite ?? '',\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 try {\n if (isEdit) {\n const response = await updateSponsor({ variables: { id, input } });\n if (!mutationSucceeded(response, response.data?.updateSponsor?.id, 'Could not update sponsor')) {\n return;\n }\n navigate('/sponsors');\n return;\n }\n\n const response = await createSponsor({ variables: { input } });\n if (!mutationSucceeded(response, response.data?.createSponsor?.id, 'Could not create sponsor')) {\n return;\n }\n navigate('/sponsors');\n } catch (error) {\n notify.error('Could not save sponsor', describeError(error));\n }\n };\n\n const saving = creating || updating;\n const events = eventsData?.events?.items ?? [];\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 keep\n 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 value={form.eventId} onValueChange={(value) => onChange('eventId', value)}>\n <SelectTrigger aria-label=\"Event\">\n <SelectValue placeholder=\"Select Event\" />\n </SelectTrigger>\n <SelectContent>\n {events.map((eventItem: { id: string; name: string }) => (\n <SelectItem key={eventItem.id} value={eventItem.id}>\n {eventItem.name}\n </SelectItem>\n ))}\n </SelectContent>\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} onValueChange={(value) => onChange('level', value)}>\n <SelectTrigger aria-label=\"Level\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"PLATINUM\">Platinum</SelectItem>\n <SelectItem value=\"GOLD\">Gold</SelectItem>\n <SelectItem value=\"SILVER\">Silver</SelectItem>\n <SelectItem value=\"BRONZE\">Bronze</SelectItem>\n <SelectItem value=\"COMMUNITY\">Community</SelectItem>\n </SelectContent>\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=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Logo</span>\n <ImageUploadField\n label=\"Upload logo\"\n folderPath=\"/EventfullyManaged/Sponsors\"\n value={form.logoUrl || null}\n onUploaded={(url) => onChange('logoUrl', url)}\n hint=\"Stored securely in Files. Shown across sponsor listings and detail pages.\"\n />\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\">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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"}
|