@burdenoff/microfe-eventfullymanaged 2026.825.1 → 2026.828.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/hooks/index.d.ts +1 -0
- package/dist/eventfullymanaged/hooks/index.d.ts.map +1 -1
- package/dist/eventfullymanaged/hooks/index.js +3 -0
- package/dist/eventfullymanaged/hooks/useEventDelete.d.ts +19 -0
- package/dist/eventfullymanaged/hooks/useEventDelete.d.ts.map +1 -0
- package/dist/eventfullymanaged/hooks/useEventDelete.js +16 -0
- package/dist/eventfullymanaged/hooks/useEventDelete.js.map +1 -0
- package/dist/eventfullymanaged/lib/format.d.ts +9 -0
- package/dist/eventfullymanaged/lib/format.d.ts.map +1 -1
- package/dist/eventfullymanaged/lib/format.js +11 -3
- package/dist/eventfullymanaged/lib/format.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/EventDetailPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js +315 -277
- package/dist/eventfullymanaged/pages/events/EventDetailPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/events/SessionFormPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js +91 -81
- package/dist/eventfullymanaged/pages/events/SessionFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/EventsPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/modules/EventsPage.js +231 -229
- package/dist/eventfullymanaged/pages/modules/EventsPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js +120 -102
- package/dist/eventfullymanaged/pages/modules/NetworkingPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js +128 -120
- package/dist/eventfullymanaged/pages/modules/RegistrationPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.d.ts.map +1 -1
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js +68 -75
- package/dist/eventfullymanaged/pages/registration/PromoCodeFormPage.js.map +1 -1
- package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js +41 -41
- package/dist/eventfullymanaged/pages/registration/RegisterAttendeePage.js.map +1 -1
- package/dist/eventfullymanaged/store/eventfullyManagedStore.js +15 -0
- package/dist/eventfullymanaged/store/eventfullyManagedStore.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEventfullyManaged as e } from "../../context/EventfullyManagedContext.js";
|
|
2
2
|
import { notify as t } from "../../lib/toast.js";
|
|
3
3
|
import { useAttendeesQuery as n, useCreateAttendeeMutation as r, useCreateRegistrationMutation as i, useEventsQuery as a, usePromoCodesQuery as o, useTicketTypesQuery as ee } from "../../api/eventApi.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { computeDiscount as te, describeDiscount as ne, formatMoney as s } from "../../lib/format.js";
|
|
5
|
+
import { describeError as re, mutationSucceeded as ie } from "../../lib/mutationResult.js";
|
|
6
6
|
import { useMemo as c, useState as l } from "react";
|
|
7
7
|
import { Fragment as ae, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
8
|
import { ArrowLeft as f, ArrowRight as oe, BadgePercent as se, CalendarDays as ce, Check as le, CheckCircle2 as ue, Minus as de, Plus as fe, Ticket as p, UserRound as pe } from "lucide-react";
|
|
@@ -31,7 +31,7 @@ var _ = [
|
|
|
31
31
|
}
|
|
32
32
|
];
|
|
33
33
|
function v() {
|
|
34
|
-
let { navigate: v } = e(), [y, b] = l(0), [x,
|
|
34
|
+
let { navigate: v } = e(), [y, b] = l(0), [x, Se] = l(""), [S, C] = l(""), [w, T] = l("new"), [E, D] = l(""), [O, Ce] = l(""), [k, we] = l(""), [Te, Ee] = l(""), [A, j] = l(""), [De, M] = l(1), [N, P] = l(""), [F, I] = l(null), [Oe, L] = l(""), [R, ke] = l(""), [z, Ae] = l(null), { data: je, loading: Me } = a({
|
|
35
35
|
limit: 100,
|
|
36
36
|
offset: 0
|
|
37
37
|
}), { data: Ne, loading: Pe } = ee({
|
|
@@ -46,13 +46,13 @@ function v() {
|
|
|
46
46
|
eventId: x || void 0,
|
|
47
47
|
limit: 100,
|
|
48
48
|
offset: 0
|
|
49
|
-
}), B = c(() => je?.events.items ?? [], [je]), V = c(() => (Ne?.ticketTypes.items ?? []).filter((e) => (!x || e.eventId === x) && e.isActive), [Ne, x]), H = c(() => (Fe?.attendees.items ?? []).filter((e) => !x || e.eventId === x), [Fe, x]), U = c(() => (Ie?.promoCodes.items ?? []).filter((e) => e.isActive && (!x || e.eventId === x)), [Ie, x]), [Le, { loading: Re }] = r(), [ze, { loading: Be }] = i(), W = Re || Be, G = c(() => B.find((e) => e.id === x), [B, x]), K = c(() => V.find((e) => e.id ===
|
|
50
|
-
|
|
49
|
+
}), B = c(() => je?.events.items ?? [], [je]), V = c(() => (Ne?.ticketTypes.items ?? []).filter((e) => (!x || e.eventId === x) && e.isActive), [Ne, x]), H = c(() => (Fe?.attendees.items ?? []).filter((e) => !x || e.eventId === x), [Fe, x]), U = c(() => (Ie?.promoCodes.items ?? []).filter((e) => e.isActive && (!x || e.eventId === x)), [Ie, x]), [Le, { loading: Re }] = r(), [ze, { loading: Be }] = i(), W = Re || Be, G = c(() => B.find((e) => e.id === x), [B, x]), K = c(() => V.find((e) => e.id === S), [V, S]), q = c(() => H.find((e) => e.id === E), [H, E]), J = Math.max(1, De), Ve = K ? Number(K.price) : 0, Y = K?.currency ?? "USD", X = Number.isFinite(Ve) ? Ve * J : 0, Z = F ? te(X, F.discountType, Number(F.discountValue)) : 0, He = Math.max(X - Z, 0), Q = X > 0, Ue = w === "existing" ? q?.fullName ?? "" : O.trim(), We = (e) => {
|
|
50
|
+
Se(e), C(""), T("new"), D(""), I(null), P(""), L("");
|
|
51
51
|
}, Ge = (e) => {
|
|
52
52
|
switch (e) {
|
|
53
53
|
case 0: return !!x;
|
|
54
|
-
case 1: return !!
|
|
55
|
-
case 2: return
|
|
54
|
+
case 1: return !!S;
|
|
55
|
+
case 2: return w === "existing" ? !!E : !!(O.trim() && k.trim());
|
|
56
56
|
default: return !0;
|
|
57
57
|
}
|
|
58
58
|
}, Ke = (e) => {
|
|
@@ -82,11 +82,11 @@ function v() {
|
|
|
82
82
|
I(null), L("That code is not active for this event.");
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
|
-
I(n), L(""), t.success("Promo applied",
|
|
85
|
+
I(n), L(""), t.success("Promo applied", ne(n.discountType, n.discountValue, Y));
|
|
86
86
|
}, $ = () => {
|
|
87
87
|
I(null), P(""), L("");
|
|
88
88
|
}, Ze = () => {
|
|
89
|
-
b(0),
|
|
89
|
+
b(0), Se(""), C(""), T("new"), D(""), Ce(""), we(""), Ee(""), j(""), M(1), $(), ke("");
|
|
90
90
|
};
|
|
91
91
|
return z ? /* @__PURE__ */ d("div", {
|
|
92
92
|
className: "mx-auto max-w-2xl space-y-6 p-6",
|
|
@@ -302,11 +302,11 @@ function v() {
|
|
|
302
302
|
}) : /* @__PURE__ */ u("div", {
|
|
303
303
|
className: "grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3",
|
|
304
304
|
children: V.map((e) => {
|
|
305
|
-
let t = e.id ===
|
|
305
|
+
let t = e.id === S, n = e.capacity ?? null, r = e.soldCount ?? 0, i = n && n > 0 ? Math.min(100, Math.round(r / n * 100)) : null, a = n != null && r >= n;
|
|
306
306
|
return /* @__PURE__ */ d("button", {
|
|
307
307
|
type: "button",
|
|
308
308
|
disabled: a && !t,
|
|
309
|
-
onClick: () =>
|
|
309
|
+
onClick: () => C(e.id),
|
|
310
310
|
"aria-pressed": t,
|
|
311
311
|
className: `flex flex-col gap-3 rounded-card border p-4 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${t ? "border-action-primary-border bg-accent-wash ring-1 ring-border-focus" : "border-border-seam bg-bg-surface hover:border-border-strong"}`,
|
|
312
312
|
children: [
|
|
@@ -398,25 +398,25 @@ function v() {
|
|
|
398
398
|
className: "inline-flex rounded-input border border-border-seam bg-bg-sunken p-1",
|
|
399
399
|
children: [/* @__PURE__ */ u("button", {
|
|
400
400
|
type: "button",
|
|
401
|
-
onClick: () =>
|
|
402
|
-
className: `rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors ${
|
|
401
|
+
onClick: () => T("new"),
|
|
402
|
+
className: `rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors ${w === "new" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
|
|
403
403
|
children: "New attendee"
|
|
404
404
|
}), /* @__PURE__ */ u("button", {
|
|
405
405
|
type: "button",
|
|
406
|
-
onClick: () =>
|
|
406
|
+
onClick: () => T("existing"),
|
|
407
407
|
disabled: H.length === 0,
|
|
408
|
-
className: `rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${
|
|
408
|
+
className: `rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${w === "existing" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
|
|
409
409
|
children: "Existing attendee"
|
|
410
410
|
})]
|
|
411
411
|
}),
|
|
412
|
-
|
|
412
|
+
w === "existing" ? /* @__PURE__ */ d("label", {
|
|
413
413
|
className: "block space-y-1 text-sm",
|
|
414
414
|
children: [/* @__PURE__ */ u("span", {
|
|
415
415
|
className: "font-medium text-text-primary",
|
|
416
416
|
children: "Attendee"
|
|
417
417
|
}), /* @__PURE__ */ d(ge, {
|
|
418
|
-
value:
|
|
419
|
-
onValueChange:
|
|
418
|
+
value: E,
|
|
419
|
+
onValueChange: D,
|
|
420
420
|
children: [/* @__PURE__ */ u(ye, {
|
|
421
421
|
"aria-label": "Attendee",
|
|
422
422
|
children: /* @__PURE__ */ u(be, { placeholder: "Select an attendee" })
|
|
@@ -438,8 +438,8 @@ function v() {
|
|
|
438
438
|
className: "font-medium text-text-primary",
|
|
439
439
|
children: "Full name"
|
|
440
440
|
}), /* @__PURE__ */ u(g, {
|
|
441
|
-
value:
|
|
442
|
-
onChange: (e) =>
|
|
441
|
+
value: O,
|
|
442
|
+
onChange: (e) => Ce(e.target.value),
|
|
443
443
|
placeholder: "Enter full name"
|
|
444
444
|
})]
|
|
445
445
|
}),
|
|
@@ -450,8 +450,8 @@ function v() {
|
|
|
450
450
|
children: "Email"
|
|
451
451
|
}), /* @__PURE__ */ u(g, {
|
|
452
452
|
type: "email",
|
|
453
|
-
value:
|
|
454
|
-
onChange: (e) =>
|
|
453
|
+
value: k,
|
|
454
|
+
onChange: (e) => we(e.target.value),
|
|
455
455
|
placeholder: "Enter email address"
|
|
456
456
|
})]
|
|
457
457
|
}),
|
|
@@ -461,8 +461,8 @@ function v() {
|
|
|
461
461
|
className: "font-medium text-text-primary",
|
|
462
462
|
children: "Company"
|
|
463
463
|
}), /* @__PURE__ */ u(g, {
|
|
464
|
-
value:
|
|
465
|
-
onChange: (e) =>
|
|
464
|
+
value: Te,
|
|
465
|
+
onChange: (e) => Ee(e.target.value),
|
|
466
466
|
placeholder: "Enter company name"
|
|
467
467
|
})]
|
|
468
468
|
}),
|
|
@@ -472,7 +472,7 @@ function v() {
|
|
|
472
472
|
className: "font-medium text-text-primary",
|
|
473
473
|
children: "Phone"
|
|
474
474
|
}), /* @__PURE__ */ u(g, {
|
|
475
|
-
value:
|
|
475
|
+
value: A,
|
|
476
476
|
onChange: (e) => j(e.target.value),
|
|
477
477
|
placeholder: "Optional"
|
|
478
478
|
})]
|
|
@@ -518,7 +518,7 @@ function v() {
|
|
|
518
518
|
className: "h-3.5 w-3.5",
|
|
519
519
|
"aria-hidden": "true"
|
|
520
520
|
}),
|
|
521
|
-
|
|
521
|
+
ne(F.discountType, F.discountValue, Y),
|
|
522
522
|
" applied"
|
|
523
523
|
]
|
|
524
524
|
}) : Oe ? /* @__PURE__ */ u("span", {
|
|
@@ -601,7 +601,7 @@ function v() {
|
|
|
601
601
|
className: "ml-auto text-right font-medium text-text-primary",
|
|
602
602
|
children: [Ue || "—", /* @__PURE__ */ u("span", {
|
|
603
603
|
className: "block text-xs font-normal text-text-secondary",
|
|
604
|
-
children:
|
|
604
|
+
children: w === "existing" ? q?.email : k.trim()
|
|
605
605
|
})]
|
|
606
606
|
})
|
|
607
607
|
]
|
|
@@ -643,46 +643,46 @@ function v() {
|
|
|
643
643
|
}) : /* @__PURE__ */ d(m, {
|
|
644
644
|
type: "button",
|
|
645
645
|
onClick: async () => {
|
|
646
|
-
if (!x || !
|
|
646
|
+
if (!x || !S) {
|
|
647
647
|
t.error("Incomplete", "Pick an event and ticket first.");
|
|
648
648
|
return;
|
|
649
649
|
}
|
|
650
|
-
if (
|
|
650
|
+
if (w === "new" && (!O.trim() || !k.trim())) {
|
|
651
651
|
t.error("Attendee required", "Enter a name and email, or pick an existing attendee.");
|
|
652
652
|
return;
|
|
653
653
|
}
|
|
654
|
-
if (
|
|
654
|
+
if (w === "existing" && !E) {
|
|
655
655
|
t.error("Attendee required", "Select an existing attendee.");
|
|
656
656
|
return;
|
|
657
657
|
}
|
|
658
658
|
try {
|
|
659
|
-
let e =
|
|
660
|
-
if (
|
|
659
|
+
let e = E, n = q?.fullName ?? "";
|
|
660
|
+
if (w === "new") {
|
|
661
661
|
let t = await Le({ variables: { input: {
|
|
662
662
|
eventId: x,
|
|
663
|
-
fullName:
|
|
664
|
-
email:
|
|
665
|
-
company:
|
|
666
|
-
phone:
|
|
663
|
+
fullName: O.trim(),
|
|
664
|
+
email: k.trim(),
|
|
665
|
+
company: Te.trim() || null,
|
|
666
|
+
phone: A.trim() || null,
|
|
667
667
|
profile: {},
|
|
668
668
|
metadata: {}
|
|
669
669
|
} } }), r = t.data?.createAttendee?.id;
|
|
670
|
-
if (!
|
|
671
|
-
e = r, n =
|
|
670
|
+
if (!ie(t, r, "Could not create attendee") || !r) return;
|
|
671
|
+
e = r, n = O.trim();
|
|
672
672
|
}
|
|
673
673
|
let r = {};
|
|
674
674
|
Q && R.trim() && (r.billingAccountId = R.trim());
|
|
675
675
|
let i = await ze({ variables: { input: {
|
|
676
676
|
eventId: x,
|
|
677
677
|
attendeeId: e,
|
|
678
|
-
ticketTypeId:
|
|
678
|
+
ticketTypeId: S,
|
|
679
679
|
quantity: J,
|
|
680
680
|
currency: Y,
|
|
681
681
|
status: "CONFIRMED",
|
|
682
682
|
promoCode: F?.code || void 0,
|
|
683
683
|
metadata: r
|
|
684
684
|
} } });
|
|
685
|
-
if (!
|
|
685
|
+
if (!ie(i, i.data?.createRegistration?.id, F ? "Could not create registration (check that your promo code is still valid)" : "Could not create registration")) return;
|
|
686
686
|
let a = i.data?.createRegistration, o = a?.totalAmount == null ? He : Number(a.totalAmount);
|
|
687
687
|
Ae({
|
|
688
688
|
attendeeName: n || "Attendee",
|
|
@@ -698,7 +698,7 @@ function v() {
|
|
|
698
698
|
free: !Q
|
|
699
699
|
}), t.success("Registration confirmed", n || void 0);
|
|
700
700
|
} catch (e) {
|
|
701
|
-
t.error("Could not register attendee",
|
|
701
|
+
t.error("Could not register attendee", re(e));
|
|
702
702
|
}
|
|
703
703
|
},
|
|
704
704
|
disabled: W,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RegisterAttendeePage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/registration/RegisterAttendeePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n ArrowLeft,\n ArrowRight,\n BadgePercent,\n CalendarDays,\n Check,\n CheckCircle2,\n Minus,\n Plus,\n Ticket,\n UserRound,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n GradientText,\n Input,\n PagePurpose,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Stepper,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useAttendeesQuery,\n useCreateAttendeeMutation,\n useCreateRegistrationMutation,\n useEventsQuery,\n usePromoCodesQuery,\n useTicketTypesQuery,\n type PromoCodeGql,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { computeDiscount, describeDiscount, formatMoney } from '../../lib/format';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype Confirmation = {\n attendeeName: string;\n eventName: string;\n ticketName: string;\n quantity: number;\n status: string;\n subtotal: number;\n discount: number;\n total: number;\n currency: string;\n promoCode: string | null;\n free: boolean;\n};\n\nconst STEPS = [\n { key: 'event', label: 'Event', description: 'Choose the event' },\n { key: 'ticket', label: 'Ticket', description: 'Pick a ticket type' },\n { key: 'attendee', label: 'Attendee', description: 'Who is coming' },\n { key: 'confirm', label: 'Confirm', description: 'Review & submit' },\n];\n\nexport default function RegisterAttendeePage() {\n const { navigate } = useEventfullyManaged();\n\n const [step, setStep] = useState(0);\n const [eventId, setEventId] = useState('');\n const [ticketTypeId, setTicketTypeId] = useState('');\n const [attendeeMode, setAttendeeMode] = useState<'new' | 'existing'>('new');\n const [attendeeId, setAttendeeId] = useState('');\n const [fullName, setFullName] = useState('');\n const [email, setEmail] = useState('');\n const [company, setCompany] = useState('');\n const [phone, setPhone] = useState('');\n const [quantity, setQuantity] = useState(1);\n const [promoInput, setPromoInput] = useState('');\n const [appliedPromo, setAppliedPromo] = useState<PromoCodeGql | null>(null);\n const [promoError, setPromoError] = useState('');\n const [billingAccountId, setBillingAccountId] = useState('');\n const [confirmation, setConfirmation] = useState<Confirmation | null>(null);\n\n const { data: eventsData, loading: eventsLoading } = useEventsQuery({ limit: 100, offset: 0 });\n const { data: ticketData, loading: ticketsLoading } = useTicketTypesQuery({\n eventId: eventId || undefined,\n limit: 100,\n offset: 0,\n });\n const { data: attendeesData } = useAttendeesQuery({ eventId: eventId || undefined, limit: 100, offset: 0 });\n const { data: promoData } = usePromoCodesQuery({ eventId: eventId || undefined, limit: 100, offset: 0 });\n\n const events = useMemo(() => eventsData?.events.items ?? [], [eventsData]);\n const tickets = useMemo(\n () =>\n (ticketData?.ticketTypes.items ?? []).filter(\n (ticket) => (!eventId || ticket.eventId === eventId) && ticket.isActive\n ),\n [ticketData, eventId]\n );\n const attendees = useMemo(\n () => (attendeesData?.attendees.items ?? []).filter((attendee) => !eventId || attendee.eventId === eventId),\n [attendeesData, eventId]\n );\n const activePromos = useMemo(\n () =>\n (promoData?.promoCodes.items ?? []).filter((promo) => promo.isActive && (!eventId || promo.eventId === eventId)),\n [promoData, eventId]\n );\n\n const [createAttendee, { loading: creatingAttendee }] = useCreateAttendeeMutation();\n const [createRegistration, { loading: creatingRegistration }] = useCreateRegistrationMutation();\n const saving = creatingAttendee || creatingRegistration;\n\n const selectedEvent = useMemo(() => events.find((item) => item.id === eventId), [events, eventId]);\n const selectedTicket = useMemo(() => tickets.find((ticket) => ticket.id === ticketTypeId), [tickets, ticketTypeId]);\n const selectedAttendee = useMemo(\n () => attendees.find((attendee) => attendee.id === attendeeId),\n [attendees, attendeeId]\n );\n\n const qty = Math.max(1, quantity);\n const unitPrice = selectedTicket ? Number(selectedTicket.price) : 0;\n const currency = selectedTicket?.currency ?? 'USD';\n const subtotal = Number.isFinite(unitPrice) ? unitPrice * qty : 0;\n const discount = appliedPromo\n ? computeDiscount(subtotal, appliedPromo.discountType, Number(appliedPromo.discountValue))\n : 0;\n const total = Math.max(subtotal - discount, 0);\n const hasPositiveAmount = subtotal > 0;\n\n const attendeeName = attendeeMode === 'existing' ? (selectedAttendee?.fullName ?? '') : fullName.trim();\n\n const onEventChange = (value: string) => {\n setEventId(value);\n setTicketTypeId('');\n setAttendeeMode('new');\n setAttendeeId('');\n setAppliedPromo(null);\n setPromoInput('');\n setPromoError('');\n };\n\n const isStepValid = (index: number): boolean => {\n switch (index) {\n case 0:\n return Boolean(eventId);\n case 1:\n return Boolean(ticketTypeId);\n case 2:\n return attendeeMode === 'existing' ? Boolean(attendeeId) : Boolean(fullName.trim() && email.trim());\n default:\n return true;\n }\n };\n\n const canGoTo = (index: number): boolean => {\n if (index <= step) return true;\n for (let i = 0; i < index; i += 1) {\n if (!isStepValid(i)) return false;\n }\n return true;\n };\n\n const goToStep = (index: number) => {\n if (canGoTo(index)) {\n setStep(index);\n }\n };\n\n const goNext = () => {\n if (!isStepValid(step)) {\n const messages = [\n 'Choose an event to continue.',\n 'Pick a ticket type to continue.',\n 'Select or enter an attendee to continue.',\n ];\n notify.error('One more thing', messages[step] ?? 'Complete this step to continue.');\n return;\n }\n setStep((current) => Math.min(current + 1, STEPS.length - 1));\n };\n\n const goBack = () => setStep((current) => Math.max(current - 1, 0));\n\n const applyPromo = () => {\n const code = promoInput.trim().toUpperCase();\n if (!code) {\n setAppliedPromo(null);\n setPromoError('');\n return;\n }\n const match = activePromos.find((promo) => promo.code.toUpperCase() === code);\n if (!match) {\n setAppliedPromo(null);\n setPromoError('That code is not active for this event.');\n return;\n }\n setAppliedPromo(match);\n setPromoError('');\n notify.success('Promo applied', describeDiscount(match.discountType, match.discountValue, currency));\n };\n\n const clearPromo = () => {\n setAppliedPromo(null);\n setPromoInput('');\n setPromoError('');\n };\n\n const resetAll = () => {\n setStep(0);\n setEventId('');\n setTicketTypeId('');\n setAttendeeMode('new');\n setAttendeeId('');\n setFullName('');\n setEmail('');\n setCompany('');\n setPhone('');\n setQuantity(1);\n clearPromo();\n setBillingAccountId('');\n };\n\n const onConfirm = async () => {\n if (!eventId || !ticketTypeId) {\n notify.error('Incomplete', 'Pick an event and ticket first.');\n return;\n }\n if (attendeeMode === 'new' && (!fullName.trim() || !email.trim())) {\n notify.error('Attendee required', 'Enter a name and email, or pick an existing attendee.');\n return;\n }\n if (attendeeMode === 'existing' && !attendeeId) {\n notify.error('Attendee required', 'Select an existing attendee.');\n return;\n }\n\n try {\n let resolvedAttendeeId = attendeeId;\n let resolvedAttendeeName = selectedAttendee?.fullName ?? '';\n\n if (attendeeMode === 'new') {\n const attendeeResponse = await createAttendee({\n variables: {\n input: {\n eventId,\n fullName: fullName.trim(),\n email: email.trim(),\n company: company.trim() || null,\n phone: phone.trim() || null,\n profile: {},\n metadata: {},\n },\n },\n });\n const createdId = attendeeResponse.data?.createAttendee?.id;\n if (!mutationSucceeded(attendeeResponse, createdId, 'Could not create attendee') || !createdId) {\n return;\n }\n resolvedAttendeeId = createdId;\n resolvedAttendeeName = fullName.trim();\n }\n\n // The money leg is owned by global-billing-svc — never price locally.\n // totalAmount is always computed server-side from TicketType.price *\n // quantity; a supplied promoCode is validated and its discount applied\n // atomically by the backend (BOFF-3998) — the client-side `total`\n // above is only a preview, never trusted for billing.\n const metadata: Record<string, unknown> = {};\n if (hasPositiveAmount && billingAccountId.trim()) {\n metadata.billingAccountId = billingAccountId.trim();\n }\n\n const registrationResponse = await createRegistration({\n variables: {\n input: {\n eventId,\n attendeeId: resolvedAttendeeId,\n ticketTypeId,\n quantity: qty,\n currency,\n status: 'CONFIRMED',\n promoCode: appliedPromo?.code || undefined,\n metadata,\n },\n },\n });\n if (\n !mutationSucceeded(\n registrationResponse,\n registrationResponse.data?.createRegistration?.id,\n appliedPromo\n ? 'Could not create registration (check that your promo code is still valid)'\n : 'Could not create registration'\n )\n ) {\n return;\n }\n\n const registration = registrationResponse.data?.createRegistration;\n // Prefer the server-computed totalAmount (source of truth once a promo\n // discount was applied); fall back to the client preview for a free\n // registration where totalAmount comes back null.\n const serverTotal = registration?.totalAmount != null ? Number(registration.totalAmount) : total;\n setConfirmation({\n attendeeName: resolvedAttendeeName || 'Attendee',\n eventName: selectedEvent?.name ?? 'Event',\n ticketName: selectedTicket?.name ?? 'Ticket',\n quantity: qty,\n status: registration?.status ?? 'CONFIRMED',\n subtotal,\n discount: Math.max(subtotal - serverTotal, 0),\n total: serverTotal,\n currency,\n promoCode: appliedPromo?.code ?? null,\n free: !hasPositiveAmount,\n });\n notify.success('Registration confirmed', resolvedAttendeeName || undefined);\n } catch (error) {\n notify.error('Could not register attendee', describeError(error));\n }\n };\n\n if (confirmation) {\n return (\n <div className=\"mx-auto max-w-2xl space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/registration')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Registration\n </Button>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"p-8 text-center\">\n <div className=\"mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-status-success-bg-subtle\">\n <CheckCircle2 className=\"h-8 w-8 text-status-success-text\" aria-hidden=\"true\" />\n </div>\n <h1 className=\"mt-4 text-2xl font-bold text-text-primary\">Registration confirmed</h1>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {confirmation.attendeeName} is registered for {confirmation.eventName}.\n </p>\n\n <dl className=\"mx-auto mt-6 max-w-sm space-y-2 rounded-card border border-border-seam bg-bg-surface p-4 text-left text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Ticket</dt>\n <dd className=\"font-medium text-text-primary\">\n {confirmation.ticketName}\n {confirmation.quantity > 1 ? ` × ${confirmation.quantity}` : ''}\n </dd>\n </div>\n {!confirmation.free ? (\n <>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Subtotal</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatMoney(confirmation.subtotal, confirmation.currency)}\n </dd>\n </div>\n {confirmation.discount > 0 ? (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">\n Promo{confirmation.promoCode ? ` · ${confirmation.promoCode}` : ''}\n </dt>\n <dd className=\"tabular-nums text-status-success-text\">\n −{formatMoney(confirmation.discount, confirmation.currency)}\n </dd>\n </div>\n ) : null}\n </>\n ) : null}\n <div className=\"flex justify-between border-t border-border-seam pt-2\">\n <dt className=\"font-semibold text-text-primary\">Total</dt>\n <dd className=\"font-bold tabular-nums text-text-primary\">\n {confirmation.free ? 'Free' : formatMoney(confirmation.total, confirmation.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Status</dt>\n <dd className=\"font-medium text-text-primary\">{confirmation.status}</dd>\n </div>\n </dl>\n {!confirmation.free ? (\n <p className=\"mt-3 text-xs text-text-muted\">\n Final pricing and payment are settled by the billing service.\n </p>\n ) : null}\n\n <div className=\"mt-8 flex flex-col justify-center gap-3 sm:flex-row\">\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('/registration')}>\n Back to Registrations\n </Button>\n <Button\n type=\"button\"\n onClick={() => {\n setConfirmation(null);\n resetAll();\n }}\n >\n Register another\n </Button>\n </div>\n </GlassCard>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/registration')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Registration\n </Button>\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">\n <GradientText>Register Attendee</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Walk through the event, ticket and attendee in a few quick steps.\n </p>\n </div>\n\n <PagePurpose>\n Register a person for an event against a ticket type. Pick the event and ticket, choose an existing attendee or\n add a new one, apply a promo code if they have one, then confirm. The order summary previews the price — final\n pricing and payment are handled by the billing service.\n </PagePurpose>\n\n <Stepper steps={STEPS} active={step} onStepClick={goToStep} />\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1fr)_20rem]\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5 sm:p-6\">\n {/* STEP 0 — EVENT */}\n {step === 0 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Which event?</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Choose the event this attendee is signing up for.</p>\n </div>\n {eventsLoading ? (\n <p className=\"text-sm text-text-muted\">Loading events…</p>\n ) : events.length === 0 ? (\n <div className=\"rounded-card border border-dashed border-border-default p-6 text-center text-sm text-text-secondary\">\n No events yet.{' '}\n <button\n type=\"button\"\n className=\"font-medium text-text-link underline-offset-2 hover:underline\"\n onClick={() => navigate('/events/create')}\n >\n Create an event\n </button>{' '}\n first.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {events.map((eventItem) => {\n const selected = eventItem.id === eventId;\n return (\n <button\n key={eventItem.id}\n type=\"button\"\n onClick={() => onEventChange(eventItem.id)}\n aria-pressed={selected}\n className={`flex items-center gap-3 rounded-card border p-4 text-left transition-colors ${\n selected\n ? 'border-action-primary-border bg-accent-wash'\n : 'border-border-seam bg-bg-surface hover:border-border-strong'\n }`}\n >\n <span\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-input ${\n selected ? 'bg-action-primary-bg text-action-primary-text' : 'bg-bg-sunken text-text-muted'\n }`}\n >\n <CalendarDays className=\"h-5 w-5\" aria-hidden=\"true\" />\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-text-primary\">\n {eventItem.name}\n </span>\n {selected ? (\n <Check className=\"h-4 w-4 shrink-0 text-action-primary-bg\" aria-hidden=\"true\" />\n ) : null}\n </button>\n );\n })}\n </div>\n )}\n </div>\n ) : null}\n\n {/* STEP 1 — TICKET */}\n {step === 1 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket type</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Pick the ticket and how many they need.</p>\n </div>\n {ticketsLoading ? (\n <p className=\"text-sm text-text-muted\">Loading tickets…</p>\n ) : tickets.length === 0 ? (\n <div className=\"rounded-card border border-dashed border-border-default p-6 text-center text-sm text-text-secondary\">\n This event has no active ticket types.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {tickets.map((ticket) => {\n const selected = ticket.id === ticketTypeId;\n const cap = ticket.capacity ?? null;\n const sold = ticket.soldCount ?? 0;\n const pct = cap && cap > 0 ? Math.min(100, Math.round((sold / cap) * 100)) : null;\n const soldOut = cap != null && sold >= cap;\n return (\n <button\n key={ticket.id}\n type=\"button\"\n disabled={soldOut && !selected}\n onClick={() => setTicketTypeId(ticket.id)}\n aria-pressed={selected}\n className={`flex flex-col gap-3 rounded-card border p-4 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${\n selected\n ? 'border-action-primary-border bg-accent-wash ring-1 ring-border-focus'\n : 'border-border-seam bg-bg-surface hover:border-border-strong'\n }`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-semibold text-text-primary\">{ticket.name}</span>\n {selected ? (\n <Check className=\"h-4 w-4 shrink-0 text-action-primary-bg\" aria-hidden=\"true\" />\n ) : (\n <Ticket className=\"h-4 w-4 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n )}\n </div>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {Number(ticket.price) > 0 ? formatMoney(Number(ticket.price), ticket.currency) : 'Free'}\n </span>\n {cap != null ? (\n <div className=\"space-y-1\">\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg\"\n style={{ width: `${pct ?? 0}%` }}\n />\n </div>\n <span className=\"text-xs text-text-muted\">\n {soldOut ? 'Sold out' : `${sold} / ${cap} sold`}\n </span>\n </div>\n ) : (\n <span className=\"text-xs text-text-muted\">{sold} sold</span>\n )}\n </button>\n );\n })}\n </div>\n )}\n\n <div className=\"flex flex-wrap items-end gap-4 border-t border-border-seam pt-4\">\n <div className=\"space-y-1\">\n <span className=\"text-sm font-medium text-text-primary\">Quantity</span>\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Decrease quantity\"\n disabled={qty <= 1}\n onClick={() => setQuantity((value) => Math.max(1, value - 1))}\n >\n <Minus className=\"h-4 w-4\" />\n </Button>\n <span className=\"w-10 text-center text-base font-semibold tabular-nums text-text-primary\">\n {qty}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Increase quantity\"\n onClick={() => setQuantity((value) => value + 1)}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n\n {/* STEP 2 — ATTENDEE */}\n {step === 2 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Attendee information</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Add someone new or pick an existing attendee.</p>\n </div>\n\n <div className=\"inline-flex rounded-input border border-border-seam bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setAttendeeMode('new')}\n className={`rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors ${\n attendeeMode === 'new'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n New attendee\n </button>\n <button\n type=\"button\"\n onClick={() => setAttendeeMode('existing')}\n disabled={attendees.length === 0}\n className={`rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${\n attendeeMode === 'existing'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n Existing attendee\n </button>\n </div>\n\n {attendeeMode === 'existing' ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Attendee</span>\n <Select value={attendeeId} onValueChange={setAttendeeId}>\n <SelectTrigger aria-label=\"Attendee\">\n <SelectValue placeholder=\"Select an attendee\" />\n </SelectTrigger>\n <SelectContent>\n {attendees.map((attendee) => (\n <SelectItem key={attendee.id} value={attendee.id}>\n {attendee.fullName} · {attendee.email}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Full name</span>\n <Input\n value={fullName}\n onChange={(e) => setFullName(e.target.value)}\n placeholder=\"Enter full name\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Email</span>\n <Input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter email address\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Company</span>\n <Input\n value={company}\n onChange={(e) => setCompany(e.target.value)}\n placeholder=\"Enter company name\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Phone</span>\n <Input value={phone} onChange={(e) => setPhone(e.target.value)} placeholder=\"Optional\" />\n </label>\n </div>\n )}\n\n {/* Promo code */}\n <div className=\"space-y-2 border-t border-border-seam pt-4\">\n <span className=\"text-sm font-medium text-text-primary\">Promo code (optional)</span>\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <Input\n value={promoInput}\n onChange={(e) => {\n setPromoInput(e.target.value);\n setPromoError('');\n }}\n placeholder=\"Enter promo code\"\n className=\"sm:flex-1\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n applyPromo();\n }\n }}\n />\n {appliedPromo ? (\n <Button type=\"button\" variant=\"outline\" onClick={clearPromo}>\n Remove\n </Button>\n ) : (\n <Button type=\"button\" variant=\"outline\" onClick={applyPromo} disabled={!promoInput.trim()}>\n Apply\n </Button>\n )}\n </div>\n {appliedPromo ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2.5 py-0.5 text-xs font-medium text-status-success-text\">\n <BadgePercent className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {describeDiscount(appliedPromo.discountType, appliedPromo.discountValue, currency)} applied\n </span>\n ) : promoError ? (\n <span className=\"text-xs text-status-error-text\">{promoError}</span>\n ) : activePromos.length > 0 ? (\n <div className=\"flex flex-wrap items-center gap-1.5 text-xs text-text-muted\">\n <span>Available:</span>\n {activePromos.slice(0, 4).map((promo) => (\n <button\n key={promo.id}\n type=\"button\"\n onClick={() => {\n setPromoInput(promo.code);\n setAppliedPromo(promo);\n setPromoError('');\n }}\n className=\"rounded-full border border-border-seam bg-bg-surface px-2 py-0.5 font-medium text-text-secondary hover:border-border-strong hover:text-text-primary\"\n >\n {promo.code}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {/* STEP 3 — CONFIRM */}\n {step === 3 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Review & confirm</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Double-check the details before registering.</p>\n </div>\n <dl className=\"divide-y divide-border-seam rounded-card border border-border-seam bg-bg-surface text-sm\">\n <div className=\"flex items-center gap-3 p-3\">\n <CalendarDays className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Event</dt>\n <dd className=\"ml-auto font-medium text-text-primary\">{selectedEvent?.name ?? '—'}</dd>\n </div>\n <div className=\"flex items-center gap-3 p-3\">\n <Ticket className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Ticket</dt>\n <dd className=\"ml-auto font-medium text-text-primary\">\n {selectedTicket?.name ?? '—'}\n {qty > 1 ? ` × ${qty}` : ''}\n </dd>\n </div>\n <div className=\"flex items-center gap-3 p-3\">\n <UserRound className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Attendee</dt>\n <dd className=\"ml-auto text-right font-medium text-text-primary\">\n {attendeeName || '—'}\n <span className=\"block text-xs font-normal text-text-secondary\">\n {attendeeMode === 'existing' ? selectedAttendee?.email : email.trim()}\n </span>\n </dd>\n </div>\n </dl>\n\n {hasPositiveAmount ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Billing account ID (optional)</span>\n <Input\n value={billingAccountId}\n onChange={(e) => setBillingAccountId(e.target.value)}\n placeholder=\"Attach an existing billing account\"\n />\n <span className=\"text-xs text-text-secondary\">\n When provided, the charge is attached to this billing account.\n </span>\n </label>\n ) : null}\n </div>\n ) : null}\n\n {/* Wizard controls */}\n <div className=\"mt-6 flex items-center justify-between gap-3 border-t border-border-seam pt-4\">\n <Button type=\"button\" variant=\"ghost\" onClick={goBack} disabled={step === 0 || saving}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n {step < STEPS.length - 1 ? (\n <Button type=\"button\" onClick={goNext}>\n Continue\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button type=\"button\" onClick={onConfirm} disabled={saving}>\n <Ticket className=\"h-4 w-4\" />\n {saving ? 'Registering…' : 'Confirm registration'}\n </Button>\n )}\n </div>\n </GlassCard>\n\n {/* ORDER SUMMARY */}\n <GlassCard treatment=\"glass\" className=\"h-fit p-5 lg:sticky lg:top-6\">\n <h2 className=\"text-base font-semibold text-text-primary\">Order summary</h2>\n {selectedTicket ? (\n <div className=\"mt-4 space-y-3 text-sm\">\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"min-w-0 text-text-secondary\">\n {selectedEvent?.name ? `${selectedEvent.name} — ` : ''}\n {selectedTicket.name}\n {qty > 1 ? <span className=\"text-text-muted\"> × {qty}</span> : null}\n </span>\n <span className=\"shrink-0 tabular-nums text-text-primary\">\n {subtotal > 0 ? formatMoney(subtotal, currency) : 'Free'}\n </span>\n </div>\n {appliedPromo && discount > 0 ? (\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"text-text-secondary\">Promo · {appliedPromo.code}</span>\n <span className=\"shrink-0 tabular-nums text-status-success-text\">\n −{formatMoney(discount, currency)}\n </span>\n </div>\n ) : null}\n <div className=\"flex items-center justify-between border-t border-border-seam pt-3\">\n <span className=\"font-semibold text-text-primary\">Total</span>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {subtotal > 0 ? formatMoney(total, currency) : 'Free'}\n </span>\n </div>\n {subtotal > 0 ? (\n <p className=\"text-xs text-text-muted\">Final pricing & payment handled by the billing service.</p>\n ) : null}\n </div>\n ) : (\n <p className=\"mt-4 text-sm text-text-muted\">\n Pick a ticket to see the price breakdown. Your order total updates as you go.\n </p>\n )}\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RegisterAttendeePage.js","names":[],"sources":["../../../../src/eventfullymanaged/pages/registration/RegisterAttendeePage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n ArrowLeft,\n ArrowRight,\n BadgePercent,\n CalendarDays,\n Check,\n CheckCircle2,\n Minus,\n Plus,\n Ticket,\n UserRound,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n GradientText,\n Input,\n PagePurpose,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Stepper,\n} from '@burdenoff/fe-libs/ui';\n\nimport {\n useAttendeesQuery,\n useCreateAttendeeMutation,\n useCreateRegistrationMutation,\n useEventsQuery,\n usePromoCodesQuery,\n useTicketTypesQuery,\n type PromoCodeGql,\n} from '../../api/eventApi';\nimport { useEventfullyManaged } from '../../context/EventfullyManagedContext';\nimport { computeDiscount, describeDiscount, formatMoney } from '../../lib/format';\nimport { describeError, mutationSucceeded } from '../../lib/mutationResult';\nimport { notify } from '../../lib/toast';\n\ntype Confirmation = {\n attendeeName: string;\n eventName: string;\n ticketName: string;\n quantity: number;\n status: string;\n subtotal: number;\n discount: number;\n total: number;\n currency: string;\n promoCode: string | null;\n free: boolean;\n};\n\nconst STEPS = [\n { key: 'event', label: 'Event', description: 'Choose the event' },\n { key: 'ticket', label: 'Ticket', description: 'Pick a ticket type' },\n { key: 'attendee', label: 'Attendee', description: 'Who is coming' },\n { key: 'confirm', label: 'Confirm', description: 'Review & submit' },\n];\n\nexport default function RegisterAttendeePage() {\n const { navigate } = useEventfullyManaged();\n\n const [step, setStep] = useState(0);\n const [eventId, setEventId] = useState('');\n const [ticketTypeId, setTicketTypeId] = useState('');\n const [attendeeMode, setAttendeeMode] = useState<'new' | 'existing'>('new');\n const [attendeeId, setAttendeeId] = useState('');\n const [fullName, setFullName] = useState('');\n const [email, setEmail] = useState('');\n const [company, setCompany] = useState('');\n const [phone, setPhone] = useState('');\n const [quantity, setQuantity] = useState(1);\n const [promoInput, setPromoInput] = useState('');\n const [appliedPromo, setAppliedPromo] = useState<PromoCodeGql | null>(null);\n const [promoError, setPromoError] = useState('');\n const [billingAccountId, setBillingAccountId] = useState('');\n const [confirmation, setConfirmation] = useState<Confirmation | null>(null);\n\n const { data: eventsData, loading: eventsLoading } = useEventsQuery({ limit: 100, offset: 0 });\n const { data: ticketData, loading: ticketsLoading } = useTicketTypesQuery({\n eventId: eventId || undefined,\n limit: 100,\n offset: 0,\n });\n const { data: attendeesData } = useAttendeesQuery({ eventId: eventId || undefined, limit: 100, offset: 0 });\n const { data: promoData } = usePromoCodesQuery({ eventId: eventId || undefined, limit: 100, offset: 0 });\n\n const events = useMemo(() => eventsData?.events.items ?? [], [eventsData]);\n const tickets = useMemo(\n () =>\n (ticketData?.ticketTypes.items ?? []).filter(\n (ticket) => (!eventId || ticket.eventId === eventId) && ticket.isActive\n ),\n [ticketData, eventId]\n );\n const attendees = useMemo(\n () => (attendeesData?.attendees.items ?? []).filter((attendee) => !eventId || attendee.eventId === eventId),\n [attendeesData, eventId]\n );\n const activePromos = useMemo(\n () =>\n (promoData?.promoCodes.items ?? []).filter((promo) => promo.isActive && (!eventId || promo.eventId === eventId)),\n [promoData, eventId]\n );\n\n const [createAttendee, { loading: creatingAttendee }] = useCreateAttendeeMutation();\n const [createRegistration, { loading: creatingRegistration }] = useCreateRegistrationMutation();\n const saving = creatingAttendee || creatingRegistration;\n\n const selectedEvent = useMemo(() => events.find((item) => item.id === eventId), [events, eventId]);\n const selectedTicket = useMemo(() => tickets.find((ticket) => ticket.id === ticketTypeId), [tickets, ticketTypeId]);\n const selectedAttendee = useMemo(\n () => attendees.find((attendee) => attendee.id === attendeeId),\n [attendees, attendeeId]\n );\n\n const qty = Math.max(1, quantity);\n const unitPrice = selectedTicket ? Number(selectedTicket.price) : 0;\n const currency = selectedTicket?.currency ?? 'USD';\n const subtotal = Number.isFinite(unitPrice) ? unitPrice * qty : 0;\n const discount = appliedPromo\n ? computeDiscount(subtotal, appliedPromo.discountType, Number(appliedPromo.discountValue))\n : 0;\n const total = Math.max(subtotal - discount, 0);\n const hasPositiveAmount = subtotal > 0;\n\n const attendeeName = attendeeMode === 'existing' ? (selectedAttendee?.fullName ?? '') : fullName.trim();\n\n const onEventChange = (value: string) => {\n setEventId(value);\n setTicketTypeId('');\n setAttendeeMode('new');\n setAttendeeId('');\n setAppliedPromo(null);\n setPromoInput('');\n setPromoError('');\n };\n\n const isStepValid = (index: number): boolean => {\n switch (index) {\n case 0:\n return Boolean(eventId);\n case 1:\n return Boolean(ticketTypeId);\n case 2:\n return attendeeMode === 'existing' ? Boolean(attendeeId) : Boolean(fullName.trim() && email.trim());\n default:\n return true;\n }\n };\n\n const canGoTo = (index: number): boolean => {\n if (index <= step) return true;\n for (let i = 0; i < index; i += 1) {\n if (!isStepValid(i)) return false;\n }\n return true;\n };\n\n const goToStep = (index: number) => {\n if (canGoTo(index)) {\n setStep(index);\n }\n };\n\n const goNext = () => {\n if (!isStepValid(step)) {\n const messages = [\n 'Choose an event to continue.',\n 'Pick a ticket type to continue.',\n 'Select or enter an attendee to continue.',\n ];\n notify.error('One more thing', messages[step] ?? 'Complete this step to continue.');\n return;\n }\n setStep((current) => Math.min(current + 1, STEPS.length - 1));\n };\n\n const goBack = () => setStep((current) => Math.max(current - 1, 0));\n\n const applyPromo = () => {\n const code = promoInput.trim().toUpperCase();\n if (!code) {\n setAppliedPromo(null);\n setPromoError('');\n return;\n }\n const match = activePromos.find((promo) => promo.code.toUpperCase() === code);\n if (!match) {\n setAppliedPromo(null);\n setPromoError('That code is not active for this event.');\n return;\n }\n setAppliedPromo(match);\n setPromoError('');\n notify.success('Promo applied', describeDiscount(match.discountType, match.discountValue, currency));\n };\n\n const clearPromo = () => {\n setAppliedPromo(null);\n setPromoInput('');\n setPromoError('');\n };\n\n const resetAll = () => {\n setStep(0);\n setEventId('');\n setTicketTypeId('');\n setAttendeeMode('new');\n setAttendeeId('');\n setFullName('');\n setEmail('');\n setCompany('');\n setPhone('');\n setQuantity(1);\n clearPromo();\n setBillingAccountId('');\n };\n\n const onConfirm = async () => {\n if (!eventId || !ticketTypeId) {\n notify.error('Incomplete', 'Pick an event and ticket first.');\n return;\n }\n if (attendeeMode === 'new' && (!fullName.trim() || !email.trim())) {\n notify.error('Attendee required', 'Enter a name and email, or pick an existing attendee.');\n return;\n }\n if (attendeeMode === 'existing' && !attendeeId) {\n notify.error('Attendee required', 'Select an existing attendee.');\n return;\n }\n\n try {\n let resolvedAttendeeId = attendeeId;\n let resolvedAttendeeName = selectedAttendee?.fullName ?? '';\n\n if (attendeeMode === 'new') {\n const attendeeResponse = await createAttendee({\n variables: {\n input: {\n eventId,\n fullName: fullName.trim(),\n email: email.trim(),\n company: company.trim() || null,\n phone: phone.trim() || null,\n profile: {},\n metadata: {},\n },\n },\n });\n const createdId = attendeeResponse.data?.createAttendee?.id;\n if (!mutationSucceeded(attendeeResponse, createdId, 'Could not create attendee') || !createdId) {\n return;\n }\n resolvedAttendeeId = createdId;\n resolvedAttendeeName = fullName.trim();\n }\n\n // The money leg is owned by global-billing-svc — never price locally.\n // totalAmount is always computed server-side from TicketType.price *\n // quantity; a supplied promoCode is validated and its discount applied\n // atomically by the backend (BOFF-3998) — the client-side `total`\n // above is only a preview, never trusted for billing.\n const metadata: Record<string, unknown> = {};\n if (hasPositiveAmount && billingAccountId.trim()) {\n metadata.billingAccountId = billingAccountId.trim();\n }\n\n const registrationResponse = await createRegistration({\n variables: {\n input: {\n eventId,\n attendeeId: resolvedAttendeeId,\n ticketTypeId,\n quantity: qty,\n currency,\n status: 'CONFIRMED',\n promoCode: appliedPromo?.code || undefined,\n metadata,\n },\n },\n });\n if (\n !mutationSucceeded(\n registrationResponse,\n registrationResponse.data?.createRegistration?.id,\n appliedPromo\n ? 'Could not create registration (check that your promo code is still valid)'\n : 'Could not create registration'\n )\n ) {\n return;\n }\n\n const registration = registrationResponse.data?.createRegistration;\n // Prefer the server-computed totalAmount (source of truth once a promo\n // discount was applied); fall back to the client preview for a free\n // registration where totalAmount comes back null.\n const serverTotal = registration?.totalAmount != null ? Number(registration.totalAmount) : total;\n setConfirmation({\n attendeeName: resolvedAttendeeName || 'Attendee',\n eventName: selectedEvent?.name ?? 'Event',\n ticketName: selectedTicket?.name ?? 'Ticket',\n quantity: qty,\n status: registration?.status ?? 'CONFIRMED',\n subtotal,\n discount: Math.max(subtotal - serverTotal, 0),\n total: serverTotal,\n currency,\n promoCode: appliedPromo?.code ?? null,\n free: !hasPositiveAmount,\n });\n notify.success('Registration confirmed', resolvedAttendeeName || undefined);\n } catch (error) {\n notify.error('Could not register attendee', describeError(error));\n }\n };\n\n if (confirmation) {\n return (\n <div className=\"mx-auto max-w-2xl space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/registration')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Registration\n </Button>\n </div>\n <GlassCard treatment=\"glass\" glow className=\"p-8 text-center\">\n <div className=\"mx-auto flex h-14 w-14 items-center justify-center rounded-full bg-status-success-bg-subtle\">\n <CheckCircle2 className=\"h-8 w-8 text-status-success-text\" aria-hidden=\"true\" />\n </div>\n <h1 className=\"mt-4 text-2xl font-bold text-text-primary\">Registration confirmed</h1>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {confirmation.attendeeName} is registered for {confirmation.eventName}.\n </p>\n\n <dl className=\"mx-auto mt-6 max-w-sm space-y-2 rounded-card border border-border-seam bg-bg-surface p-4 text-left text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Ticket</dt>\n <dd className=\"font-medium text-text-primary\">\n {confirmation.ticketName}\n {confirmation.quantity > 1 ? ` × ${confirmation.quantity}` : ''}\n </dd>\n </div>\n {!confirmation.free ? (\n <>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Subtotal</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatMoney(confirmation.subtotal, confirmation.currency)}\n </dd>\n </div>\n {confirmation.discount > 0 ? (\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">\n Promo{confirmation.promoCode ? ` · ${confirmation.promoCode}` : ''}\n </dt>\n <dd className=\"tabular-nums text-status-success-text\">\n −{formatMoney(confirmation.discount, confirmation.currency)}\n </dd>\n </div>\n ) : null}\n </>\n ) : null}\n <div className=\"flex justify-between border-t border-border-seam pt-2\">\n <dt className=\"font-semibold text-text-primary\">Total</dt>\n <dd className=\"font-bold tabular-nums text-text-primary\">\n {confirmation.free ? 'Free' : formatMoney(confirmation.total, confirmation.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">Status</dt>\n <dd className=\"font-medium text-text-primary\">{confirmation.status}</dd>\n </div>\n </dl>\n {!confirmation.free ? (\n <p className=\"mt-3 text-xs text-text-muted\">\n Final pricing and payment are settled by the billing service.\n </p>\n ) : null}\n\n <div className=\"mt-8 flex flex-col justify-center gap-3 sm:flex-row\">\n <Button type=\"button\" variant=\"outline\" onClick={() => navigate('/registration')}>\n Back to Registrations\n </Button>\n <Button\n type=\"button\"\n onClick={() => {\n setConfirmation(null);\n resetAll();\n }}\n >\n Register another\n </Button>\n </div>\n </GlassCard>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => navigate('/registration')}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Registration\n </Button>\n <h1 className=\"mt-3 text-2xl font-bold text-text-primary\">\n <GradientText>Register Attendee</GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Walk through the event, ticket and attendee in a few quick steps.\n </p>\n </div>\n\n <PagePurpose>\n Register a person for an event against a ticket type. Pick the event and ticket, choose an existing attendee or\n add a new one, apply a promo code if they have one, then confirm. The order summary previews the price — final\n pricing and payment are handled by the billing service.\n </PagePurpose>\n\n <Stepper steps={STEPS} active={step} onStepClick={goToStep} />\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1fr)_20rem]\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5 sm:p-6\">\n {/* STEP 0 — EVENT */}\n {step === 0 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Which event?</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Choose the event this attendee is signing up for.</p>\n </div>\n {eventsLoading ? (\n <p className=\"text-sm text-text-muted\">Loading events…</p>\n ) : events.length === 0 ? (\n <div className=\"rounded-card border border-dashed border-border-default p-6 text-center text-sm text-text-secondary\">\n No events yet.{' '}\n <button\n type=\"button\"\n className=\"font-medium text-text-link underline-offset-2 hover:underline\"\n onClick={() => navigate('/events/create')}\n >\n Create an event\n </button>{' '}\n first.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n {events.map((eventItem) => {\n const selected = eventItem.id === eventId;\n return (\n <button\n key={eventItem.id}\n type=\"button\"\n onClick={() => onEventChange(eventItem.id)}\n aria-pressed={selected}\n className={`flex items-center gap-3 rounded-card border p-4 text-left transition-colors ${\n selected\n ? 'border-action-primary-border bg-accent-wash'\n : 'border-border-seam bg-bg-surface hover:border-border-strong'\n }`}\n >\n <span\n className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-input ${\n selected ? 'bg-action-primary-bg text-action-primary-text' : 'bg-bg-sunken text-text-muted'\n }`}\n >\n <CalendarDays className=\"h-5 w-5\" aria-hidden=\"true\" />\n </span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium text-text-primary\">\n {eventItem.name}\n </span>\n {selected ? (\n <Check className=\"h-4 w-4 shrink-0 text-action-primary-bg\" aria-hidden=\"true\" />\n ) : null}\n </button>\n );\n })}\n </div>\n )}\n </div>\n ) : null}\n\n {/* STEP 1 — TICKET */}\n {step === 1 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Ticket type</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Pick the ticket and how many they need.</p>\n </div>\n {ticketsLoading ? (\n <p className=\"text-sm text-text-muted\">Loading tickets…</p>\n ) : tickets.length === 0 ? (\n <div className=\"rounded-card border border-dashed border-border-default p-6 text-center text-sm text-text-secondary\">\n This event has no active ticket types.\n </div>\n ) : (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-3\">\n {tickets.map((ticket) => {\n const selected = ticket.id === ticketTypeId;\n const cap = ticket.capacity ?? null;\n const sold = ticket.soldCount ?? 0;\n const pct = cap && cap > 0 ? Math.min(100, Math.round((sold / cap) * 100)) : null;\n const soldOut = cap != null && sold >= cap;\n return (\n <button\n key={ticket.id}\n type=\"button\"\n disabled={soldOut && !selected}\n onClick={() => setTicketTypeId(ticket.id)}\n aria-pressed={selected}\n className={`flex flex-col gap-3 rounded-card border p-4 text-left transition-colors disabled:cursor-not-allowed disabled:opacity-60 ${\n selected\n ? 'border-action-primary-border bg-accent-wash ring-1 ring-border-focus'\n : 'border-border-seam bg-bg-surface hover:border-border-strong'\n }`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <span className=\"text-sm font-semibold text-text-primary\">{ticket.name}</span>\n {selected ? (\n <Check className=\"h-4 w-4 shrink-0 text-action-primary-bg\" aria-hidden=\"true\" />\n ) : (\n <Ticket className=\"h-4 w-4 shrink-0 text-text-muted\" aria-hidden=\"true\" />\n )}\n </div>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {Number(ticket.price) > 0 ? formatMoney(Number(ticket.price), ticket.currency) : 'Free'}\n </span>\n {cap != null ? (\n <div className=\"space-y-1\">\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-full rounded-full bg-action-primary-bg\"\n style={{ width: `${pct ?? 0}%` }}\n />\n </div>\n <span className=\"text-xs text-text-muted\">\n {soldOut ? 'Sold out' : `${sold} / ${cap} sold`}\n </span>\n </div>\n ) : (\n <span className=\"text-xs text-text-muted\">{sold} sold</span>\n )}\n </button>\n );\n })}\n </div>\n )}\n\n <div className=\"flex flex-wrap items-end gap-4 border-t border-border-seam pt-4\">\n <div className=\"space-y-1\">\n <span className=\"text-sm font-medium text-text-primary\">Quantity</span>\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Decrease quantity\"\n disabled={qty <= 1}\n onClick={() => setQuantity((value) => Math.max(1, value - 1))}\n >\n <Minus className=\"h-4 w-4\" />\n </Button>\n <span className=\"w-10 text-center text-base font-semibold tabular-nums text-text-primary\">\n {qty}\n </span>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Increase quantity\"\n onClick={() => setQuantity((value) => value + 1)}\n >\n <Plus className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </div>\n </div>\n ) : null}\n\n {/* STEP 2 — ATTENDEE */}\n {step === 2 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Attendee information</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Add someone new or pick an existing attendee.</p>\n </div>\n\n <div className=\"inline-flex rounded-input border border-border-seam bg-bg-sunken p-1\">\n <button\n type=\"button\"\n onClick={() => setAttendeeMode('new')}\n className={`rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors ${\n attendeeMode === 'new'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n New attendee\n </button>\n <button\n type=\"button\"\n onClick={() => setAttendeeMode('existing')}\n disabled={attendees.length === 0}\n className={`rounded-[calc(var(--radius-input)-2px)] px-3 py-1.5 text-sm font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${\n attendeeMode === 'existing'\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n Existing attendee\n </button>\n </div>\n\n {attendeeMode === 'existing' ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Attendee</span>\n <Select value={attendeeId} onValueChange={setAttendeeId}>\n <SelectTrigger aria-label=\"Attendee\">\n <SelectValue placeholder=\"Select an attendee\" />\n </SelectTrigger>\n <SelectContent>\n {attendees.map((attendee) => (\n <SelectItem key={attendee.id} value={attendee.id}>\n {attendee.fullName} · {attendee.email}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </label>\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Full name</span>\n <Input\n value={fullName}\n onChange={(e) => setFullName(e.target.value)}\n placeholder=\"Enter full name\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Email</span>\n <Input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"Enter email address\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Company</span>\n <Input\n value={company}\n onChange={(e) => setCompany(e.target.value)}\n placeholder=\"Enter company name\"\n />\n </label>\n <label className=\"space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Phone</span>\n <Input value={phone} onChange={(e) => setPhone(e.target.value)} placeholder=\"Optional\" />\n </label>\n </div>\n )}\n\n {/* Promo code */}\n <div className=\"space-y-2 border-t border-border-seam pt-4\">\n <span className=\"text-sm font-medium text-text-primary\">Promo code (optional)</span>\n <div className=\"flex flex-col gap-2 sm:flex-row\">\n <Input\n value={promoInput}\n onChange={(e) => {\n setPromoInput(e.target.value);\n setPromoError('');\n }}\n placeholder=\"Enter promo code\"\n className=\"sm:flex-1\"\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n applyPromo();\n }\n }}\n />\n {appliedPromo ? (\n <Button type=\"button\" variant=\"outline\" onClick={clearPromo}>\n Remove\n </Button>\n ) : (\n <Button type=\"button\" variant=\"outline\" onClick={applyPromo} disabled={!promoInput.trim()}>\n Apply\n </Button>\n )}\n </div>\n {appliedPromo ? (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2.5 py-0.5 text-xs font-medium text-status-success-text\">\n <BadgePercent className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {describeDiscount(appliedPromo.discountType, appliedPromo.discountValue, currency)} applied\n </span>\n ) : promoError ? (\n <span className=\"text-xs text-status-error-text\">{promoError}</span>\n ) : activePromos.length > 0 ? (\n <div className=\"flex flex-wrap items-center gap-1.5 text-xs text-text-muted\">\n <span>Available:</span>\n {activePromos.slice(0, 4).map((promo) => (\n <button\n key={promo.id}\n type=\"button\"\n onClick={() => {\n setPromoInput(promo.code);\n setAppliedPromo(promo);\n setPromoError('');\n }}\n className=\"rounded-full border border-border-seam bg-bg-surface px-2 py-0.5 font-medium text-text-secondary hover:border-border-strong hover:text-text-primary\"\n >\n {promo.code}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n\n {/* STEP 3 — CONFIRM */}\n {step === 3 ? (\n <div className=\"space-y-4\">\n <div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Review & confirm</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">Double-check the details before registering.</p>\n </div>\n <dl className=\"divide-y divide-border-seam rounded-card border border-border-seam bg-bg-surface text-sm\">\n <div className=\"flex items-center gap-3 p-3\">\n <CalendarDays className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Event</dt>\n <dd className=\"ml-auto font-medium text-text-primary\">{selectedEvent?.name ?? '—'}</dd>\n </div>\n <div className=\"flex items-center gap-3 p-3\">\n <Ticket className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Ticket</dt>\n <dd className=\"ml-auto font-medium text-text-primary\">\n {selectedTicket?.name ?? '—'}\n {qty > 1 ? ` × ${qty}` : ''}\n </dd>\n </div>\n <div className=\"flex items-center gap-3 p-3\">\n <UserRound className=\"h-4 w-4 text-text-muted\" aria-hidden=\"true\" />\n <dt className=\"text-text-secondary\">Attendee</dt>\n <dd className=\"ml-auto text-right font-medium text-text-primary\">\n {attendeeName || '—'}\n <span className=\"block text-xs font-normal text-text-secondary\">\n {attendeeMode === 'existing' ? selectedAttendee?.email : email.trim()}\n </span>\n </dd>\n </div>\n </dl>\n\n {hasPositiveAmount ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"font-medium text-text-primary\">Billing account ID (optional)</span>\n <Input\n value={billingAccountId}\n onChange={(e) => setBillingAccountId(e.target.value)}\n placeholder=\"Attach an existing billing account\"\n />\n <span className=\"text-xs text-text-secondary\">\n When provided, the charge is attached to this billing account.\n </span>\n </label>\n ) : null}\n </div>\n ) : null}\n\n {/* Wizard controls */}\n <div className=\"mt-6 flex items-center justify-between gap-3 border-t border-border-seam pt-4\">\n <Button type=\"button\" variant=\"ghost\" onClick={goBack} disabled={step === 0 || saving}>\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </Button>\n {step < STEPS.length - 1 ? (\n <Button type=\"button\" onClick={goNext}>\n Continue\n <ArrowRight className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button type=\"button\" onClick={onConfirm} disabled={saving}>\n <Ticket className=\"h-4 w-4\" />\n {saving ? 'Registering…' : 'Confirm registration'}\n </Button>\n )}\n </div>\n </GlassCard>\n\n {/* ORDER SUMMARY */}\n <GlassCard treatment=\"glass\" className=\"h-fit p-5 lg:sticky lg:top-6\">\n <h2 className=\"text-base font-semibold text-text-primary\">Order summary</h2>\n {selectedTicket ? (\n <div className=\"mt-4 space-y-3 text-sm\">\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"min-w-0 text-text-secondary\">\n {selectedEvent?.name ? `${selectedEvent.name} — ` : ''}\n {selectedTicket.name}\n {qty > 1 ? <span className=\"text-text-muted\"> × {qty}</span> : null}\n </span>\n <span className=\"shrink-0 tabular-nums text-text-primary\">\n {subtotal > 0 ? formatMoney(subtotal, currency) : 'Free'}\n </span>\n </div>\n {appliedPromo && discount > 0 ? (\n <div className=\"flex items-start justify-between gap-3\">\n <span className=\"text-text-secondary\">Promo · {appliedPromo.code}</span>\n <span className=\"shrink-0 tabular-nums text-status-success-text\">\n −{formatMoney(discount, currency)}\n </span>\n </div>\n ) : null}\n <div className=\"flex items-center justify-between border-t border-border-seam pt-3\">\n <span className=\"font-semibold text-text-primary\">Total</span>\n <span className=\"text-lg font-bold tabular-nums text-text-primary\">\n {subtotal > 0 ? formatMoney(total, currency) : 'Free'}\n </span>\n </div>\n {subtotal > 0 ? (\n <p className=\"text-xs text-text-muted\">Final pricing & payment handled by the billing service.</p>\n ) : null}\n </div>\n ) : (\n <p className=\"mt-4 text-sm text-text-muted\">\n Pick a ticket to see the price breakdown. Your order total updates as you go.\n </p>\n )}\n </GlassCard>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { create as e } from "zustand";
|
|
2
|
+
import { devtools as t, persist as n } from "zustand/middleware";
|
|
3
|
+
import { createProfileScopedStorage as r } from "@burdenoff/fe-libs/shared/utils";
|
|
4
|
+
e()(t(n((e) => ({
|
|
5
|
+
sidebarCollapsed: !1,
|
|
6
|
+
toggleSidebar: () => e((e) => ({ sidebarCollapsed: !e.sidebarCollapsed })),
|
|
7
|
+
activeModule: "dashboard",
|
|
8
|
+
setActiveModule: (t) => e({ activeModule: t })
|
|
9
|
+
}), {
|
|
10
|
+
name: "eventfullymanaged-store",
|
|
11
|
+
storage: r()
|
|
12
|
+
}), { name: "eventfullymanaged-store" }));
|
|
13
|
+
//#endregion
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=eventfullyManagedStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eventfullyManagedStore.js","names":[],"sources":["../../../src/eventfullymanaged/store/eventfullyManagedStore.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { devtools, persist } from 'zustand/middleware';\nimport { createProfileScopedStorage } from '@burdenoff/fe-libs/shared/utils';\n\ninterface EventfullyManagedState {\n sidebarCollapsed: boolean;\n toggleSidebar: () => void;\n activeModule: string;\n setActiveModule: (module: string) => void;\n}\n\nexport const useEventfullyManagedStore = create<EventfullyManagedState>()(\n devtools(\n persist(\n (set) => ({\n sidebarCollapsed: false,\n toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),\n activeModule: 'dashboard',\n setActiveModule: (module) => set({ activeModule: module }),\n }),\n { name: 'eventfullymanaged-store', storage: createProfileScopedStorage() }\n ),\n { name: 'eventfullymanaged-store' }\n )\n);\n"],"mappings":";;;AAWyC,GAAgC,CACvE,EACE,GACG,OAAS;CACR,kBAAkB;CAClB,qBAAqB,GAAK,OAAW,EAAE,kBAAkB,CAAC,EAAM,kBAAkB,EAAE;CACpF,cAAc;CACd,kBAAkB,MAAW,EAAI,EAAE,cAAc,GAAQ,CAAC;CAC3D,GACD;CAAE,MAAM;CAA2B,SAAS,GAA4B;CAAE,CAC3E,EACD,EAAE,MAAM,2BAA2B,CACpC,CACF"}
|