@burdenoff/microfe-atheletebridge 2026.1031.3 → 2026.1102.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/atheletebridge/AthleteBridgeRoot.d.ts.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoot.js +63 -47
- package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoutes.d.ts.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoutes.js +62 -6
- package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
- package/dist/atheletebridge/components/StatusBadge.d.ts.map +1 -1
- package/dist/atheletebridge/components/StatusBadge.js +13 -1
- package/dist/atheletebridge/components/StatusBadge.js.map +1 -1
- package/dist/atheletebridge/components/registration/PaymentSummaryPanel.d.ts +6 -0
- package/dist/atheletebridge/components/registration/PaymentSummaryPanel.d.ts.map +1 -0
- package/dist/atheletebridge/components/registration/PaymentSummaryPanel.js +104 -0
- package/dist/atheletebridge/components/registration/PaymentSummaryPanel.js.map +1 -0
- package/dist/atheletebridge/components/registration/RegistrationEntryFields.d.ts +15 -0
- package/dist/atheletebridge/components/registration/RegistrationEntryFields.d.ts.map +1 -0
- package/dist/atheletebridge/components/registration/RegistrationEntryFields.js +236 -0
- package/dist/atheletebridge/components/registration/RegistrationEntryFields.js.map +1 -0
- package/dist/atheletebridge/components/registration/entryRules.d.ts +23 -0
- package/dist/atheletebridge/components/registration/entryRules.d.ts.map +1 -0
- package/dist/atheletebridge/components/registration/entryRules.js +29 -0
- package/dist/atheletebridge/components/registration/entryRules.js.map +1 -0
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts +1 -0
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/hooks/useRegistrationApi.d.ts +54 -0
- package/dist/atheletebridge/hooks/useRegistrationApi.d.ts.map +1 -0
- package/dist/atheletebridge/hooks/useRegistrationApi.js +265 -0
- package/dist/atheletebridge/hooks/useRegistrationApi.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/MyRegistrationsPage.d.ts +10 -0
- package/dist/atheletebridge/pages/registrations/MyRegistrationsPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/MyRegistrationsPage.js +89 -0
- package/dist/atheletebridge/pages/registrations/MyRegistrationsPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RecordRegistrationPage.d.ts +10 -0
- package/dist/atheletebridge/pages/registrations/RecordRegistrationPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RecordRegistrationPage.js +94 -0
- package/dist/atheletebridge/pages/registrations/RecordRegistrationPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegisterPage.d.ts +11 -0
- package/dist/atheletebridge/pages/registrations/RegisterPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegisterPage.js +160 -0
- package/dist/atheletebridge/pages/registrations/RegisterPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormBuilderPage.d.ts +10 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormBuilderPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormBuilderPage.js +602 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormBuilderPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormDetailPage.d.ts +9 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormDetailPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormDetailPage.js +317 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormDetailPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormsListPage.d.ts +9 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormsListPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormsListPage.js +127 -0
- package/dist/atheletebridge/pages/registrations/RegistrationFormsListPage.js.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationSubmissionPage.d.ts +11 -0
- package/dist/atheletebridge/pages/registrations/RegistrationSubmissionPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/registrations/RegistrationSubmissionPage.js +411 -0
- package/dist/atheletebridge/pages/registrations/RegistrationSubmissionPage.js.map +1 -0
- package/dist/atheletebridge/types/registration.d.ts +220 -0
- package/dist/atheletebridge/types/registration.d.ts.map +1 -0
- package/dist/atheletebridge/utils/money.d.ts +22 -0
- package/dist/atheletebridge/utils/money.d.ts.map +1 -0
- package/dist/atheletebridge/utils/money.js +38 -0
- package/dist/atheletebridge/utils/money.js.map +1 -0
- package/dist/atheletebridge/utils/registration.d.ts +17 -0
- package/dist/atheletebridge/utils/registration.d.ts.map +1 -0
- package/dist/atheletebridge/utils/registration.js +25 -0
- package/dist/atheletebridge/utils/registration.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { useAthleteBridge as e } from "../context/AthleteBridgeContext.js";
|
|
2
|
+
import "../context/index.js";
|
|
3
|
+
import { athQuery as t } from "./useAthleteBridgeApi.js";
|
|
4
|
+
import { useMutation as n, useQuery as r, useQueryClient as i } from "@tanstack/react-query";
|
|
5
|
+
//#region src/atheletebridge/hooks/useRegistrationApi.ts
|
|
6
|
+
var a = ["atheletebridge", "registration"], o = "id key label fieldType required options helpText position", s = "id name description amount feeType position", c = `
|
|
7
|
+
id workspaceId title description season teamId programId slug status currency
|
|
8
|
+
opensAt closesAt maxSubmissions waiverText publishedAt closedAt isOpen
|
|
9
|
+
submissionCount createdAt updatedAt
|
|
10
|
+
fields { ${o} }
|
|
11
|
+
fees { ${s} }
|
|
12
|
+
`, l = "\n id workspaceId formId formTitle source submittedByUserId participantName\n participantUserId contactName contactEmail contactPhone answers selectedFeeIds\n status paymentStatus amountDue amountPaid amountOutstanding currency\n waiverAcceptedAt reviewNotes reviewedAt submittedAt createdAt updatedAt\n", u = "\n id submissionId amount refundedAmount netAmount currency method status\n reference note receivedAt voidedAt voidReason refundedAt refundReason\n createdBy createdAt\n", d = "\n formId submissionCount acceptedCount notRequiredCount unpaidCount\n partiallyPaidCount paidCount refundedCount\n totals { currency amountDue amountCollected amountRefunded amountOutstanding }\n", f = `
|
|
13
|
+
id slug title description season currency opensAt closesAt waiverText isOpen
|
|
14
|
+
spotsRemaining
|
|
15
|
+
fields { ${o} }
|
|
16
|
+
fees { ${s} }
|
|
17
|
+
`, p = "\n id formId formTitle formSlug participantName status paymentStatus amountDue\n amountPaid amountOutstanding currency submittedAt\n", m = () => {
|
|
18
|
+
let e = i();
|
|
19
|
+
return () => e.invalidateQueries({ queryKey: a });
|
|
20
|
+
}, h = (n = {}) => {
|
|
21
|
+
let { apiGatewayUrl: i, workspaceId: o } = e();
|
|
22
|
+
return r({
|
|
23
|
+
queryKey: [
|
|
24
|
+
...a,
|
|
25
|
+
o ?? null,
|
|
26
|
+
"forms",
|
|
27
|
+
n
|
|
28
|
+
],
|
|
29
|
+
queryFn: async () => (await t(`query AthListRegistrationForms($status: AthRegistrationFormStatus, $season: String, $pagination: PaginationInput) {
|
|
30
|
+
athListRegistrationForms(status: $status, season: $season, pagination: $pagination) {
|
|
31
|
+
items { ${c} }
|
|
32
|
+
pageInfo { cursor hasMore }
|
|
33
|
+
}
|
|
34
|
+
}`, { ...n }, i)).athListRegistrationForms
|
|
35
|
+
});
|
|
36
|
+
}, g = (n) => {
|
|
37
|
+
let { apiGatewayUrl: i, workspaceId: o } = e();
|
|
38
|
+
return r({
|
|
39
|
+
queryKey: [
|
|
40
|
+
...a,
|
|
41
|
+
o ?? null,
|
|
42
|
+
"form",
|
|
43
|
+
n
|
|
44
|
+
],
|
|
45
|
+
queryFn: async () => (await t(`query AthRegistrationForm($id: ID!) { athRegistrationForm(id: $id) { ${c} } }`, { id: n }, i)).athRegistrationForm,
|
|
46
|
+
enabled: !!n
|
|
47
|
+
});
|
|
48
|
+
}, _ = () => {
|
|
49
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
50
|
+
return n({
|
|
51
|
+
mutationFn: async (e) => (await t(`mutation AthCreateRegistrationForm($input: AthCreateRegistrationFormInput!) {
|
|
52
|
+
athCreateRegistrationForm(input: $input) { ${c} }
|
|
53
|
+
}`, { input: e }, r)).athCreateRegistrationForm,
|
|
54
|
+
onSuccess: () => void i()
|
|
55
|
+
});
|
|
56
|
+
}, v = () => {
|
|
57
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
58
|
+
return n({
|
|
59
|
+
mutationFn: async ({ id: e, input: n }) => (await t(`mutation AthUpdateRegistrationForm($id: ID!, $input: AthUpdateRegistrationFormInput!) {
|
|
60
|
+
athUpdateRegistrationForm(id: $id, input: $input) { ${c} }
|
|
61
|
+
}`, {
|
|
62
|
+
id: e,
|
|
63
|
+
input: n
|
|
64
|
+
}, r)).athUpdateRegistrationForm,
|
|
65
|
+
onSuccess: () => void i()
|
|
66
|
+
});
|
|
67
|
+
}, y = {
|
|
68
|
+
publish: {
|
|
69
|
+
field: "athPublishRegistrationForm",
|
|
70
|
+
selection: `{ ${c} }`
|
|
71
|
+
},
|
|
72
|
+
close: {
|
|
73
|
+
field: "athCloseRegistrationForm",
|
|
74
|
+
selection: `{ ${c} }`
|
|
75
|
+
},
|
|
76
|
+
archive: {
|
|
77
|
+
field: "athArchiveRegistrationForm",
|
|
78
|
+
selection: ""
|
|
79
|
+
}
|
|
80
|
+
}, b = () => {
|
|
81
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
82
|
+
return n({
|
|
83
|
+
mutationFn: async ({ id: e, action: n }) => {
|
|
84
|
+
let { field: i, selection: a } = y[n];
|
|
85
|
+
return await t(`mutation AthRegistrationFormLifecycle($id: ID!) { ${i}(id: $id) ${a} }`, { id: e }, r), n;
|
|
86
|
+
},
|
|
87
|
+
onSuccess: () => void i()
|
|
88
|
+
});
|
|
89
|
+
}, x = (n, i = !0) => {
|
|
90
|
+
let { apiGatewayUrl: o, workspaceId: s } = e();
|
|
91
|
+
return r({
|
|
92
|
+
queryKey: [
|
|
93
|
+
...a,
|
|
94
|
+
s ?? null,
|
|
95
|
+
"submissions",
|
|
96
|
+
n
|
|
97
|
+
],
|
|
98
|
+
queryFn: async () => (await t(`query AthListRegistrationSubmissions(
|
|
99
|
+
$formId: ID
|
|
100
|
+
$status: AthRegistrationSubmissionStatus
|
|
101
|
+
$paymentStatus: AthRegistrationPaymentStatus
|
|
102
|
+
$pagination: PaginationInput
|
|
103
|
+
) {
|
|
104
|
+
athListRegistrationSubmissions(
|
|
105
|
+
formId: $formId
|
|
106
|
+
status: $status
|
|
107
|
+
paymentStatus: $paymentStatus
|
|
108
|
+
pagination: $pagination
|
|
109
|
+
) {
|
|
110
|
+
items { ${l} }
|
|
111
|
+
pageInfo { cursor hasMore }
|
|
112
|
+
}
|
|
113
|
+
}`, { ...n }, o)).athListRegistrationSubmissions,
|
|
114
|
+
enabled: i
|
|
115
|
+
});
|
|
116
|
+
}, S = (n) => {
|
|
117
|
+
let { apiGatewayUrl: i, workspaceId: o } = e();
|
|
118
|
+
return r({
|
|
119
|
+
queryKey: [
|
|
120
|
+
...a,
|
|
121
|
+
o ?? null,
|
|
122
|
+
"submission",
|
|
123
|
+
n
|
|
124
|
+
],
|
|
125
|
+
queryFn: async () => (await t(`query AthRegistrationSubmission($id: ID!) {
|
|
126
|
+
athRegistrationSubmission(id: $id) { ${l} }
|
|
127
|
+
}`, { id: n }, i)).athRegistrationSubmission,
|
|
128
|
+
enabled: !!n
|
|
129
|
+
});
|
|
130
|
+
}, C = () => {
|
|
131
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
132
|
+
return n({
|
|
133
|
+
mutationFn: async (e) => (await t(`mutation AthRecordRegistration($input: AthRecordRegistrationInput!) {
|
|
134
|
+
athRecordRegistration(input: $input) { ${l} }
|
|
135
|
+
}`, { input: e }, r)).athRecordRegistration,
|
|
136
|
+
onSuccess: () => void i()
|
|
137
|
+
});
|
|
138
|
+
}, w = () => {
|
|
139
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
140
|
+
return n({
|
|
141
|
+
mutationFn: async ({ id: e, decision: n, notes: i }) => (await t(`mutation AthReviewRegistrationSubmission($id: ID!, $input: AthReviewRegistrationInput!) {
|
|
142
|
+
athReviewRegistrationSubmission(id: $id, input: $input) { ${l} }
|
|
143
|
+
}`, {
|
|
144
|
+
id: e,
|
|
145
|
+
input: {
|
|
146
|
+
decision: n,
|
|
147
|
+
notes: i
|
|
148
|
+
}
|
|
149
|
+
}, r)).athReviewRegistrationSubmission,
|
|
150
|
+
onSuccess: () => void i()
|
|
151
|
+
});
|
|
152
|
+
}, T = (n) => {
|
|
153
|
+
let { apiGatewayUrl: i, workspaceId: o } = e();
|
|
154
|
+
return r({
|
|
155
|
+
queryKey: [
|
|
156
|
+
...a,
|
|
157
|
+
o ?? null,
|
|
158
|
+
"payments",
|
|
159
|
+
n
|
|
160
|
+
],
|
|
161
|
+
queryFn: async () => (await t(`query AthListRegistrationPayments($submissionId: ID!) {
|
|
162
|
+
athListRegistrationPayments(submissionId: $submissionId) { ${u} }
|
|
163
|
+
}`, { submissionId: n }, i)).athListRegistrationPayments,
|
|
164
|
+
enabled: !!n,
|
|
165
|
+
retry: !1
|
|
166
|
+
});
|
|
167
|
+
}, E = (n) => {
|
|
168
|
+
let { apiGatewayUrl: i, workspaceId: o } = e();
|
|
169
|
+
return r({
|
|
170
|
+
queryKey: [
|
|
171
|
+
...a,
|
|
172
|
+
o ?? null,
|
|
173
|
+
"summary",
|
|
174
|
+
n ?? null
|
|
175
|
+
],
|
|
176
|
+
queryFn: async () => (await t(`query AthRegistrationPaymentSummary($formId: ID) {
|
|
177
|
+
athRegistrationPaymentSummary(formId: $formId) { ${d} }
|
|
178
|
+
}`, { formId: n ?? null }, i)).athRegistrationPaymentSummary,
|
|
179
|
+
retry: !1
|
|
180
|
+
});
|
|
181
|
+
}, D = () => {
|
|
182
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
183
|
+
return n({
|
|
184
|
+
mutationFn: async (e) => (await t(`mutation AthRecordRegistrationPayment($input: AthRecordRegistrationPaymentInput!) {
|
|
185
|
+
athRecordRegistrationPayment(input: $input) { ${u} }
|
|
186
|
+
}`, { input: e }, r)).athRecordRegistrationPayment,
|
|
187
|
+
onSuccess: () => void i()
|
|
188
|
+
});
|
|
189
|
+
}, O = () => {
|
|
190
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
191
|
+
return n({
|
|
192
|
+
mutationFn: async ({ id: e, reason: n }) => (await t(`mutation AthVoidRegistrationPayment($id: ID!, $reason: String!) {
|
|
193
|
+
athVoidRegistrationPayment(id: $id, reason: $reason) { ${u} }
|
|
194
|
+
}`, {
|
|
195
|
+
id: e,
|
|
196
|
+
reason: n
|
|
197
|
+
}, r)).athVoidRegistrationPayment,
|
|
198
|
+
onSuccess: () => void i()
|
|
199
|
+
});
|
|
200
|
+
}, k = () => {
|
|
201
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
202
|
+
return n({
|
|
203
|
+
mutationFn: async ({ id: e, amount: n, reason: i }) => (await t(`mutation AthRefundRegistrationPayment($id: ID!, $input: AthRefundRegistrationPaymentInput!) {
|
|
204
|
+
athRefundRegistrationPayment(id: $id, input: $input) { ${u} }
|
|
205
|
+
}`, {
|
|
206
|
+
id: e,
|
|
207
|
+
input: {
|
|
208
|
+
amount: n,
|
|
209
|
+
reason: i
|
|
210
|
+
}
|
|
211
|
+
}, r)).athRefundRegistrationPayment,
|
|
212
|
+
onSuccess: () => void i()
|
|
213
|
+
});
|
|
214
|
+
}, A = (n) => {
|
|
215
|
+
let { apiGatewayUrl: i } = e();
|
|
216
|
+
return r({
|
|
217
|
+
queryKey: [
|
|
218
|
+
...a,
|
|
219
|
+
"public",
|
|
220
|
+
n
|
|
221
|
+
],
|
|
222
|
+
queryFn: async () => (await t(`query AthRegistrationFormBySlug($slug: String!) {
|
|
223
|
+
athRegistrationFormBySlug(slug: $slug) { ${f} }
|
|
224
|
+
}`, { slug: n }, i)).athRegistrationFormBySlug,
|
|
225
|
+
enabled: !!n
|
|
226
|
+
});
|
|
227
|
+
}, j = () => {
|
|
228
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
229
|
+
return n({
|
|
230
|
+
mutationFn: async ({ slug: e, input: n }) => (await t(`mutation AthSubmitRegistration($slug: String!, $input: AthSubmitRegistrationInput!) {
|
|
231
|
+
athSubmitRegistration(slug: $slug, input: $input) { ${p} }
|
|
232
|
+
}`, {
|
|
233
|
+
slug: e,
|
|
234
|
+
input: n
|
|
235
|
+
}, r)).athSubmitRegistration,
|
|
236
|
+
onSuccess: () => void i()
|
|
237
|
+
});
|
|
238
|
+
}, M = (n) => {
|
|
239
|
+
let { apiGatewayUrl: i } = e();
|
|
240
|
+
return r({
|
|
241
|
+
queryKey: [
|
|
242
|
+
...a,
|
|
243
|
+
"mine",
|
|
244
|
+
n ?? null
|
|
245
|
+
],
|
|
246
|
+
queryFn: async () => (await t(`query AthMyRegistrations($pagination: PaginationInput) {
|
|
247
|
+
athMyRegistrations(pagination: $pagination) {
|
|
248
|
+
items { ${p} }
|
|
249
|
+
pageInfo { cursor hasMore }
|
|
250
|
+
}
|
|
251
|
+
}`, { pagination: n ?? null }, i)).athMyRegistrations
|
|
252
|
+
});
|
|
253
|
+
}, N = () => {
|
|
254
|
+
let { apiGatewayUrl: r } = e(), i = m();
|
|
255
|
+
return n({
|
|
256
|
+
mutationFn: async (e) => (await t(`mutation AthWithdrawMyRegistration($id: ID!) {
|
|
257
|
+
athWithdrawMyRegistration(id: $id) { ${p} }
|
|
258
|
+
}`, { id: e }, r)).athWithdrawMyRegistration,
|
|
259
|
+
onSuccess: () => void i()
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
//#endregion
|
|
263
|
+
export { _ as useCreateRegistrationForm, M as useMyRegistrations, A as usePublicRegistrationForm, C as useRecordRegistration, D as useRecordRegistrationPayment, k as useRefundRegistrationPayment, g as useRegistrationForm, b as useRegistrationFormLifecycle, h as useRegistrationForms, E as useRegistrationPaymentSummary, T as useRegistrationPayments, S as useRegistrationSubmission, x as useRegistrationSubmissions, w as useReviewRegistration, j as useSubmitRegistration, v as useUpdateRegistrationForm, O as useVoidRegistrationPayment, N as useWithdrawMyRegistration };
|
|
264
|
+
|
|
265
|
+
//# sourceMappingURL=useRegistrationApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRegistrationApi.js","names":[],"sources":["../../../src/atheletebridge/hooks/useRegistrationApi.ts"],"sourcesContent":["/**\n * Club registration & payments API hooks (BOFF-4135).\n *\n * react-query wrappers over the `wspace-atheletebridge-svc` registration\n * module, reached through the workspace gateway like every other hook in this\n * package. Staff hooks are gated by `atheletebridge-registration` /\n * `atheletebridge-registration-payment`; the family-facing hooks\n * (`usePublicRegistrationForm`, `useSubmitRegistration`, `useMyRegistrations`,\n * `useWithdrawMyRegistration`) are self-scoped and work for any signed-in user.\n *\n * @module atheletebridge/hooks/registration\n */\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { useAthleteBridge } from '../context';\nimport type { PaginationInput } from '../types';\nimport type {\n AthCreateRegistrationFormInput,\n AthMyRegistration,\n AthMyRegistrationConnection,\n AthPublicRegistrationForm,\n AthRecordRegistrationInput,\n AthRecordRegistrationPaymentInput,\n AthRegistrationDecision,\n AthRegistrationEntryInput,\n AthRegistrationForm,\n AthRegistrationFormConnection,\n AthRegistrationFormStatus,\n AthRegistrationPayment,\n AthRegistrationPaymentStatus,\n AthRegistrationPaymentSummary,\n AthRegistrationSubmission,\n AthRegistrationSubmissionConnection,\n AthRegistrationSubmissionStatus,\n AthUpdateRegistrationFormInput,\n} from '../types/registration';\nimport { athQuery } from './useAthleteBridgeApi';\n\n// Workspace-scoped reads put the active workspace right after ROOT: the\n// QueryClient outlives a workspace switch, and one club's registrations or\n// ledger must never be served from cache to another club. Invalidating ROOT\n// still clears every workspace's entries.\nconst ROOT = ['atheletebridge', 'registration'] as const;\n\nconst FIELD_FIELDS = `id key label fieldType required options helpText position`;\nconst FEE_FIELDS = `id name description amount feeType position`;\n\nconst FORM_FIELDS = `\n id workspaceId title description season teamId programId slug status currency\n opensAt closesAt maxSubmissions waiverText publishedAt closedAt isOpen\n submissionCount createdAt updatedAt\n fields { ${FIELD_FIELDS} }\n fees { ${FEE_FIELDS} }\n`;\n\nconst SUBMISSION_FIELDS = `\n id workspaceId formId formTitle source submittedByUserId participantName\n participantUserId contactName contactEmail contactPhone answers selectedFeeIds\n status paymentStatus amountDue amountPaid amountOutstanding currency\n waiverAcceptedAt reviewNotes reviewedAt submittedAt createdAt updatedAt\n`;\n\nconst PAYMENT_FIELDS = `\n id submissionId amount refundedAmount netAmount currency method status\n reference note receivedAt voidedAt voidReason refundedAt refundReason\n createdBy createdAt\n`;\n\nconst SUMMARY_FIELDS = `\n formId submissionCount acceptedCount notRequiredCount unpaidCount\n partiallyPaidCount paidCount refundedCount\n totals { currency amountDue amountCollected amountRefunded amountOutstanding }\n`;\n\nconst PUBLIC_FORM_FIELDS = `\n id slug title description season currency opensAt closesAt waiverText isOpen\n spotsRemaining\n fields { ${FIELD_FIELDS} }\n fees { ${FEE_FIELDS} }\n`;\n\nconst MY_REGISTRATION_FIELDS = `\n id formId formTitle formSlug participantName status paymentStatus amountDue\n amountPaid amountOutstanding currency submittedAt\n`;\n\n/** Every registration read is invalidated together after any write. */\nconst useInvalidateRegistration = () => {\n const queryClient = useQueryClient();\n return () => queryClient.invalidateQueries({ queryKey: ROOT });\n};\n\n// ============================================================================\n// Forms (staff)\n// ============================================================================\n\nexport interface RegistrationFormFilters {\n status?: AthRegistrationFormStatus;\n season?: string;\n pagination?: PaginationInput;\n}\n\nexport const useRegistrationForms = (filters: RegistrationFormFilters = {}) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'forms', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListRegistrationForms: AthRegistrationFormConnection }>(\n `query AthListRegistrationForms($status: AthRegistrationFormStatus, $season: String, $pagination: PaginationInput) {\n athListRegistrationForms(status: $status, season: $season, pagination: $pagination) {\n items { ${FORM_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { ...filters },\n apiGatewayUrl\n );\n return result.athListRegistrationForms;\n },\n });\n};\n\nexport const useRegistrationForm = (id: string | undefined) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'form', id],\n queryFn: async () => {\n const result = await athQuery<{ athRegistrationForm: AthRegistrationForm | null }>(\n `query AthRegistrationForm($id: ID!) { athRegistrationForm(id: $id) { ${FORM_FIELDS} } }`,\n { id },\n apiGatewayUrl\n );\n return result.athRegistrationForm;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateRegistrationForm = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async (input: AthCreateRegistrationFormInput) => {\n const result = await athQuery<{ athCreateRegistrationForm: AthRegistrationForm }>(\n `mutation AthCreateRegistrationForm($input: AthCreateRegistrationFormInput!) {\n athCreateRegistrationForm(input: $input) { ${FORM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athCreateRegistrationForm;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport const useUpdateRegistrationForm = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthUpdateRegistrationFormInput }) => {\n const result = await athQuery<{ athUpdateRegistrationForm: AthRegistrationForm }>(\n `mutation AthUpdateRegistrationForm($id: ID!, $input: AthUpdateRegistrationFormInput!) {\n athUpdateRegistrationForm(id: $id, input: $input) { ${FORM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athUpdateRegistrationForm;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport type RegistrationFormLifecycleAction = 'publish' | 'close' | 'archive';\n\nconst LIFECYCLE_MUTATIONS: Record<\n RegistrationFormLifecycleAction,\n { field: string; selection: string }\n> = {\n publish: { field: 'athPublishRegistrationForm', selection: `{ ${FORM_FIELDS} }` },\n close: { field: 'athCloseRegistrationForm', selection: `{ ${FORM_FIELDS} }` },\n archive: { field: 'athArchiveRegistrationForm', selection: '' },\n};\n\nexport const useRegistrationFormLifecycle = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({ id, action }: { id: string; action: RegistrationFormLifecycleAction }) => {\n const { field, selection } = LIFECYCLE_MUTATIONS[action];\n await athQuery<Record<string, unknown>>(\n `mutation AthRegistrationFormLifecycle($id: ID!) { ${field}(id: $id) ${selection} }`,\n { id },\n apiGatewayUrl\n );\n return action;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\n// ============================================================================\n// Submissions (staff)\n// ============================================================================\n\nexport interface RegistrationSubmissionFilters {\n formId?: string;\n status?: AthRegistrationSubmissionStatus;\n paymentStatus?: AthRegistrationPaymentStatus;\n pagination?: PaginationInput;\n}\n\nexport const useRegistrationSubmissions = (\n filters: RegistrationSubmissionFilters,\n enabled = true\n) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'submissions', filters],\n queryFn: async () => {\n const result = await athQuery<{\n athListRegistrationSubmissions: AthRegistrationSubmissionConnection;\n }>(\n `query AthListRegistrationSubmissions(\n $formId: ID\n $status: AthRegistrationSubmissionStatus\n $paymentStatus: AthRegistrationPaymentStatus\n $pagination: PaginationInput\n ) {\n athListRegistrationSubmissions(\n formId: $formId\n status: $status\n paymentStatus: $paymentStatus\n pagination: $pagination\n ) {\n items { ${SUBMISSION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { ...filters },\n apiGatewayUrl\n );\n return result.athListRegistrationSubmissions;\n },\n enabled,\n });\n};\n\nexport const useRegistrationSubmission = (id: string | undefined) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'submission', id],\n queryFn: async () => {\n const result = await athQuery<{\n athRegistrationSubmission: AthRegistrationSubmission | null;\n }>(\n `query AthRegistrationSubmission($id: ID!) {\n athRegistrationSubmission(id: $id) { ${SUBMISSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athRegistrationSubmission;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useRecordRegistration = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async (input: AthRecordRegistrationInput) => {\n const result = await athQuery<{ athRecordRegistration: AthRegistrationSubmission }>(\n `mutation AthRecordRegistration($input: AthRecordRegistrationInput!) {\n athRecordRegistration(input: $input) { ${SUBMISSION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athRecordRegistration;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport const useReviewRegistration = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({\n id,\n decision,\n notes,\n }: {\n id: string;\n decision: AthRegistrationDecision;\n notes?: string;\n }) => {\n const result = await athQuery<{ athReviewRegistrationSubmission: AthRegistrationSubmission }>(\n `mutation AthReviewRegistrationSubmission($id: ID!, $input: AthReviewRegistrationInput!) {\n athReviewRegistrationSubmission(id: $id, input: $input) { ${SUBMISSION_FIELDS} }\n }`,\n { id, input: { decision, notes } },\n apiGatewayUrl\n );\n return result.athReviewRegistrationSubmission;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\n// ============================================================================\n// Payments (staff)\n// ============================================================================\n\nexport const useRegistrationPayments = (submissionId: string | undefined) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'payments', submissionId],\n queryFn: async () => {\n const result = await athQuery<{ athListRegistrationPayments: AthRegistrationPayment[] }>(\n `query AthListRegistrationPayments($submissionId: ID!) {\n athListRegistrationPayments(submissionId: $submissionId) { ${PAYMENT_FIELDS} }\n }`,\n { submissionId },\n apiGatewayUrl\n );\n return result.athListRegistrationPayments;\n },\n enabled: Boolean(submissionId),\n retry: false,\n });\n};\n\nexport const useRegistrationPaymentSummary = (formId?: string) => {\n const { apiGatewayUrl, workspaceId } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, workspaceId ?? null, 'summary', formId ?? null],\n queryFn: async () => {\n const result = await athQuery<{\n athRegistrationPaymentSummary: AthRegistrationPaymentSummary;\n }>(\n `query AthRegistrationPaymentSummary($formId: ID) {\n athRegistrationPaymentSummary(formId: $formId) { ${SUMMARY_FIELDS} }\n }`,\n { formId: formId ?? null },\n apiGatewayUrl\n );\n return result.athRegistrationPaymentSummary;\n },\n // A coach can read submissions without the payment ledger; a FORBIDDEN\n // here just hides the money panel, so never retry it.\n retry: false,\n });\n};\n\nexport const useRecordRegistrationPayment = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async (input: AthRecordRegistrationPaymentInput) => {\n const result = await athQuery<{ athRecordRegistrationPayment: AthRegistrationPayment }>(\n `mutation AthRecordRegistrationPayment($input: AthRecordRegistrationPaymentInput!) {\n athRecordRegistrationPayment(input: $input) { ${PAYMENT_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athRecordRegistrationPayment;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport const useVoidRegistrationPayment = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({ id, reason }: { id: string; reason: string }) => {\n const result = await athQuery<{ athVoidRegistrationPayment: AthRegistrationPayment }>(\n `mutation AthVoidRegistrationPayment($id: ID!, $reason: String!) {\n athVoidRegistrationPayment(id: $id, reason: $reason) { ${PAYMENT_FIELDS} }\n }`,\n { id, reason },\n apiGatewayUrl\n );\n return result.athVoidRegistrationPayment;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport const useRefundRegistrationPayment = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({ id, amount, reason }: { id: string; amount: number; reason: string }) => {\n const result = await athQuery<{ athRefundRegistrationPayment: AthRegistrationPayment }>(\n `mutation AthRefundRegistrationPayment($id: ID!, $input: AthRefundRegistrationPaymentInput!) {\n athRefundRegistrationPayment(id: $id, input: $input) { ${PAYMENT_FIELDS} }\n }`,\n { id, input: { amount, reason } },\n apiGatewayUrl\n );\n return result.athRefundRegistrationPayment;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\n// ============================================================================\n// Family-facing (self-scoped)\n// ============================================================================\n\nexport const usePublicRegistrationForm = (slug: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, 'public', slug],\n queryFn: async () => {\n const result = await athQuery<{\n athRegistrationFormBySlug: AthPublicRegistrationForm | null;\n }>(\n `query AthRegistrationFormBySlug($slug: String!) {\n athRegistrationFormBySlug(slug: $slug) { ${PUBLIC_FORM_FIELDS} }\n }`,\n { slug },\n apiGatewayUrl\n );\n return result.athRegistrationFormBySlug;\n },\n enabled: Boolean(slug),\n });\n};\n\nexport const useSubmitRegistration = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async ({ slug, input }: { slug: string; input: AthRegistrationEntryInput }) => {\n const result = await athQuery<{ athSubmitRegistration: AthMyRegistration }>(\n `mutation AthSubmitRegistration($slug: String!, $input: AthSubmitRegistrationInput!) {\n athSubmitRegistration(slug: $slug, input: $input) { ${MY_REGISTRATION_FIELDS} }\n }`,\n { slug, input },\n apiGatewayUrl\n );\n return result.athSubmitRegistration;\n },\n onSuccess: () => void invalidate(),\n });\n};\n\nexport const useMyRegistrations = (pagination?: PaginationInput) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: [...ROOT, 'mine', pagination ?? null],\n queryFn: async () => {\n const result = await athQuery<{ athMyRegistrations: AthMyRegistrationConnection }>(\n `query AthMyRegistrations($pagination: PaginationInput) {\n athMyRegistrations(pagination: $pagination) {\n items { ${MY_REGISTRATION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: pagination ?? null },\n apiGatewayUrl\n );\n return result.athMyRegistrations;\n },\n });\n};\n\nexport const useWithdrawMyRegistration = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n const invalidate = useInvalidateRegistration();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athWithdrawMyRegistration: AthMyRegistration }>(\n `mutation AthWithdrawMyRegistration($id: ID!) {\n athWithdrawMyRegistration(id: $id) { ${MY_REGISTRATION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athWithdrawMyRegistration;\n },\n onSuccess: () => void invalidate(),\n });\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* My registrations (families)
|
|
3
|
+
* @module atheletebridge/pages/registrations
|
|
4
|
+
*
|
|
5
|
+
* Every registration the signed-in user submitted through a club's share
|
|
6
|
+
* link, with its review and payment status (BOFF-4135). Unpaid registrations
|
|
7
|
+
* the club has not reviewed yet can be withdrawn here.
|
|
8
|
+
*/
|
|
9
|
+
export declare function MyRegistrationsPage(): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=MyRegistrationsPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MyRegistrationsPage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/registrations/MyRegistrationsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,wBAAgB,mBAAmB,gCAwFlC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { PageLayout as e } from "../../components/PageLayout.js";
|
|
2
|
+
import { StatusBadge as t } from "../../components/StatusBadge.js";
|
|
3
|
+
import { formatDate as n } from "../../utils/formatters.js";
|
|
4
|
+
import { EmptyState as r } from "../../components/EmptyState.js";
|
|
5
|
+
import { ErrorState as i, LoadingState as a } from "../../components/LoadingState.js";
|
|
6
|
+
import { CursorPager as o } from "../../components/CursorPager.js";
|
|
7
|
+
import { useMyRegistrations as s, useWithdrawMyRegistration as c } from "../../hooks/useRegistrationApi.js";
|
|
8
|
+
import { formatMoney as l } from "../../utils/money.js";
|
|
9
|
+
import { useState as u } from "react";
|
|
10
|
+
import { ClipboardList as d, Undo2 as f } from "lucide-react";
|
|
11
|
+
import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
12
|
+
//#region src/atheletebridge/pages/registrations/MyRegistrationsPage.tsx
|
|
13
|
+
var g = 20;
|
|
14
|
+
function _() {
|
|
15
|
+
let [_, v] = u(0), y = s({
|
|
16
|
+
limit: g,
|
|
17
|
+
offset: _ * g
|
|
18
|
+
}), b = c(), [x, S] = u(null), C = y.data?.items ?? [], w = async (e) => {
|
|
19
|
+
if (window.confirm("Withdraw this registration?")) {
|
|
20
|
+
S(null);
|
|
21
|
+
try {
|
|
22
|
+
await b.mutateAsync(e);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
S(e instanceof Error ? e.message : "Could not withdraw the registration.");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ h(e, {
|
|
29
|
+
title: "My registrations",
|
|
30
|
+
description: "Registrations you have submitted to clubs and academies, and what is still due.",
|
|
31
|
+
children: [x && /* @__PURE__ */ m("p", {
|
|
32
|
+
role: "alert",
|
|
33
|
+
className: "mb-4 text-sm text-status-error-text",
|
|
34
|
+
children: x
|
|
35
|
+
}), y.isLoading ? /* @__PURE__ */ m(a, { label: "Loading your registrations…" }) : y.isError ? /* @__PURE__ */ m(i, { onRetry: () => void y.refetch() }) : C.length === 0 ? /* @__PURE__ */ m(r, {
|
|
36
|
+
illustration: "empty-data",
|
|
37
|
+
icon: /* @__PURE__ */ m(d, { className: "h-10 w-10" }),
|
|
38
|
+
title: "No registrations yet",
|
|
39
|
+
description: "When you register through a club's link, it shows up here."
|
|
40
|
+
}) : /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("ul", {
|
|
41
|
+
className: "divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface",
|
|
42
|
+
"data-testid": "my-registrations",
|
|
43
|
+
children: C.map((e) => /* @__PURE__ */ h("li", {
|
|
44
|
+
className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3",
|
|
45
|
+
children: [/* @__PURE__ */ h("span", {
|
|
46
|
+
className: "min-w-0",
|
|
47
|
+
children: [/* @__PURE__ */ m("span", {
|
|
48
|
+
className: "block font-medium text-text-primary",
|
|
49
|
+
children: e.participantName
|
|
50
|
+
}), /* @__PURE__ */ h("span", {
|
|
51
|
+
className: "block text-xs text-text-secondary",
|
|
52
|
+
children: [
|
|
53
|
+
e.formTitle,
|
|
54
|
+
" · ",
|
|
55
|
+
n(e.submittedAt)
|
|
56
|
+
]
|
|
57
|
+
})]
|
|
58
|
+
}), /* @__PURE__ */ h("span", {
|
|
59
|
+
className: "flex flex-wrap items-center gap-2",
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ m(t, { status: e.status }),
|
|
62
|
+
/* @__PURE__ */ m(t, { status: e.paymentStatus }),
|
|
63
|
+
e.amountDue > 0 && /* @__PURE__ */ h("span", {
|
|
64
|
+
className: "text-sm tabular-nums text-text-secondary",
|
|
65
|
+
children: [l(e.amountOutstanding, e.currency), " due"]
|
|
66
|
+
}),
|
|
67
|
+
e.status === "SUBMITTED" && e.amountPaid === 0 && /* @__PURE__ */ h("button", {
|
|
68
|
+
type: "button",
|
|
69
|
+
disabled: b.isPending,
|
|
70
|
+
onClick: () => void w(e.id),
|
|
71
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50",
|
|
72
|
+
children: [/* @__PURE__ */ m(f, { className: "h-4 w-4" }), " Withdraw"]
|
|
73
|
+
})
|
|
74
|
+
]
|
|
75
|
+
})]
|
|
76
|
+
}, e.id))
|
|
77
|
+
}), /* @__PURE__ */ m(o, {
|
|
78
|
+
className: "mt-6",
|
|
79
|
+
page: _,
|
|
80
|
+
hasMore: y.data?.pageInfo.hasMore ?? !1,
|
|
81
|
+
onPrev: () => v((e) => Math.max(0, e - 1)),
|
|
82
|
+
onNext: () => v((e) => e + 1)
|
|
83
|
+
})] })]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { _ as MyRegistrationsPage };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=MyRegistrationsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MyRegistrationsPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/registrations/MyRegistrationsPage.tsx"],"sourcesContent":["/**\n * My registrations (families)\n * @module atheletebridge/pages/registrations\n *\n * Every registration the signed-in user submitted through a club's share\n * link, with its review and payment status (BOFF-4135). Unpaid registrations\n * the club has not reviewed yet can be withdrawn here.\n */\n\nimport { useState } from 'react';\nimport { ClipboardList, Undo2 } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/LoadingState';\nimport { CursorPager } from '../../components/CursorPager';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { useMyRegistrations, useWithdrawMyRegistration } from '../../hooks/useRegistrationApi';\nimport { formatDate } from '../../utils/formatters';\nimport { formatMoney } from '../../utils/money';\n\nconst PAGE_SIZE = 20;\n\nexport function MyRegistrationsPage() {\n const [page, setPage] = useState(0);\n const mine = useMyRegistrations({ limit: PAGE_SIZE, offset: page * PAGE_SIZE });\n const withdraw = useWithdrawMyRegistration();\n const [error, setError] = useState<string | null>(null);\n const items = mine.data?.items ?? [];\n\n const onWithdraw = async (id: string) => {\n if (!window.confirm('Withdraw this registration?')) return;\n setError(null);\n try {\n await withdraw.mutateAsync(id);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Could not withdraw the registration.');\n }\n };\n\n return (\n <PageLayout\n title=\"My registrations\"\n description=\"Registrations you have submitted to clubs and academies, and what is still due.\"\n >\n {error && (\n <p role=\"alert\" className=\"mb-4 text-sm text-status-error-text\">\n {error}\n </p>\n )}\n {mine.isLoading ? (\n <LoadingState label=\"Loading your registrations…\" />\n ) : mine.isError ? (\n <ErrorState onRetry={() => void mine.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<ClipboardList className=\"h-10 w-10\" />}\n title=\"No registrations yet\"\n description=\"When you register through a club's link, it shows up here.\"\n />\n ) : (\n <>\n <ul\n className=\"divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface\"\n data-testid=\"my-registrations\"\n >\n {items.map((row) => (\n <li\n key={row.id}\n className=\"flex flex-wrap items-center justify-between gap-3 px-4 py-3\"\n >\n <span className=\"min-w-0\">\n <span className=\"block font-medium text-text-primary\">{row.participantName}</span>\n <span className=\"block text-xs text-text-secondary\">\n {row.formTitle} · {formatDate(row.submittedAt)}\n </span>\n </span>\n <span className=\"flex flex-wrap items-center gap-2\">\n <StatusBadge status={row.status} />\n <StatusBadge status={row.paymentStatus} />\n {row.amountDue > 0 && (\n <span className=\"text-sm tabular-nums text-text-secondary\">\n {formatMoney(row.amountOutstanding, row.currency)} due\n </span>\n )}\n {row.status === 'SUBMITTED' && row.amountPaid === 0 && (\n <button\n type=\"button\"\n disabled={withdraw.isPending}\n onClick={() => void onWithdraw(row.id)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Undo2 className=\"h-4 w-4\" /> Withdraw\n </button>\n )}\n </span>\n </li>\n ))}\n </ul>\n <CursorPager\n className=\"mt-6\"\n page={page}\n hasMore={mine.data?.pageInfo.hasMore ?? false}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAM,IAAY;AAElB,SAAgB,IAAsB;CACpC,IAAM,CAAC,GAAM,KAAW,EAAS,CAAC,GAC5B,IAAO,EAAmB;EAAE,OAAO;EAAW,QAAQ,IAAO;CAAU,CAAC,GACxE,IAAW,EAA0B,GACrC,CAAC,GAAO,KAAY,EAAwB,IAAI,GAChD,IAAQ,EAAK,MAAM,SAAS,CAAC,GAE7B,IAAa,OAAO,MAAe;EAClC,WAAO,QAAQ,6BAA6B,GACjD;KAAS,IAAI;GACb,IAAI;IACF,MAAM,EAAS,YAAY,CAAE;GAC/B,SAAS,GAAK;IACZ,EAAS,aAAe,QAAQ,EAAI,UAAU,sCAAsC;GACtF;EALa;CAMf;CAEA,OACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIG,KACC,kBAAC,KAAD;GAAG,MAAK;GAAQ,WAAU;aACvB;EACA,CAAA,GAEJ,EAAK,YACJ,kBAAC,GAAD,EAAc,OAAM,8BAA+B,CAAA,IACjD,EAAK,UACP,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAK,QAAQ,EAAI,CAAA,IAC/C,EAAM,WAAW,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAe,WAAU,YAAa,CAAA;GAC5C,OAAM;GACN,aAAY;EACb,CAAA,IAED,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,MAAD;GACE,WAAU;GACV,eAAY;aAEX,EAAM,KAAK,MACV,kBAAC,MAAD;IAEE,WAAU;cAFZ,CAIE,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,QAAD;MAAM,WAAU;gBAAuC,EAAI;KAAsB,CAAA,GACjF,kBAAC,QAAD;MAAM,WAAU;gBAAhB;OACG,EAAI;OAAU;OAAI,EAAW,EAAI,WAAW;MACzC;OACF;QACN,kBAAC,QAAD;KAAM,WAAU;eAAhB;MACE,kBAAC,GAAD,EAAa,QAAQ,EAAI,OAAS,CAAA;MAClC,kBAAC,GAAD,EAAa,QAAQ,EAAI,cAAgB,CAAA;MACxC,EAAI,YAAY,KACf,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACG,EAAY,EAAI,mBAAmB,EAAI,QAAQ,GAAE,MAC9C;;MAEP,EAAI,WAAW,eAAe,EAAI,eAAe,KAChD,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,EAAS;OACnB,eAAe,KAAK,EAAW,EAAI,EAAE;OACrC,WAAU;iBAJZ,CAME,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA,GAAC,WACvB;;KAEN;MACJ;MA5BG,EAAI,EA4BP,CACL;EACC,CAAA,GACJ,kBAAC,GAAD;GACE,WAAU;GACJ;GACN,SAAS,EAAK,MAAM,SAAS,WAAW;GACxC,cAAc,GAAS,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;GAC/C,cAAc,GAAS,MAAM,IAAI,CAAC;EACnC,CAAA,CACD,EAAA,CAAA,CAEM;;AAEhB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record a registration (club staff)
|
|
3
|
+
* @module atheletebridge/pages/registrations
|
|
4
|
+
*
|
|
5
|
+
* Key in a paper, phone or in-person registration against a form (BOFF-4135).
|
|
6
|
+
* Staff entries are accepted for draft and closed forms too (late paper
|
|
7
|
+
* forms, pre-season sign-ups) — only archived forms are off limits.
|
|
8
|
+
*/
|
|
9
|
+
export declare function RecordRegistrationPage(): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=RecordRegistrationPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordRegistrationPage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/registrations/RecordRegistrationPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,wBAAgB,sBAAsB,gCAmGrC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { ErrorState as n, LoadingState as r } from "../../components/LoadingState.js";
|
|
4
|
+
import { useRecordRegistration as i, useRegistrationForm as a } from "../../hooks/useRegistrationApi.js";
|
|
5
|
+
import { EMPTY_REGISTRATION_ENTRY as o, cleanAnswers as s, missingRequiredAnswer as c } from "../../components/registration/entryRules.js";
|
|
6
|
+
import { RegistrationEntryFields as l } from "../../components/registration/RegistrationEntryFields.js";
|
|
7
|
+
import { useState as u } from "react";
|
|
8
|
+
import { ArrowLeft as d, Loader2 as f, Save as p } from "lucide-react";
|
|
9
|
+
import { useParams as m } from "react-router";
|
|
10
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
11
|
+
//#region src/atheletebridge/pages/registrations/RecordRegistrationPage.tsx
|
|
12
|
+
function _() {
|
|
13
|
+
let { id: _ } = m(), { navigateTo: v } = e(), y = a(_), b = i(), [x, S] = u(o), [C, w] = u(null);
|
|
14
|
+
if (y.isLoading) return /* @__PURE__ */ h(t, {
|
|
15
|
+
title: "Record registration",
|
|
16
|
+
children: /* @__PURE__ */ h(r, { label: "Loading registration form…" })
|
|
17
|
+
});
|
|
18
|
+
if (y.isError || !y.data || !_) return /* @__PURE__ */ h(t, {
|
|
19
|
+
title: "Record registration",
|
|
20
|
+
children: /* @__PURE__ */ h(n, {
|
|
21
|
+
title: "Registration form not found",
|
|
22
|
+
onRetry: () => v("/registrations")
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
let T = y.data;
|
|
26
|
+
return /* @__PURE__ */ h(t, {
|
|
27
|
+
title: "Record registration",
|
|
28
|
+
description: `${T.title} — enter a registration received on paper, by phone or in person.`,
|
|
29
|
+
actions: /* @__PURE__ */ g("button", {
|
|
30
|
+
type: "button",
|
|
31
|
+
onClick: () => v(`/registrations/${_}`),
|
|
32
|
+
className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
|
|
33
|
+
children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), " Cancel"]
|
|
34
|
+
}),
|
|
35
|
+
children: /* @__PURE__ */ g("form", {
|
|
36
|
+
onSubmit: async (e) => {
|
|
37
|
+
e.preventDefault(), w(null);
|
|
38
|
+
let t = c(T.fields, x);
|
|
39
|
+
if (t) {
|
|
40
|
+
w(`Please answer "${t}".`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (T.waiverText && !x.waiverAccepted) {
|
|
44
|
+
w("Confirm the registrant accepted the waiver.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
v(`/registrations/${_}/submissions/${(await b.mutateAsync({
|
|
49
|
+
formId: _,
|
|
50
|
+
participantName: x.participantName.trim(),
|
|
51
|
+
contactName: x.contactName.trim() || void 0,
|
|
52
|
+
contactEmail: x.contactEmail.trim() || void 0,
|
|
53
|
+
contactPhone: x.contactPhone.trim() || void 0,
|
|
54
|
+
answers: s(x.answers),
|
|
55
|
+
selectedFeeIds: x.optionalFeeIds,
|
|
56
|
+
waiverAccepted: x.waiverAccepted
|
|
57
|
+
})).id}`);
|
|
58
|
+
} catch (e) {
|
|
59
|
+
w(e instanceof Error ? e.message : "Could not record the registration.");
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
className: "max-w-2xl space-y-6",
|
|
63
|
+
children: [
|
|
64
|
+
/* @__PURE__ */ h(l, {
|
|
65
|
+
fields: T.fields,
|
|
66
|
+
fees: T.fees,
|
|
67
|
+
currency: T.currency,
|
|
68
|
+
waiverText: T.waiverText,
|
|
69
|
+
state: x,
|
|
70
|
+
onChange: S
|
|
71
|
+
}),
|
|
72
|
+
C && /* @__PURE__ */ h("p", {
|
|
73
|
+
role: "alert",
|
|
74
|
+
className: "text-sm text-status-error-text",
|
|
75
|
+
children: C
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ g("button", {
|
|
78
|
+
type: "submit",
|
|
79
|
+
disabled: b.isPending,
|
|
80
|
+
className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
|
|
81
|
+
children: [
|
|
82
|
+
b.isPending ? /* @__PURE__ */ h(f, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ h(p, { className: "h-4 w-4" }),
|
|
83
|
+
" ",
|
|
84
|
+
"Save registration"
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
]
|
|
88
|
+
})
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { _ as RecordRegistrationPage };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=RecordRegistrationPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordRegistrationPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/registrations/RecordRegistrationPage.tsx"],"sourcesContent":["/**\n * Record a registration (club staff)\n * @module atheletebridge/pages/registrations\n *\n * Key in a paper, phone or in-person registration against a form (BOFF-4135).\n * Staff entries are accepted for draft and closed forms too (late paper\n * forms, pre-season sign-ups) — only archived forms are off limits.\n */\n\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { ArrowLeft, Loader2, Save } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { LoadingState, ErrorState } from '../../components/LoadingState';\nimport { RegistrationEntryFields } from '../../components/registration/RegistrationEntryFields';\nimport {\n EMPTY_REGISTRATION_ENTRY,\n type RegistrationEntryState,\n cleanAnswers,\n missingRequiredAnswer,\n} from '../../components/registration/entryRules';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useRecordRegistration, useRegistrationForm } from '../../hooks/useRegistrationApi';\n\nexport function RecordRegistrationPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useAthleteBridge();\n const form = useRegistrationForm(id);\n const record = useRecordRegistration();\n const [state, setState] = useState<RegistrationEntryState>(EMPTY_REGISTRATION_ENTRY);\n const [error, setError] = useState<string | null>(null);\n\n if (form.isLoading) {\n return (\n <PageLayout title=\"Record registration\">\n <LoadingState label=\"Loading registration form…\" />\n </PageLayout>\n );\n }\n if (form.isError || !form.data || !id) {\n return (\n <PageLayout title=\"Record registration\">\n <ErrorState\n title=\"Registration form not found\"\n onRetry={() => navigateTo('/registrations')}\n />\n </PageLayout>\n );\n }\n const data = form.data;\n\n const submit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n const missing = missingRequiredAnswer(data.fields, state);\n if (missing) {\n setError(`Please answer \"${missing}\".`);\n return;\n }\n if (data.waiverText && !state.waiverAccepted) {\n setError('Confirm the registrant accepted the waiver.');\n return;\n }\n try {\n const created = await record.mutateAsync({\n formId: id,\n participantName: state.participantName.trim(),\n contactName: state.contactName.trim() || undefined,\n contactEmail: state.contactEmail.trim() || undefined,\n contactPhone: state.contactPhone.trim() || undefined,\n answers: cleanAnswers(state.answers),\n selectedFeeIds: state.optionalFeeIds,\n waiverAccepted: state.waiverAccepted,\n });\n navigateTo(`/registrations/${id}/submissions/${created.id}`);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Could not record the registration.');\n }\n };\n\n return (\n <PageLayout\n title=\"Record registration\"\n description={`${data.title} — enter a registration received on paper, by phone or in person.`}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo(`/registrations/${id}`)}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Cancel\n </button>\n }\n >\n <form onSubmit={submit} className=\"max-w-2xl space-y-6\">\n <RegistrationEntryFields\n fields={data.fields}\n fees={data.fees}\n currency={data.currency}\n waiverText={data.waiverText}\n state={state}\n onChange={setState}\n />\n {error && (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {error}\n </p>\n )}\n <button\n type=\"submit\"\n disabled={record.isPending}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60\"\n >\n {record.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}{' '}\n Save registration\n </button>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAgB,IAAyB;CACvC,IAAM,EAAE,UAAO,EAA0B,GACnC,EAAE,kBAAe,EAAiB,GAClC,IAAO,EAAoB,CAAE,GAC7B,IAAS,EAAsB,GAC/B,CAAC,GAAO,KAAY,EAAiC,CAAwB,GAC7E,CAAC,GAAO,KAAY,EAAwB,IAAI;CAEtD,IAAI,EAAK,WACP,OACE,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD,EAAc,OAAM,6BAA8B,CAAA;CACxC,CAAA;CAGhB,IAAI,EAAK,WAAW,CAAC,EAAK,QAAQ,CAAC,GACjC,OACE,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD;GACE,OAAM;GACN,eAAe,EAAW,gBAAgB;EAC3C,CAAA;CACS,CAAA;CAGhB,IAAM,IAAO,EAAK;CA+BlB,OACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,GAAG,EAAK,MAAM;EAC3B,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,kBAAkB,GAAI;GAChD,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,UAAW,CAAA,GAAC,SAC3B;;YAGV,kBAAC,QAAD;GAAM,UAAU,OA3CE,MAAuB;IAE3C,AADA,EAAE,eAAe,GACjB,EAAS,IAAI;IACb,IAAM,IAAU,EAAsB,EAAK,QAAQ,CAAK;IACxD,IAAI,GAAS;KACX,EAAS,kBAAkB,EAAQ,GAAG;KACtC;IACF;IACA,IAAI,EAAK,cAAc,CAAC,EAAM,gBAAgB;KAC5C,EAAS,6CAA6C;KACtD;IACF;IACA,IAAI;KAWF,EAAW,kBAAkB,EAAG,gBAAe,MAVzB,EAAO,YAAY;MACvC,QAAQ;MACR,iBAAiB,EAAM,gBAAgB,KAAK;MAC5C,aAAa,EAAM,YAAY,KAAK,KAAK,KAAA;MACzC,cAAc,EAAM,aAAa,KAAK,KAAK,KAAA;MAC3C,cAAc,EAAM,aAAa,KAAK,KAAK,KAAA;MAC3C,SAAS,EAAa,EAAM,OAAO;MACnC,gBAAgB,EAAM;MACtB,gBAAgB,EAAM;KACxB,CAAC,GACsD,IAAI;IAC7D,SAAS,GAAK;KACZ,EAAS,aAAe,QAAQ,EAAI,UAAU,oCAAoC;IACpF;GACF;GAgB4B,WAAU;aAAlC;IACE,kBAAC,GAAD;KACE,QAAQ,EAAK;KACb,MAAM,EAAK;KACX,UAAU,EAAK;KACf,YAAY,EAAK;KACV;KACP,UAAU;IACX,CAAA;IACA,KACC,kBAAC,KAAD;KAAG,MAAK;KAAQ,WAAU;eACvB;IACA,CAAA;IAEL,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,EAAO;KACjB,WAAU;eAHZ;MAKG,EAAO,YACN,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,IAE3C,kBAAC,GAAD,EAAM,WAAU,UAAW,CAAA;MAC1B;MAAI;KAED;;GACJ;;CACI,CAAA;AAEhB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Family registration (share link)
|
|
3
|
+
* @module atheletebridge/pages/registrations
|
|
4
|
+
*
|
|
5
|
+
* Opened from a club's share link (`/register/:slug`). Any signed-in user —
|
|
6
|
+
* typically a parent who is not a member of the club's workspace — can fill
|
|
7
|
+
* in a published form; the registration is filed with the club and tracked
|
|
8
|
+
* under "My registrations" (BOFF-4135).
|
|
9
|
+
*/
|
|
10
|
+
export declare function RegisterPage(): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=RegisterPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RegisterPage.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/pages/registrations/RegisterPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsBH,wBAAgB,YAAY,gCAgK3B"}
|