@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
|
@@ -1,150 +1,180 @@
|
|
|
1
1
|
import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { notify as t } from "../../lib/toast.js";
|
|
3
|
+
import { useDeleteSponsorMutation as n, useSponsorsQuery as r } from "../../api/eventApi.js";
|
|
4
|
+
import { ActionMenu as i } from "../../components/ActionMenu.js";
|
|
5
|
+
import { Pagination as a, usePagination as o } from "../../components/Pagination.js";
|
|
6
|
+
import { SafeLink as s } from "../../components/SafeLink.js";
|
|
7
|
+
import { useMemo as c, useState as l } from "react";
|
|
8
|
+
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
9
|
+
import { Building2 as p, Mail as m, Phone as h, Plus as g, Search as _ } from "lucide-react";
|
|
10
|
+
import { Badge as v, Button as y, GlassCard as b, IllustratedEmptyState as x, Input as S, PagePurpose as C } from "@burdenoff/fe-libs/ui";
|
|
7
11
|
//#region src/eventfullymanaged/pages/sponsors/SponsorsListPage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { navigate:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
function w() {
|
|
13
|
+
let { navigate: w } = e(), [T, E] = l(""), D = o({
|
|
14
|
+
pageSize: 12,
|
|
15
|
+
resetKey: T
|
|
16
|
+
}), { data: O, loading: k, refetch: A } = r({
|
|
17
|
+
search: T,
|
|
18
|
+
limit: D.limit,
|
|
19
|
+
offset: D.offset
|
|
20
|
+
}), [j] = n(), M = c(() => O?.sponsors?.items ?? [], [O]), N = O?.sponsors?.total ?? 0, P = M.reduce((e, t) => e + Number(t.metrics?.value ?? 0), 0), F = M.reduce((e, t) => e + Number(t.metrics?.leads ?? 0), 0), I = async (e) => {
|
|
21
|
+
let n = await j({ variables: { id: e.id } });
|
|
22
|
+
if (n.error) throw Error(n.error.message);
|
|
23
|
+
if (!n.data?.deleteSponsor) throw t.error("Could not delete sponsor", "The server did not confirm the deletion. Please try again."), Error("Deletion not confirmed");
|
|
24
|
+
await A(), t.success("Sponsor deleted");
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ f("div", {
|
|
15
27
|
className: "space-y-6 p-6",
|
|
16
28
|
children: [
|
|
17
|
-
/* @__PURE__ */
|
|
18
|
-
/* @__PURE__ */
|
|
29
|
+
/* @__PURE__ */ d(C, { 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." }),
|
|
30
|
+
/* @__PURE__ */ f("div", {
|
|
19
31
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
20
|
-
children: [/* @__PURE__ */
|
|
32
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
|
|
21
33
|
className: "text-2xl font-bold text-text-primary",
|
|
22
34
|
children: "Sponsors"
|
|
23
|
-
}), /* @__PURE__ */
|
|
35
|
+
}), /* @__PURE__ */ d("p", {
|
|
24
36
|
className: "mt-1 text-sm text-text-secondary",
|
|
25
37
|
children: "Manage event sponsors with live API data."
|
|
26
|
-
})] }), /* @__PURE__ */
|
|
38
|
+
})] }), /* @__PURE__ */ f(y, {
|
|
27
39
|
type: "button",
|
|
28
|
-
onClick: () =>
|
|
29
|
-
children: [/* @__PURE__ */
|
|
40
|
+
onClick: () => w("/sponsors/create"),
|
|
41
|
+
children: [/* @__PURE__ */ d(g, { className: "h-4 w-4" }), "Add Sponsor"]
|
|
30
42
|
})]
|
|
31
43
|
}),
|
|
32
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ f("div", {
|
|
33
45
|
className: "grid grid-cols-1 gap-4 md:grid-cols-3",
|
|
34
46
|
children: [
|
|
35
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ f(b, {
|
|
36
48
|
treatment: "glass",
|
|
37
49
|
glow: !0,
|
|
38
50
|
className: "p-4",
|
|
39
|
-
children: [/* @__PURE__ */
|
|
51
|
+
children: [/* @__PURE__ */ d("p", {
|
|
40
52
|
className: "text-sm text-text-secondary",
|
|
41
53
|
children: "Total Sponsors"
|
|
42
|
-
}), /* @__PURE__ */
|
|
54
|
+
}), /* @__PURE__ */ d("p", {
|
|
43
55
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
44
|
-
children:
|
|
56
|
+
children: N
|
|
45
57
|
})]
|
|
46
58
|
}),
|
|
47
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ f(b, {
|
|
48
60
|
treatment: "metric",
|
|
49
61
|
className: "p-4",
|
|
50
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ d("p", {
|
|
51
63
|
className: "text-sm text-text-secondary",
|
|
52
|
-
children: "
|
|
53
|
-
}), /* @__PURE__ */
|
|
64
|
+
children: "Value (this page)"
|
|
65
|
+
}), /* @__PURE__ */ f("p", {
|
|
54
66
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
55
|
-
children: ["$",
|
|
67
|
+
children: ["$", P.toLocaleString()]
|
|
56
68
|
})]
|
|
57
69
|
}),
|
|
58
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ f(b, {
|
|
59
71
|
treatment: "metric",
|
|
60
72
|
className: "p-4",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
73
|
+
children: [/* @__PURE__ */ d("p", {
|
|
62
74
|
className: "text-sm text-text-secondary",
|
|
63
|
-
children: "
|
|
64
|
-
}), /* @__PURE__ */
|
|
75
|
+
children: "Leads (this page)"
|
|
76
|
+
}), /* @__PURE__ */ d("p", {
|
|
65
77
|
className: "mt-1 text-2xl font-bold tabular-nums text-text-primary",
|
|
66
|
-
children:
|
|
78
|
+
children: F.toLocaleString()
|
|
67
79
|
})]
|
|
68
80
|
})
|
|
69
81
|
]
|
|
70
82
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
83
|
+
/* @__PURE__ */ f("div", {
|
|
72
84
|
className: "relative",
|
|
73
|
-
children: [/* @__PURE__ */
|
|
85
|
+
children: [/* @__PURE__ */ d(_, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-muted" }), /* @__PURE__ */ d(S, {
|
|
74
86
|
type: "text",
|
|
75
|
-
value:
|
|
76
|
-
onChange: (e) =>
|
|
87
|
+
value: T,
|
|
88
|
+
onChange: (e) => E(e.target.value),
|
|
77
89
|
placeholder: "Search sponsors",
|
|
78
90
|
"aria-label": "Search sponsors",
|
|
79
91
|
className: "pl-10"
|
|
80
92
|
})]
|
|
81
93
|
}),
|
|
82
|
-
|
|
94
|
+
k ? /* @__PURE__ */ d(b, {
|
|
83
95
|
treatment: "plain",
|
|
84
96
|
className: "border-border-seam p-8 text-center text-sm text-text-secondary",
|
|
85
97
|
children: "Loading sponsors..."
|
|
86
|
-
}) :
|
|
98
|
+
}) : M.length === 0 ? /* @__PURE__ */ d(b, {
|
|
87
99
|
treatment: "plain",
|
|
88
100
|
className: "border-border-seam",
|
|
89
|
-
children: /* @__PURE__ */
|
|
90
|
-
illustration:
|
|
91
|
-
title:
|
|
92
|
-
description:
|
|
93
|
-
action:
|
|
101
|
+
children: /* @__PURE__ */ d(x, {
|
|
102
|
+
illustration: T ? "empty-search" : "empty-people",
|
|
103
|
+
title: T ? "No sponsors match your search." : "No sponsors yet.",
|
|
104
|
+
description: T ? "Try a different name." : "Add your first sponsor to start tracking value and leads.",
|
|
105
|
+
action: T ? void 0 : /* @__PURE__ */ f(y, {
|
|
94
106
|
type: "button",
|
|
95
|
-
onClick: () =>
|
|
96
|
-
children: [/* @__PURE__ */
|
|
107
|
+
onClick: () => w("/sponsors/create"),
|
|
108
|
+
children: [/* @__PURE__ */ d(g, { className: "h-4 w-4" }), "Add Sponsor"]
|
|
97
109
|
})
|
|
98
110
|
})
|
|
99
|
-
}) : /* @__PURE__ */
|
|
111
|
+
}) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", {
|
|
100
112
|
className: "space-y-4",
|
|
101
|
-
children:
|
|
113
|
+
children: M.map((e) => /* @__PURE__ */ f(b, {
|
|
102
114
|
treatment: "plain",
|
|
103
115
|
className: "border-border-seam p-5",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ f("div", {
|
|
105
117
|
className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
118
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("button", {
|
|
107
119
|
type: "button",
|
|
108
|
-
onClick: () =>
|
|
120
|
+
onClick: () => w(`/sponsors/${e.id}`),
|
|
109
121
|
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)]",
|
|
110
122
|
children: e.name
|
|
111
|
-
}), /* @__PURE__ */
|
|
123
|
+
}), /* @__PURE__ */ f("div", {
|
|
112
124
|
className: "mt-1 flex items-center gap-2 text-sm text-text-secondary",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
125
|
+
children: [/* @__PURE__ */ d(p, { className: "h-4 w-4" }), /* @__PURE__ */ d(v, {
|
|
114
126
|
variant: "secondary",
|
|
115
127
|
className: "uppercase",
|
|
116
128
|
children: e.level
|
|
117
129
|
})]
|
|
118
|
-
})] }), /* @__PURE__ */
|
|
119
|
-
className: "
|
|
120
|
-
children: [/* @__PURE__ */
|
|
130
|
+
})] }), /* @__PURE__ */ f("div", {
|
|
131
|
+
className: "flex items-start gap-3",
|
|
132
|
+
children: [/* @__PURE__ */ f("div", {
|
|
133
|
+
className: "text-sm tabular-nums text-text-secondary",
|
|
134
|
+
children: [/* @__PURE__ */ f("p", { children: ["Value: $", Number(e.metrics?.value ?? 0).toLocaleString()] }), /* @__PURE__ */ f("p", { children: ["Leads: ", Number(e.metrics?.leads ?? 0).toLocaleString()] })]
|
|
135
|
+
}), /* @__PURE__ */ d(i, {
|
|
136
|
+
ariaLabel: `Actions for ${e.name}`,
|
|
137
|
+
entityName: e.name,
|
|
138
|
+
onView: () => w(`/sponsors/${e.id}`),
|
|
139
|
+
onEdit: () => w(`/sponsors/${e.id}/edit`),
|
|
140
|
+
onDelete: () => I(e),
|
|
141
|
+
deleteLabel: "Delete sponsor"
|
|
142
|
+
})]
|
|
121
143
|
})]
|
|
122
|
-
}), /* @__PURE__ */
|
|
144
|
+
}), /* @__PURE__ */ f("div", {
|
|
123
145
|
className: "mt-4 grid grid-cols-1 gap-2 text-sm text-text-secondary sm:grid-cols-3",
|
|
124
146
|
children: [
|
|
125
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ f("div", {
|
|
126
148
|
className: "flex items-center gap-2",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
149
|
+
children: [/* @__PURE__ */ d(m, { className: "h-4 w-4" }), /* @__PURE__ */ d("span", { children: e.contactEmail ?? "No email" })]
|
|
128
150
|
}),
|
|
129
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ f("div", {
|
|
130
152
|
className: "flex items-center gap-2",
|
|
131
|
-
children: [/* @__PURE__ */
|
|
153
|
+
children: [/* @__PURE__ */ d(h, { className: "h-4 w-4" }), /* @__PURE__ */ d("span", { children: e.contactPhone ?? "No phone" })]
|
|
132
154
|
}),
|
|
133
|
-
/* @__PURE__ */
|
|
155
|
+
/* @__PURE__ */ d("div", { children: e.website ? /* @__PURE__ */ d(s, {
|
|
134
156
|
href: e.website,
|
|
135
|
-
target: "_blank",
|
|
136
|
-
rel: "noreferrer",
|
|
137
157
|
className: "text-text-link hover:underline",
|
|
158
|
+
fallbackClassName: "text-text-secondary",
|
|
138
159
|
children: e.website
|
|
139
160
|
}) : "No website" })
|
|
140
161
|
]
|
|
141
162
|
})]
|
|
142
163
|
}, e.id))
|
|
143
|
-
})
|
|
164
|
+
}), /* @__PURE__ */ d(a, {
|
|
165
|
+
offset: D.offset,
|
|
166
|
+
limit: D.limit,
|
|
167
|
+
loadedCount: M.length,
|
|
168
|
+
total: N,
|
|
169
|
+
onPrev: D.prevPage,
|
|
170
|
+
onNext: D.nextPage,
|
|
171
|
+
itemLabel: "sponsors",
|
|
172
|
+
loading: k
|
|
173
|
+
})] })
|
|
144
174
|
]
|
|
145
175
|
});
|
|
146
176
|
}
|
|
147
177
|
//#endregion
|
|
148
|
-
export {
|
|
178
|
+
export { w as default };
|
|
149
179
|
|
|
150
180
|
//# 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, 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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"}
|
|
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 { useDeleteSponsorMutation, useSponsorsQuery } from '../../api/eventApi';\nimport { ActionMenu } from '../../components/ActionMenu';\nimport { Pagination, usePagination } from '../../components/Pagination';\nimport { SafeLink } from '../../components/SafeLink';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { notify } from '../../lib/toast';\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 pagination = usePagination({ pageSize: 12, resetKey: search });\n const { data, loading, refetch } = useSponsorsQuery({\n search,\n limit: pagination.limit,\n offset: pagination.offset,\n });\n const [deleteSponsor] = useDeleteSponsorMutation();\n\n const sponsors = useMemo(() => (data?.sponsors?.items ?? []) as SponsorItem[], [data]);\n const total = data?.sponsors?.total ?? 0;\n\n const pageValue = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.value ?? 0), 0);\n const pageLeads = sponsors.reduce((sum, sponsor) => sum + Number(sponsor.metrics?.leads ?? 0), 0);\n\n const handleDelete = async (sponsor: SponsorItem) => {\n const response = await deleteSponsor({ variables: { id: sponsor.id } });\n if (response.error) {\n // useDeleteSponsorMutation.onError already surfaces the toast.\n throw new Error(response.error.message);\n }\n if (!response.data?.deleteSponsor) {\n notify.error('Could not delete sponsor', 'The server did not confirm the deletion. Please try again.');\n throw new Error('Deletion not confirmed');\n }\n await refetch();\n notify.success('Sponsor deleted');\n };\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\">{total}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Value (this page)</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">${pageValue.toLocaleString()}</p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">Leads (this page)</p>\n <p className=\"mt-1 text-2xl font-bold tabular-nums text-text-primary\">{pageLeads.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 <>\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}`)}\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=\"flex items-start gap-3\">\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 <ActionMenu\n ariaLabel={`Actions for ${sponsor.name}`}\n entityName={sponsor.name}\n onView={() => navigate(`/sponsors/${sponsor.id}`)}\n onEdit={() => navigate(`/sponsors/${sponsor.id}/edit`)}\n onDelete={() => handleDelete(sponsor)}\n deleteLabel=\"Delete sponsor\"\n />\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 <SafeLink\n href={sponsor.website}\n className=\"text-text-link hover:underline\"\n fallbackClassName=\"text-text-secondary\"\n >\n {sponsor.website}\n </SafeLink>\n ) : (\n 'No website'\n )}\n </div>\n </div>\n </GlassCard>\n ))}\n </div>\n\n <Pagination\n offset={pagination.offset}\n limit={pagination.limit}\n loadedCount={sponsors.length}\n total={total}\n onPrev={pagination.prevPage}\n onNext={pagination.nextPage}\n itemLabel=\"sponsors\"\n loading={loading}\n />\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;AAuBA,SAAwB,IAAmB;CACzC,IAAM,EAAE,gBAAa,GAAsB,EACrC,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,IAAa,EAAc;EAAE,UAAU;EAAI,UAAU;EAAQ,CAAC,EAC9D,EAAE,SAAM,YAAS,eAAY,EAAiB;EAClD;EACA,OAAO,EAAW;EAClB,QAAQ,EAAW;EACpB,CAAC,EACI,CAAC,KAAiB,GAA0B,EAE5C,IAAW,QAAe,GAAM,UAAU,SAAS,EAAE,EAAoB,CAAC,EAAK,CAAC,EAChF,IAAQ,GAAM,UAAU,SAAS,GAEjC,IAAY,EAAS,QAAQ,GAAK,MAAY,IAAM,OAAO,EAAQ,SAAS,SAAS,EAAE,EAAE,EAAE,EAC3F,IAAY,EAAS,QAAQ,GAAK,MAAY,IAAM,OAAO,EAAQ,SAAS,SAAS,EAAE,EAAE,EAAE,EAE3F,IAAe,OAAO,MAAyB;EACnD,IAAM,IAAW,MAAM,EAAc,EAAE,WAAW,EAAE,IAAI,EAAQ,IAAI,EAAE,CAAC;AACvE,MAAI,EAAS,MAEX,OAAU,MAAM,EAAS,MAAM,QAAQ;AAEzC,MAAI,CAAC,EAAS,MAAM,cAElB,OADA,EAAO,MAAM,4BAA4B,6DAA6D,EAC5F,MAAM,yBAAyB;AAG3C,EADA,MAAM,GAAS,EACf,EAAO,QAAQ,kBAAkB;;AAGnC,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAA,UAAa,wSAIC,CAAA;GAEd,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAAuC;KAAa,CAAA,EAClE,kBAAC,KAAD;KAAG,WAAU;eAAmC;KAA6C,CAAA,CACzF,EAAA,CAAA,EACN,kBAAC,GAAD;KAAQ,MAAK;KAAS,eAAe,EAAS,mBAAmB;eAAjE,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,cAErB;OACL;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAW,WAAU;MAAQ,MAAA;MAAK,WAAU;gBAA5C,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAkB,CAAA,EAC7D,kBAAC,KAAD;OAAG,WAAU;iBAA0D;OAAU,CAAA,CACvE;;KACZ,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBAAxC,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAqB,CAAA,EAChE,kBAAC,KAAD;OAAG,WAAU;iBAAb,CAAsE,KAAE,EAAU,gBAAgB,CAAK;SAC7F;;KACZ,kBAAC,GAAD;MAAW,WAAU;MAAS,WAAU;gBAAxC,CACE,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAAqB,CAAA,EAChE,kBAAC,KAAD;OAAG,WAAU;iBAA0D,EAAU,gBAAgB;OAAK,CAAA,CAC5F;;KACR;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,wFAAyF,CAAA,EAC3G,kBAAC,GAAD;KACE,MAAK;KACL,OAAO;KACP,WAAW,MAAU,EAAU,EAAM,OAAO,MAAM;KAClD,aAAY;KACZ,cAAW;KACX,WAAU;KACV,CAAA,CACE;;GAEL,IACC,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cAAiE;IAE5F,CAAA,GACV,EAAS,WAAW,IACtB,kBAAC,GAAD;IAAW,WAAU;IAAQ,WAAU;cACrC,kBAAC,GAAD;KACE,cAAc,IAAS,iBAAiB;KACxC,OAAO,IAAS,mCAAmC;KACnD,aAAa,IAAS,0BAA0B;KAChD,QACG,IAKG,KAAA,IAJF,kBAAC,GAAD;MAAQ,MAAK;MAAS,eAAe,EAAS,mBAAmB;gBAAjE,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,cAErB;;KAGb,CAAA;IACQ,CAAA,GAEZ,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAS,KAAK,MACb,kBAAC,GAAD;KAA4B,WAAU;KAAQ,WAAU;eAAxD,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,aAAa,EAAQ,KAAK;OAClD,WAAU;iBAET,EAAQ;OACF,CAAA,EACT,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EACjC,kBAAC,GAAD;QAAO,SAAQ;QAAY,WAAU;kBAClC,EAAQ;QACH,CAAA,CACJ;SACF,EAAA,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD,EAAA,UAAA,CAAG,YAAS,OAAO,EAAQ,SAAS,SAAS,EAAE,CAAC,gBAAgB,CAAK,EAAA,CAAA,EACrE,kBAAC,KAAD,EAAA,UAAA,CAAG,WAAQ,OAAO,EAAQ,SAAS,SAAS,EAAE,CAAC,gBAAgB,CAAK,EAAA,CAAA,CAChE;WACN,kBAAC,GAAD;QACE,WAAW,eAAe,EAAQ;QAClC,YAAY,EAAQ;QACpB,cAAc,EAAS,aAAa,EAAQ,KAAK;QACjD,cAAc,EAAS,aAAa,EAAQ,GAAG,OAAO;QACtD,gBAAgB,EAAa,EAAQ;QACrC,aAAY;QACZ,CAAA,CACE;SACF;SAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC5B,kBAAC,QAAD,EAAA,UAAO,EAAQ,gBAAgB,YAAkB,CAAA,CAC7C;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAC7B,kBAAC,QAAD,EAAA,UAAO,EAAQ,gBAAgB,YAAkB,CAAA,CAC7C;;OACN,kBAAC,OAAD,EAAA,UACG,EAAQ,UACP,kBAAC,GAAD;QACE,MAAM,EAAQ;QACd,WAAU;QACV,mBAAkB;kBAEjB,EAAQ;QACA,CAAA,GAEX,cAEE,CAAA;OACF;QACI;OAxDI,EAAQ,GAwDZ,CACZ;IACE,CAAA,EAEN,kBAAC,GAAD;IACE,QAAQ,EAAW;IACnB,OAAO,EAAW;IAClB,aAAa,EAAS;IACf;IACP,QAAQ,EAAW;IACnB,QAAQ,EAAW;IACnB,WAAU;IACD;IACT,CAAA,CACD,EAAA,CAAA;GAED"}
|
|
@@ -1,141 +1,162 @@
|
|
|
1
1
|
import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
|
|
2
2
|
import { useVenueQuery as t } from "../../api/eventApi.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { EntityTagsField as n } from "../../components/EntityTagsField.js";
|
|
4
|
+
import { useParams as r } from "react-router-dom";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
import { ArrowLeft as o, Building2 as s, Edit as c, MapPin as l, Megaphone as u, SquareStack as d, Users as f } from "lucide-react";
|
|
7
|
+
import { Badge as p, Button as m, GlassCard as h, IllustratedEmptyState as g, NextSteps as _, PagePurpose as v } from "@burdenoff/fe-libs/ui";
|
|
7
8
|
//#region src/eventfullymanaged/pages/venues/VenueDetailPage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { id:
|
|
10
|
-
return
|
|
9
|
+
function y() {
|
|
10
|
+
let { id: y = "" } = r(), { navigate: b } = e(), { data: x, loading: S } = t(y), C = x?.venue ?? null, w = x?.floorPlans?.items ?? [];
|
|
11
|
+
return S ? /* @__PURE__ */ i("div", {
|
|
11
12
|
className: "p-6 text-sm text-text-secondary",
|
|
12
13
|
children: "Loading venue..."
|
|
13
|
-
}) :
|
|
14
|
+
}) : C ? /* @__PURE__ */ a("div", {
|
|
14
15
|
className: "space-y-6 p-6",
|
|
15
16
|
children: [
|
|
16
|
-
/* @__PURE__ */
|
|
17
|
-
/* @__PURE__ */
|
|
17
|
+
/* @__PURE__ */ i(v, { children: "The full record for one venue. Review its location, capacity and status, see what amenities it offers, and manage the floor plans attendees will navigate. Come here to confirm a space is ready before you assign an event to it." }),
|
|
18
|
+
/* @__PURE__ */ a("div", {
|
|
18
19
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
19
|
-
children: [/* @__PURE__ */
|
|
20
|
+
children: [/* @__PURE__ */ a("div", {
|
|
20
21
|
className: "space-y-3",
|
|
21
|
-
children: [/* @__PURE__ */
|
|
22
|
+
children: [/* @__PURE__ */ a(m, {
|
|
22
23
|
type: "button",
|
|
23
24
|
variant: "ghost",
|
|
24
25
|
size: "sm",
|
|
25
|
-
onClick: () =>
|
|
26
|
-
children: [/* @__PURE__ */
|
|
27
|
-
}), /* @__PURE__ */
|
|
26
|
+
onClick: () => b("/venues"),
|
|
27
|
+
children: [/* @__PURE__ */ i(o, { className: "h-4 w-4" }), "Back to Venues"]
|
|
28
|
+
}), /* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("h1", {
|
|
28
29
|
className: "text-2xl font-bold text-text-primary",
|
|
29
|
-
children:
|
|
30
|
-
}), /* @__PURE__ */
|
|
30
|
+
children: C.name
|
|
31
|
+
}), /* @__PURE__ */ i("p", {
|
|
31
32
|
className: "mt-1 text-sm text-text-secondary",
|
|
32
|
-
children:
|
|
33
|
+
children: C.description ?? "No description provided."
|
|
33
34
|
})] })]
|
|
34
|
-
}), /* @__PURE__ */
|
|
35
|
+
}), /* @__PURE__ */ a(m, {
|
|
35
36
|
type: "button",
|
|
36
|
-
onClick: () =>
|
|
37
|
-
children: [/* @__PURE__ */
|
|
37
|
+
onClick: () => b(`/venues/${C.id}/edit`),
|
|
38
|
+
children: [/* @__PURE__ */ i(c, { className: "h-4 w-4" }), "Edit Venue"]
|
|
38
39
|
})]
|
|
39
40
|
}),
|
|
40
|
-
/* @__PURE__ */
|
|
41
|
+
/* @__PURE__ */ a("div", {
|
|
41
42
|
className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
|
|
42
43
|
children: [
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
+
/* @__PURE__ */ a(h, {
|
|
44
45
|
treatment: "metric",
|
|
45
46
|
className: "p-4",
|
|
46
|
-
children: [/* @__PURE__ */
|
|
47
|
+
children: [/* @__PURE__ */ a("div", {
|
|
47
48
|
className: "mb-2 flex items-center gap-2 text-sm font-medium text-text-primary",
|
|
48
|
-
children: [/* @__PURE__ */
|
|
49
|
-
}), /* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ i(l, { className: "h-4 w-4 text-action-primary-bg" }), "Location"]
|
|
50
|
+
}), /* @__PURE__ */ i("p", {
|
|
50
51
|
className: "text-sm text-text-secondary",
|
|
51
52
|
children: [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
C.addressLine1,
|
|
54
|
+
C.city,
|
|
55
|
+
C.state,
|
|
56
|
+
C.country,
|
|
57
|
+
C.postalCode
|
|
57
58
|
].filter(Boolean).join(", ") || "Location not configured"
|
|
58
59
|
})]
|
|
59
60
|
}),
|
|
60
|
-
/* @__PURE__ */
|
|
61
|
+
/* @__PURE__ */ a(h, {
|
|
61
62
|
treatment: "glass",
|
|
62
63
|
glow: !0,
|
|
63
64
|
className: "p-4",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ a("div", {
|
|
65
66
|
className: "mb-2 flex items-center gap-2 text-sm font-medium text-text-primary",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
67
|
-
}), /* @__PURE__ */
|
|
67
|
+
children: [/* @__PURE__ */ i(f, { className: "h-4 w-4 text-action-primary-bg" }), "Capacity"]
|
|
68
|
+
}), /* @__PURE__ */ a("p", {
|
|
68
69
|
className: "text-sm tabular-nums text-text-secondary",
|
|
69
|
-
children: [
|
|
70
|
+
children: [C.capacity ?? 0, " attendees"]
|
|
70
71
|
})]
|
|
71
72
|
}),
|
|
72
|
-
/* @__PURE__ */
|
|
73
|
+
/* @__PURE__ */ a(h, {
|
|
73
74
|
treatment: "metric",
|
|
74
75
|
className: "p-4",
|
|
75
|
-
children: [/* @__PURE__ */
|
|
76
|
+
children: [/* @__PURE__ */ a("div", {
|
|
76
77
|
className: "mb-2 flex items-center gap-2 text-sm font-medium text-text-primary",
|
|
77
|
-
children: [/* @__PURE__ */
|
|
78
|
-
}), /* @__PURE__ */
|
|
78
|
+
children: [/* @__PURE__ */ i(s, { className: "h-4 w-4 text-action-primary-bg" }), "Status"]
|
|
79
|
+
}), /* @__PURE__ */ i("p", {
|
|
79
80
|
className: "text-sm uppercase text-text-secondary",
|
|
80
|
-
children:
|
|
81
|
+
children: C.status
|
|
81
82
|
})]
|
|
82
83
|
})
|
|
83
84
|
]
|
|
84
85
|
}),
|
|
85
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ a(h, {
|
|
86
87
|
treatment: "plain",
|
|
87
88
|
className: "border-border-seam p-5",
|
|
88
|
-
children: [/* @__PURE__ */
|
|
89
|
+
children: [/* @__PURE__ */ i("h2", {
|
|
89
90
|
className: "text-lg font-semibold text-text-primary",
|
|
90
91
|
children: "Amenities"
|
|
91
|
-
}), /* @__PURE__ */
|
|
92
|
+
}), /* @__PURE__ */ i("div", {
|
|
92
93
|
className: "mt-3 flex flex-wrap gap-2",
|
|
93
|
-
children:
|
|
94
|
+
children: C.amenities.length > 0 ? C.amenities.map((e) => /* @__PURE__ */ i(p, {
|
|
94
95
|
variant: "secondary",
|
|
95
96
|
children: e
|
|
96
|
-
}, e)) : /* @__PURE__ */
|
|
97
|
+
}, e)) : /* @__PURE__ */ i("p", {
|
|
97
98
|
className: "text-sm text-text-secondary",
|
|
98
99
|
children: "No amenities configured."
|
|
99
100
|
})
|
|
100
101
|
})]
|
|
101
102
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ a(h, {
|
|
104
|
+
treatment: "plain",
|
|
105
|
+
className: "border-border-seam p-5",
|
|
106
|
+
children: [
|
|
107
|
+
/* @__PURE__ */ i("h2", {
|
|
108
|
+
className: "text-lg font-semibold text-text-primary",
|
|
109
|
+
children: "Tags"
|
|
110
|
+
}),
|
|
111
|
+
/* @__PURE__ */ i("p", {
|
|
112
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
113
|
+
children: "Label this venue so you can group and filter it — for example by region, tier or amenity profile."
|
|
114
|
+
}),
|
|
115
|
+
/* @__PURE__ */ i(n, {
|
|
116
|
+
entityType: "venue",
|
|
117
|
+
entityId: C.id,
|
|
118
|
+
label: "Venue tags",
|
|
119
|
+
className: "mt-3"
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
}),
|
|
123
|
+
/* @__PURE__ */ a(h, {
|
|
103
124
|
treatment: "plain",
|
|
104
125
|
className: "border-border-seam p-5",
|
|
105
|
-
children: [/* @__PURE__ */
|
|
126
|
+
children: [/* @__PURE__ */ a("div", {
|
|
106
127
|
className: "flex items-center justify-between gap-3",
|
|
107
|
-
children: [/* @__PURE__ */
|
|
128
|
+
children: [/* @__PURE__ */ i("h2", {
|
|
108
129
|
className: "text-lg font-semibold text-text-primary",
|
|
109
130
|
children: "Floor Plans"
|
|
110
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), /* @__PURE__ */ a(m, {
|
|
111
132
|
type: "button",
|
|
112
133
|
variant: "outline",
|
|
113
134
|
size: "sm",
|
|
114
|
-
onClick: () =>
|
|
115
|
-
children: [/* @__PURE__ */
|
|
135
|
+
onClick: () => b(`/venues/${C.id}/floor-plans`),
|
|
136
|
+
children: [/* @__PURE__ */ i(d, { className: "h-4 w-4" }), "Manage Floor Plans"]
|
|
116
137
|
})]
|
|
117
|
-
}), /* @__PURE__ */
|
|
138
|
+
}), /* @__PURE__ */ i("div", {
|
|
118
139
|
className: "mt-4",
|
|
119
|
-
children:
|
|
140
|
+
children: w.length > 0 ? /* @__PURE__ */ i("ul", {
|
|
120
141
|
className: "space-y-2.5",
|
|
121
|
-
children:
|
|
142
|
+
children: w.map((e) => /* @__PURE__ */ a("li", {
|
|
122
143
|
className: "rounded-card border border-border-seam p-3 transition-[box-shadow,border-color] duration-200 hover:border-border-strong hover:shadow-elevation-1",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ i("p", {
|
|
124
145
|
className: "font-medium text-text-primary",
|
|
125
146
|
children: e.name
|
|
126
|
-
}), /* @__PURE__ */
|
|
147
|
+
}), /* @__PURE__ */ i("p", {
|
|
127
148
|
className: "text-sm text-text-secondary",
|
|
128
149
|
children: e.imageUrl ? "Image configured" : "No image configured"
|
|
129
150
|
})]
|
|
130
151
|
}, e.id))
|
|
131
|
-
}) : /* @__PURE__ */
|
|
152
|
+
}) : /* @__PURE__ */ i(g, {
|
|
132
153
|
illustration: "empty-files",
|
|
133
154
|
title: "No floor plans have been added yet.",
|
|
134
155
|
className: "py-8"
|
|
135
156
|
})
|
|
136
157
|
})]
|
|
137
158
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ i(_, {
|
|
139
160
|
storageKey: "eventfullymanaged-venue-detail",
|
|
140
161
|
title: "Get this venue ready to host",
|
|
141
162
|
steps: [
|
|
@@ -143,38 +164,38 @@ function v() {
|
|
|
143
164
|
id: "edit-venue",
|
|
144
165
|
label: "Edit venue details",
|
|
145
166
|
description: "Update capacity, address, status and amenities.",
|
|
146
|
-
icon: /* @__PURE__ */
|
|
147
|
-
onClick: () =>
|
|
167
|
+
icon: /* @__PURE__ */ i(c, { className: "h-4 w-4" }),
|
|
168
|
+
onClick: () => b(`/venues/${C.id}/edit`)
|
|
148
169
|
},
|
|
149
170
|
{
|
|
150
171
|
id: "floor-plans",
|
|
151
172
|
label: "Add floor plans",
|
|
152
173
|
description: "Map the layout so attendees and staff can navigate.",
|
|
153
|
-
icon: /* @__PURE__ */
|
|
154
|
-
onClick: () =>
|
|
174
|
+
icon: /* @__PURE__ */ i(d, { className: "h-4 w-4" }),
|
|
175
|
+
onClick: () => b(`/venues/${C.id}/floor-plans`)
|
|
155
176
|
},
|
|
156
177
|
{
|
|
157
178
|
id: "resources",
|
|
158
179
|
label: "Review resource readiness",
|
|
159
180
|
description: "Check capacity, amenities and plans at a glance.",
|
|
160
|
-
icon: /* @__PURE__ */
|
|
161
|
-
onClick: () =>
|
|
181
|
+
icon: /* @__PURE__ */ i(u, { className: "h-4 w-4" }),
|
|
182
|
+
onClick: () => b(`/venues/${C.id}/resources`)
|
|
162
183
|
}
|
|
163
184
|
]
|
|
164
185
|
})
|
|
165
186
|
]
|
|
166
|
-
}) : /* @__PURE__ */
|
|
187
|
+
}) : /* @__PURE__ */ a("div", {
|
|
167
188
|
className: "space-y-4 p-6",
|
|
168
|
-
children: [/* @__PURE__ */
|
|
189
|
+
children: [/* @__PURE__ */ a(m, {
|
|
169
190
|
type: "button",
|
|
170
191
|
variant: "ghost",
|
|
171
192
|
size: "sm",
|
|
172
|
-
onClick: () =>
|
|
173
|
-
children: [/* @__PURE__ */
|
|
174
|
-
}), /* @__PURE__ */
|
|
193
|
+
onClick: () => b("/venues"),
|
|
194
|
+
children: [/* @__PURE__ */ i(o, { className: "h-4 w-4" }), "Back to Venues"]
|
|
195
|
+
}), /* @__PURE__ */ i(h, {
|
|
175
196
|
treatment: "plain",
|
|
176
197
|
className: "border-border-seam",
|
|
177
|
-
children: /* @__PURE__ */
|
|
198
|
+
children: /* @__PURE__ */ i(g, {
|
|
178
199
|
illustration: "empty-search",
|
|
179
200
|
title: "Venue not found.",
|
|
180
201
|
description: "This venue may have been removed or is outside your current scope."
|
|
@@ -183,6 +204,6 @@ function v() {
|
|
|
183
204
|
});
|
|
184
205
|
}
|
|
185
206
|
//#endregion
|
|
186
|
-
export {
|
|
207
|
+
export { y as default };
|
|
187
208
|
|
|
188
209
|
//# sourceMappingURL=VenueDetailPage.js.map
|