@odla-ai/chapter 0.56.1 → 0.57.0
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/README.md +96 -0
- package/dist/{chunk-NK267YQZ.js → chunk-CKC6X5H2.js} +714 -506
- package/dist/chunk-CKC6X5H2.js.map +1 -0
- package/dist/{chunk-4M2PN5K3.js → chunk-FHKZVF5G.js} +3 -1
- package/dist/chunk-FHKZVF5G.js.map +1 -0
- package/dist/{chunk-ZAE24YKY.js → chunk-L2IPS2FQ.js} +51 -4
- package/dist/chunk-L2IPS2FQ.js.map +1 -0
- package/dist/{copy-context-CaUXIxUI.d.ts → copy-context-DE4YMAbz.d.ts} +1 -1
- package/dist/index.cjs +176 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -3
- package/dist/index.d.ts +36 -3
- package/dist/index.js +176 -13
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +4 -3
- package/dist/ui/admin/index.js +2 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +13 -3
- package/dist/ui/member/index.d.ts +93 -4
- package/dist/ui/member/index.js +12 -2
- package/dist/worker/index.cjs +1558 -1125
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +149 -3
- package/dist/worker/index.d.ts +149 -3
- package/dist/worker/index.js +1558 -1125
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4M2PN5K3.js.map +0 -1
- package/dist/chunk-NK267YQZ.js.map +0 -1
- package/dist/chunk-ZAE24YKY.js.map +0 -1
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
DEFAULT_JOIN_COPY,
|
|
3
3
|
formatChapterCopy,
|
|
4
4
|
useChapterCopy
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FHKZVF5G.js";
|
|
6
6
|
import {
|
|
7
7
|
collectFormFields
|
|
8
8
|
} from "./chunk-IVXVECKR.js";
|
|
@@ -111,14 +111,185 @@ function SlotPicker(props) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
// src/ui/member-restart.tsx
|
|
114
|
-
import { useEffect as useEffect2, useState as
|
|
114
|
+
import { useEffect as useEffect2, useState as useState7 } from "preact/hooks";
|
|
115
|
+
|
|
116
|
+
// src/ui/additional-member-editor.tsx
|
|
117
|
+
import { useRef as useRef2, useState as useState3 } from "preact/hooks";
|
|
118
|
+
|
|
119
|
+
// src/ui/additional-member-fields.tsx
|
|
120
|
+
import { useRef } from "preact/hooks";
|
|
121
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "preact/jsx-runtime";
|
|
122
|
+
var ADDITIONAL_MEMBER_COPY = {
|
|
123
|
+
label: "Additional member",
|
|
124
|
+
includedChoice: "Include my additional member at no extra charge.",
|
|
125
|
+
paidChoice: "Add one additional member.",
|
|
126
|
+
includedHint: "Included with your membership at no extra charge.",
|
|
127
|
+
pendingHint: "Your additional-member rate will be confirmed at checkout.",
|
|
128
|
+
editTitle: "Edit additional member details"
|
|
129
|
+
};
|
|
130
|
+
function additionalMemberSelection(value) {
|
|
131
|
+
return value.selected ? { recipientName: value.name.trim(), recipientEmail: value.email.trim() } : null;
|
|
132
|
+
}
|
|
133
|
+
function AdditionalMemberFields({ value, onChange, offer, ...options }) {
|
|
134
|
+
const draft = useRef(value);
|
|
135
|
+
draft.current = value;
|
|
136
|
+
const change = (patch) => {
|
|
137
|
+
draft.current = { ...draft.current, ...patch };
|
|
138
|
+
onChange(draft.current);
|
|
139
|
+
};
|
|
140
|
+
const copy = { ...ADDITIONAL_MEMBER_COPY, ...options.copy };
|
|
141
|
+
const names = { selected: "additionalMemberSelected", name: "additionalMemberName", email: "additionalMemberEmail", ...options.names };
|
|
142
|
+
const price2 = offer && new Intl.NumberFormat("en-US", { style: "currency", currency: offer.currency ?? "USD" }).format(offer.amountCents / 100);
|
|
143
|
+
return /* @__PURE__ */ jsxs2("div", { className: "form-group additional-member-fields", children: [
|
|
144
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: names.selected, children: copy.label }),
|
|
145
|
+
/* @__PURE__ */ jsx2("p", { className: "hint", children: offer?.amountCents === 0 ? copy.includedHint : offer ? `${price2} per ${offer.interval ?? "year"}, paid with your membership.` : copy.pendingHint }),
|
|
146
|
+
/* @__PURE__ */ jsxs2("label", { className: "checkbox-option journey-consent", children: [
|
|
147
|
+
/* @__PURE__ */ jsx2(
|
|
148
|
+
"input",
|
|
149
|
+
{
|
|
150
|
+
type: "checkbox",
|
|
151
|
+
id: names.selected,
|
|
152
|
+
name: names.selected,
|
|
153
|
+
value: "yes",
|
|
154
|
+
checked: value.selected,
|
|
155
|
+
onChange: (event) => change({ selected: event.currentTarget.checked })
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
offer?.amountCents === 0 ? copy.includedChoice : copy.paidChoice
|
|
159
|
+
] }),
|
|
160
|
+
value.selected ? /* @__PURE__ */ jsxs2("div", { className: "additional-member-details", children: [
|
|
161
|
+
/* @__PURE__ */ jsxs2("label", { htmlFor: names.name, children: [
|
|
162
|
+
"Full name ",
|
|
163
|
+
/* @__PURE__ */ jsx2("span", { className: "req", "aria-hidden": "true", children: "*" })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsx2(
|
|
166
|
+
"input",
|
|
167
|
+
{
|
|
168
|
+
type: "text",
|
|
169
|
+
id: names.name,
|
|
170
|
+
name: names.name,
|
|
171
|
+
placeholder: "Full name",
|
|
172
|
+
required: true,
|
|
173
|
+
minLength: 2,
|
|
174
|
+
maxLength: 160,
|
|
175
|
+
pattern: ".*\\S.*\\S.*",
|
|
176
|
+
value: value.name,
|
|
177
|
+
onInput: (event) => change({ name: event.currentTarget.value })
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
/* @__PURE__ */ jsxs2("label", { htmlFor: names.email, children: [
|
|
181
|
+
"Email ",
|
|
182
|
+
/* @__PURE__ */ jsx2("span", { className: "req", "aria-hidden": "true", children: "*" })
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsx2(
|
|
185
|
+
"input",
|
|
186
|
+
{
|
|
187
|
+
type: "email",
|
|
188
|
+
id: names.email,
|
|
189
|
+
name: names.email,
|
|
190
|
+
placeholder: "member@example.com",
|
|
191
|
+
required: true,
|
|
192
|
+
pattern: "[^\\s@]+@[^\\s@]+\\.[^\\s@]+",
|
|
193
|
+
maxLength: 254,
|
|
194
|
+
value: value.email,
|
|
195
|
+
onInput: (event) => change({ email: event.currentTarget.value })
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
] }) : null
|
|
199
|
+
] });
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// src/ui/form-readiness.ts
|
|
203
|
+
import { useLayoutEffect, useState as useState2 } from "preact/hooks";
|
|
204
|
+
function isFormReady(form) {
|
|
205
|
+
return Array.from(form.elements).every((element) => {
|
|
206
|
+
const field = element;
|
|
207
|
+
return !field.willValidate || field.validity.valid && (!field.required || field.value.trim().length > 0);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function useFormReadiness(ref) {
|
|
211
|
+
const [ready, setReady] = useState2(false);
|
|
212
|
+
useLayoutEffect(() => {
|
|
213
|
+
const form = ref.current;
|
|
214
|
+
if (!form) return;
|
|
215
|
+
let live = true;
|
|
216
|
+
const update = () => {
|
|
217
|
+
if (live) setReady(isFormReady(form));
|
|
218
|
+
};
|
|
219
|
+
const afterInput = () => queueMicrotask(update);
|
|
220
|
+
update();
|
|
221
|
+
for (const type of ["input", "change", "focusin", "reset"]) form.addEventListener(type, afterInput);
|
|
222
|
+
const observer = new MutationObserver(afterInput);
|
|
223
|
+
observer.observe(form, {
|
|
224
|
+
childList: true,
|
|
225
|
+
subtree: true,
|
|
226
|
+
attributes: true,
|
|
227
|
+
attributeFilter: ["required", "disabled", "pattern", "minlength", "maxlength", "min", "max", "type"]
|
|
228
|
+
});
|
|
229
|
+
return () => {
|
|
230
|
+
live = false;
|
|
231
|
+
observer.disconnect();
|
|
232
|
+
for (const type of ["input", "change", "focusin", "reset"]) form.removeEventListener(type, afterInput);
|
|
233
|
+
};
|
|
234
|
+
});
|
|
235
|
+
return ready;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/ui/join-submit-button.tsx
|
|
239
|
+
import { jsx as jsx3 } from "preact/jsx-runtime";
|
|
240
|
+
function JoinSubmitButton(props) {
|
|
241
|
+
return /* @__PURE__ */ jsx3("button", { ...props, type: "submit", className: "submit-btn chapter-form-primary" });
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/ui/join-recipient.ts
|
|
245
|
+
function validJoinRecipient(recipient) {
|
|
246
|
+
if (!recipient) return true;
|
|
247
|
+
const name = recipient.recipientName.trim(), email = recipient.recipientEmail.trim();
|
|
248
|
+
return name.length >= 2 && name.length <= 160 && !/[\u0000-\u001f\u007f]/.test(name) && email.length <= 254 && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/ui/additional-member-editor.tsx
|
|
252
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
253
|
+
function AdditionalMemberEditor({ selection, offer, save, cancel, onSaved, ...options }) {
|
|
254
|
+
const [value, setValue] = useState3({ selected: Boolean(selection), name: selection?.recipientName ?? "", email: selection?.recipientEmail ?? "" });
|
|
255
|
+
const [saving, setSaving] = useState3(false), [error, setError] = useState3("");
|
|
256
|
+
const form = useRef2(null), inFlight = useRef2(false);
|
|
257
|
+
const ready = useFormReadiness(form);
|
|
258
|
+
const valid = validJoinRecipient(additionalMemberSelection(value) ?? void 0);
|
|
259
|
+
return /* @__PURE__ */ jsxs3("form", { ref: form, className: "join-form additional-member-editor", onSubmit: async (event) => {
|
|
260
|
+
event.preventDefault();
|
|
261
|
+
if (inFlight.current || !valid || !isFormReady(event.currentTarget)) return;
|
|
262
|
+
inFlight.current = true;
|
|
263
|
+
setSaving(true);
|
|
264
|
+
setError("");
|
|
265
|
+
try {
|
|
266
|
+
await save(additionalMemberSelection(value));
|
|
267
|
+
onSaved?.(value);
|
|
268
|
+
} catch (failure) {
|
|
269
|
+
setError(failure instanceof Error ? failure.message : "Could not save your changes. Try again.");
|
|
270
|
+
} finally {
|
|
271
|
+
inFlight.current = false;
|
|
272
|
+
setSaving(false);
|
|
273
|
+
}
|
|
274
|
+
}, children: [
|
|
275
|
+
/* @__PURE__ */ jsx4("h2", { children: options.copy?.editTitle ?? ADDITIONAL_MEMBER_COPY.editTitle }),
|
|
276
|
+
/* @__PURE__ */ jsxs3("fieldset", { disabled: saving, children: [
|
|
277
|
+
/* @__PURE__ */ jsx4(AdditionalMemberFields, { ...options, value, onChange: setValue, offer }),
|
|
278
|
+
error ? /* @__PURE__ */ jsx4("p", { role: "alert", children: error }) : null,
|
|
279
|
+
/* @__PURE__ */ jsxs3("div", { className: "journey-actions additional-member-actions", children: [
|
|
280
|
+
/* @__PURE__ */ jsx4(JoinSubmitButton, { disabled: saving || !ready || !valid, children: saving ? "Saving\u2026" : "Save details" }),
|
|
281
|
+
/* @__PURE__ */ jsx4("button", { className: "journey-secondary", type: "button", onClick: cancel, children: "Cancel" })
|
|
282
|
+
] })
|
|
283
|
+
] })
|
|
284
|
+
] });
|
|
285
|
+
}
|
|
115
286
|
|
|
116
287
|
// src/ui/membership-payment-step.tsx
|
|
117
|
-
import { useEffect, useState as
|
|
288
|
+
import { useEffect, useState as useState6 } from "preact/hooks";
|
|
118
289
|
|
|
119
290
|
// src/ui/payment-step.tsx
|
|
120
|
-
import { useRef, useState as
|
|
121
|
-
import { jsx as
|
|
291
|
+
import { useRef as useRef3, useState as useState4 } from "preact/hooks";
|
|
292
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
122
293
|
var loader = null;
|
|
123
294
|
function loadStripe() {
|
|
124
295
|
const existing = globalThis.Stripe;
|
|
@@ -152,13 +323,13 @@ function PaymentStep(props) {
|
|
|
152
323
|
simulation
|
|
153
324
|
} = props;
|
|
154
325
|
const copy = props.copy ?? inheritedCopy.join.payment;
|
|
155
|
-
const [status, setStatus] =
|
|
156
|
-
const [error, setError] =
|
|
157
|
-
const [lineItems, setLineItems] =
|
|
158
|
-
const mountRef =
|
|
159
|
-
const stripeRef =
|
|
160
|
-
const elementsRef =
|
|
161
|
-
const completionRef =
|
|
326
|
+
const [status, setStatus] = useState4("idle");
|
|
327
|
+
const [error, setError] = useState4(null);
|
|
328
|
+
const [lineItems, setLineItems] = useState4(null);
|
|
329
|
+
const mountRef = useRef3(null);
|
|
330
|
+
const stripeRef = useRef3(null);
|
|
331
|
+
const elementsRef = useRef3(null);
|
|
332
|
+
const completionRef = useRef3({ gift: false });
|
|
162
333
|
const begin = async () => {
|
|
163
334
|
setStatus("loading");
|
|
164
335
|
setError(null);
|
|
@@ -228,12 +399,12 @@ function PaymentStep(props) {
|
|
|
228
399
|
setStatus("ready");
|
|
229
400
|
}
|
|
230
401
|
};
|
|
231
|
-
return /* @__PURE__ */
|
|
232
|
-
/* @__PURE__ */
|
|
233
|
-
merchantDisclosureText ? /* @__PURE__ */
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
/* @__PURE__ */
|
|
236
|
-
/* @__PURE__ */
|
|
402
|
+
return /* @__PURE__ */ jsxs4("div", { className: "join-pay", children: [
|
|
403
|
+
/* @__PURE__ */ jsxs4("div", { className: "compliance-box", children: [
|
|
404
|
+
merchantDisclosureText ? /* @__PURE__ */ jsx5("p", { className: "compliance-merchant", children: merchantDisclosureText }) : null,
|
|
405
|
+
/* @__PURE__ */ jsx5("p", { className: "compliance-policy", children: refundPolicyText }),
|
|
406
|
+
/* @__PURE__ */ jsxs4("label", { className: "compliance-check", children: [
|
|
407
|
+
/* @__PURE__ */ jsx5(
|
|
237
408
|
"input",
|
|
238
409
|
{
|
|
239
410
|
type: "checkbox",
|
|
@@ -243,52 +414,55 @@ function PaymentStep(props) {
|
|
|
243
414
|
}
|
|
244
415
|
}
|
|
245
416
|
),
|
|
246
|
-
copy.consent ? /* @__PURE__ */
|
|
417
|
+
copy.consent ? /* @__PURE__ */ jsx5("span", { children: copy.consent }) : null
|
|
247
418
|
] })
|
|
248
419
|
] }),
|
|
249
|
-
status === "loading" ? /* @__PURE__ */
|
|
420
|
+
status === "loading" ? /* @__PURE__ */ jsx5("p", { className: "pay-status", children: copy.preparing }) : null,
|
|
250
421
|
lineItems && renderPriceLines ? renderPriceLines(lineItems) : null,
|
|
251
422
|
children,
|
|
252
|
-
simulation && (status === "ready" || status === "confirming") ? /* @__PURE__ */
|
|
253
|
-
/* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
423
|
+
simulation && (status === "ready" || status === "confirming") ? /* @__PURE__ */ jsxs4("fieldset", { className: "join-pay-simulation", children: [
|
|
424
|
+
/* @__PURE__ */ jsx5("legend", { children: "Payment details" }),
|
|
425
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
255
426
|
"Card number",
|
|
256
|
-
/* @__PURE__ */
|
|
427
|
+
/* @__PURE__ */ jsx5("input", { name: "simulationCardNumber", inputMode: "numeric", autoComplete: "off", defaultValue: "4242 4242 4242 4242" })
|
|
257
428
|
] }),
|
|
258
|
-
/* @__PURE__ */
|
|
429
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
259
430
|
"Expiration",
|
|
260
|
-
/* @__PURE__ */
|
|
431
|
+
/* @__PURE__ */ jsx5("input", { name: "simulationCardExpiry", inputMode: "numeric", autoComplete: "off", defaultValue: "12 / 34" })
|
|
261
432
|
] }),
|
|
262
|
-
/* @__PURE__ */
|
|
433
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
263
434
|
"Security code",
|
|
264
|
-
/* @__PURE__ */
|
|
435
|
+
/* @__PURE__ */ jsx5("input", { name: "simulationCardCvc", inputMode: "numeric", autoComplete: "off", defaultValue: "123" })
|
|
265
436
|
] }),
|
|
266
|
-
/* @__PURE__ */
|
|
437
|
+
/* @__PURE__ */ jsx5("p", { children: "This is a simulation. No card data is sent and no charge is created." })
|
|
267
438
|
] }) : null,
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
-
status === "ready" || status === "confirming" ? /* @__PURE__ */
|
|
270
|
-
error ? /* @__PURE__ */
|
|
439
|
+
/* @__PURE__ */ jsx5("div", { ref: mountRef, hidden: status === "idle" || status === "loading" }),
|
|
440
|
+
status === "ready" || status === "confirming" ? /* @__PURE__ */ jsx5("button", { className: "submit-btn", disabled: status === "confirming", onClick: () => void pay(), children: status === "confirming" ? copy.processing : copy.payAndContinue }) : null,
|
|
441
|
+
error ? /* @__PURE__ */ jsx5("p", { className: "pay-error", children: error }) : null
|
|
271
442
|
] });
|
|
272
443
|
}
|
|
273
444
|
|
|
274
445
|
// src/ui/checkout-seat-choice.tsx
|
|
275
|
-
import { useState as
|
|
276
|
-
import {
|
|
446
|
+
import { useRef as useRef4, useState as useState5 } from "preact/hooks";
|
|
447
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
277
448
|
function CheckoutSeatChoice(props) {
|
|
278
449
|
const saved = props.quote.namedSeat;
|
|
279
|
-
const [selected, setSelected] =
|
|
280
|
-
const [name, setName] =
|
|
281
|
-
const [email, setEmail] =
|
|
282
|
-
const [saving, setSaving] =
|
|
283
|
-
const
|
|
284
|
-
const
|
|
450
|
+
const [selected, setSelected] = useState5(Boolean(saved || props.initial));
|
|
451
|
+
const [name, setName] = useState5(saved?.recipientName ?? props.initial?.recipientName ?? "");
|
|
452
|
+
const [email, setEmail] = useState5(saved?.recipientEmail ?? props.initial?.recipientEmail ?? "");
|
|
453
|
+
const [saving, setSaving] = useState5(false), [error, setError] = useState5("");
|
|
454
|
+
const form = useRef4(null), inFlight = useRef4(false);
|
|
455
|
+
const ready = useFormReadiness(form);
|
|
456
|
+
const valid = validJoinRecipient(selected ? { recipientName: name, recipientEmail: email } : void 0);
|
|
285
457
|
const dirty = selected !== Boolean(saved) || selected && (name !== saved?.recipientName || email !== saved?.recipientEmail);
|
|
286
458
|
const edit = (nextSelected, nextName = name, nextEmail = email) => {
|
|
287
459
|
props.onEditing(nextSelected !== Boolean(saved) || nextSelected && (nextName !== saved?.recipientName || nextEmail !== saved?.recipientEmail));
|
|
288
460
|
setError("");
|
|
289
461
|
};
|
|
290
|
-
return /* @__PURE__ */
|
|
462
|
+
return /* @__PURE__ */ jsx6("section", { className: "checkout-seat-choice", "aria-label": "Additional member", children: /* @__PURE__ */ jsxs5("form", { ref: form, onSubmit: async (event) => {
|
|
291
463
|
event.preventDefault();
|
|
464
|
+
if (props.locked || inFlight.current || !valid || !isFormReady(event.currentTarget)) return;
|
|
465
|
+
inFlight.current = true;
|
|
292
466
|
setSaving(true);
|
|
293
467
|
setError("");
|
|
294
468
|
try {
|
|
@@ -296,88 +470,60 @@ function CheckoutSeatChoice(props) {
|
|
|
296
470
|
} catch (error2) {
|
|
297
471
|
setError(error2 instanceof Error ? error2.message : "Could not save your selection. Try again.");
|
|
298
472
|
} finally {
|
|
473
|
+
inFlight.current = false;
|
|
299
474
|
setSaving(false);
|
|
300
475
|
}
|
|
301
476
|
}, children: [
|
|
302
|
-
/* @__PURE__ */
|
|
303
|
-
/* @__PURE__ */
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
required: true,
|
|
319
|
-
minLength: 2,
|
|
320
|
-
maxLength: 160,
|
|
321
|
-
value: name,
|
|
322
|
-
onInput: (event) => {
|
|
323
|
-
setName(event.currentTarget.value);
|
|
324
|
-
edit(selected, event.currentTarget.value);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
)
|
|
328
|
-
] }),
|
|
329
|
-
/* @__PURE__ */ jsxs3("label", { children: [
|
|
330
|
-
"Email",
|
|
331
|
-
/* @__PURE__ */ jsx3(
|
|
332
|
-
"input",
|
|
333
|
-
{
|
|
334
|
-
required: true,
|
|
335
|
-
type: "email",
|
|
336
|
-
maxLength: 254,
|
|
337
|
-
value: email,
|
|
338
|
-
onInput: (event) => {
|
|
339
|
-
setEmail(event.currentTarget.value);
|
|
340
|
-
edit(selected, name, event.currentTarget.value);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
)
|
|
344
|
-
] }),
|
|
345
|
-
/* @__PURE__ */ jsx3("p", { children: "For one named person, who completes their own application and any required interview. Non-transferable; renews and ends with your membership." })
|
|
346
|
-
] }) : /* @__PURE__ */ jsx3("p", { children: "You can add someone from your member page after paying." }),
|
|
347
|
-
dirty ? /* @__PURE__ */ jsx3("button", { type: "submit", disabled: saving, children: saving ? "Saving\u2026" : amount === 0 ? "Save member details" : "Update total" }) : null
|
|
477
|
+
/* @__PURE__ */ jsxs5("fieldset", { disabled: props.locked || saving, children: [
|
|
478
|
+
/* @__PURE__ */ jsx6(
|
|
479
|
+
AdditionalMemberFields,
|
|
480
|
+
{
|
|
481
|
+
value: { selected, name, email },
|
|
482
|
+
offer: { ...props.quote.seatOffer, currency: props.quote.currency, interval: props.quote.interval },
|
|
483
|
+
onChange: (value) => {
|
|
484
|
+
setSelected(value.selected);
|
|
485
|
+
setName(value.name);
|
|
486
|
+
setEmail(value.email);
|
|
487
|
+
edit(value.selected, value.name, value.email);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
),
|
|
491
|
+
selected ? /* @__PURE__ */ jsx6("p", { children: "For one named person, who completes their own application and any required interview. Non-transferable; renews and ends with your membership." }) : /* @__PURE__ */ jsx6("p", { children: "You can add someone from your member page after paying." }),
|
|
492
|
+
dirty ? /* @__PURE__ */ jsx6(JoinSubmitButton, { disabled: saving || !ready || !valid, children: saving ? "Saving\u2026" : "Save details" }) : null
|
|
348
493
|
] }),
|
|
349
|
-
error ? /* @__PURE__ */
|
|
494
|
+
error ? /* @__PURE__ */ jsx6("p", { role: "alert", children: error }) : null
|
|
350
495
|
] }) });
|
|
351
496
|
}
|
|
352
497
|
|
|
353
498
|
// src/ui/checkout-seat-review.tsx
|
|
354
|
-
import { jsx as
|
|
499
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
355
500
|
function CheckoutSeatReview({ quote, label, locked, onEdit }) {
|
|
356
501
|
if (!quote.namedSeat) return null;
|
|
357
|
-
return /* @__PURE__ */
|
|
358
|
-
/* @__PURE__ */
|
|
359
|
-
/* @__PURE__ */
|
|
502
|
+
return /* @__PURE__ */ jsxs6("section", { className: "checkout-seat-review", "aria-label": label, children: [
|
|
503
|
+
/* @__PURE__ */ jsx7("h3", { children: label }),
|
|
504
|
+
/* @__PURE__ */ jsxs6("p", { children: [
|
|
360
505
|
quote.namedSeat.recipientName,
|
|
361
|
-
/* @__PURE__ */
|
|
506
|
+
/* @__PURE__ */ jsx7("br", {}),
|
|
362
507
|
quote.namedSeat.recipientEmail
|
|
363
508
|
] }),
|
|
364
|
-
!locked ? /* @__PURE__ */
|
|
509
|
+
!locked ? /* @__PURE__ */ jsx7("button", { type: "button", onClick: onEdit, children: "Edit details" }) : null
|
|
365
510
|
] });
|
|
366
511
|
}
|
|
367
512
|
|
|
368
513
|
// src/ui/membership-payment-step.tsx
|
|
369
|
-
import { Fragment as
|
|
514
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
370
515
|
function MembershipPaymentStep(props) {
|
|
516
|
+
const renderEditor = props.renderNamedSeatEditor ?? (props.additionalMember ? (context) => /* @__PURE__ */ jsx8(AdditionalMemberEditor, { ...props.additionalMember, ...context }) : void 0);
|
|
371
517
|
const inherited = useChapterCopy();
|
|
372
518
|
const copy = props.copy ?? inherited.join.payment;
|
|
373
|
-
const [quote, setQuote] =
|
|
374
|
-
const [locked, setLocked] =
|
|
375
|
-
const [prefillConsumed, setPrefillConsumed] =
|
|
376
|
-
const [error, setError] =
|
|
377
|
-
const [revision, setRevision] =
|
|
519
|
+
const [quote, setQuote] = useState6(null);
|
|
520
|
+
const [locked, setLocked] = useState6(false), [editing, setEditing] = useState6(Boolean(props.initialNamedSeat));
|
|
521
|
+
const [prefillConsumed, setPrefillConsumed] = useState6(false);
|
|
522
|
+
const [error, setError] = useState6(false);
|
|
523
|
+
const [revision, setRevision] = useState6(0);
|
|
378
524
|
useEffect(() => {
|
|
379
|
-
props.onNamedSeatEditingChange?.(Boolean(
|
|
380
|
-
}, [editing, locked, Boolean(quote), Boolean(
|
|
525
|
+
props.onNamedSeatEditingChange?.(Boolean(renderEditor && editing && !locked && quote));
|
|
526
|
+
}, [editing, locked, Boolean(quote), Boolean(renderEditor)]);
|
|
381
527
|
useEffect(() => {
|
|
382
528
|
let live = true;
|
|
383
529
|
setQuote(null);
|
|
@@ -388,7 +534,7 @@ function MembershipPaymentStep(props) {
|
|
|
388
534
|
value.checkoutStarted = response.headers.get("x-chapter-checkout-started") === "true";
|
|
389
535
|
if (value.applicationId !== props.applicationId || !/^[a-f0-9]{64}$/.test(value.digest) || !/^[a-z]{3}$/.test(value.currency) || !Number.isSafeInteger(value.lineItems?.dueTodayCents) || value.lineItems.dueTodayCents <= 0 || typeof value.refundPolicyText !== "string") throw new Error("invalid quote");
|
|
390
536
|
if (!live) return;
|
|
391
|
-
if (
|
|
537
|
+
if (renderEditor && props.initialNamedSeat && !prefillConsumed && !value.namedSeat && !value.checkoutStarted && value.seatOffer) {
|
|
392
538
|
const saved = await fetch(`/api/payments/quote?application=${encodeURIComponent(props.applicationId)}`, {
|
|
393
539
|
method: "POST",
|
|
394
540
|
cache: "no-store",
|
|
@@ -427,10 +573,10 @@ function MembershipPaymentStep(props) {
|
|
|
427
573
|
setQuote(null);
|
|
428
574
|
setRevision((value) => value + 1);
|
|
429
575
|
};
|
|
430
|
-
if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */
|
|
431
|
-
props.merchantDisclosureText ? /* @__PURE__ */
|
|
432
|
-
/* @__PURE__ */
|
|
433
|
-
error ? /* @__PURE__ */
|
|
576
|
+
if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */ jsxs7("div", { className: "join-pay", role: "status", children: [
|
|
577
|
+
props.merchantDisclosureText ? /* @__PURE__ */ jsx8("p", { className: "compliance-merchant", children: props.merchantDisclosureText }) : null,
|
|
578
|
+
/* @__PURE__ */ jsx8("p", { children: error ? copy.setupFailed : copy.preparing }),
|
|
579
|
+
error ? /* @__PURE__ */ jsx8("button", { type: "button", onClick: refresh, children: "Reload payment terms" }) : null
|
|
434
580
|
] });
|
|
435
581
|
const startCheckout = async () => {
|
|
436
582
|
setLocked(true);
|
|
@@ -470,9 +616,9 @@ function MembershipPaymentStep(props) {
|
|
|
470
616
|
setPrefillConsumed(true);
|
|
471
617
|
};
|
|
472
618
|
const pickLater = !quote.namedSeat && quote.seatOffer?.amountCents === 0;
|
|
473
|
-
if (
|
|
474
|
-
error ? /* @__PURE__ */
|
|
475
|
-
|
|
619
|
+
if (renderEditor && editing && !locked && quote.seatOffer) return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
620
|
+
error ? /* @__PURE__ */ jsx8("p", { role: "alert", children: "Enter a different recipient's full name and valid email to continue." }) : null,
|
|
621
|
+
renderEditor({
|
|
476
622
|
selection: quote.namedSeat ?? (!prefillConsumed ? props.initialNamedSeat : void 0) ?? null,
|
|
477
623
|
offer: { ...quote.seatOffer, currency: quote.currency, interval: quote.interval },
|
|
478
624
|
save: changeSeat,
|
|
@@ -483,8 +629,8 @@ function MembershipPaymentStep(props) {
|
|
|
483
629
|
}
|
|
484
630
|
})
|
|
485
631
|
] });
|
|
486
|
-
return /* @__PURE__ */
|
|
487
|
-
|
|
632
|
+
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
633
|
+
renderEditor ? /* @__PURE__ */ jsx8(
|
|
488
634
|
CheckoutSeatReview,
|
|
489
635
|
{
|
|
490
636
|
quote,
|
|
@@ -492,7 +638,7 @@ function MembershipPaymentStep(props) {
|
|
|
492
638
|
locked,
|
|
493
639
|
onEdit: () => setEditing(true)
|
|
494
640
|
}
|
|
495
|
-
) : quote.seatOffer ? /* @__PURE__ */
|
|
641
|
+
) : quote.seatOffer ? /* @__PURE__ */ jsx8(
|
|
496
642
|
CheckoutSeatChoice,
|
|
497
643
|
{
|
|
498
644
|
quote,
|
|
@@ -503,52 +649,52 @@ function MembershipPaymentStep(props) {
|
|
|
503
649
|
},
|
|
504
650
|
quote.digest
|
|
505
651
|
) : null,
|
|
506
|
-
/* @__PURE__ */
|
|
507
|
-
/* @__PURE__ */
|
|
508
|
-
quote.founding ? /* @__PURE__ */
|
|
652
|
+
/* @__PURE__ */ jsxs7("section", { className: "payment-quote", "aria-label": "Membership price", children: [
|
|
653
|
+
/* @__PURE__ */ jsx8("h3", { children: quote.tierName }),
|
|
654
|
+
quote.founding ? /* @__PURE__ */ jsx8("p", { className: "payment-founding", role: "note", "aria-label": "Founding member", children: copy.foundingMember }) : null,
|
|
509
655
|
props.renderPriceLines ? props.renderPriceLines({
|
|
510
656
|
...quote.lineItems,
|
|
511
657
|
...quote.founding ? { founding: quote.founding } : {},
|
|
512
658
|
...pickLater ? { namedSeatPickLater: true } : {},
|
|
513
659
|
...quote.presentation ? { presentation: quote.presentation } : {}
|
|
514
|
-
}) : /* @__PURE__ */
|
|
515
|
-
quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
517
|
-
/* @__PURE__ */
|
|
660
|
+
}) : /* @__PURE__ */ jsxs7("dl", { children: [
|
|
661
|
+
quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
662
|
+
/* @__PURE__ */ jsx8("dt", { children: copy.standardRate }),
|
|
663
|
+
/* @__PURE__ */ jsxs7("dd", { children: [
|
|
518
664
|
amount(quote.lineItems.standardCents),
|
|
519
665
|
" per ",
|
|
520
666
|
quote.interval
|
|
521
667
|
] }),
|
|
522
|
-
/* @__PURE__ */
|
|
523
|
-
/* @__PURE__ */
|
|
668
|
+
/* @__PURE__ */ jsx8("dt", { children: copy.yourRate }),
|
|
669
|
+
/* @__PURE__ */ jsxs7("dd", { children: [
|
|
524
670
|
amount(quote.lineItems.dueTodayCents - (quote.lineItems.namedSeatCents ?? 0)),
|
|
525
671
|
" per ",
|
|
526
672
|
quote.interval
|
|
527
673
|
] })
|
|
528
|
-
] }) : /* @__PURE__ */
|
|
529
|
-
/* @__PURE__ */
|
|
530
|
-
/* @__PURE__ */
|
|
674
|
+
] }) : /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
675
|
+
/* @__PURE__ */ jsx8("dt", { children: "Membership price" }),
|
|
676
|
+
/* @__PURE__ */ jsxs7("dd", { children: [
|
|
531
677
|
amount(quote.lineItems.standardCents),
|
|
532
678
|
" per ",
|
|
533
679
|
quote.interval
|
|
534
680
|
] }),
|
|
535
|
-
quote.lineItems.discountCents > 0 ? /* @__PURE__ */
|
|
536
|
-
/* @__PURE__ */
|
|
537
|
-
/* @__PURE__ */
|
|
681
|
+
quote.lineItems.discountCents > 0 ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
682
|
+
/* @__PURE__ */ jsx8("dt", { children: quote.founding ? copy.foundingDiscount : "Discount" }),
|
|
683
|
+
/* @__PURE__ */ jsx8("dd", { children: amount(quote.lineItems.discountCents) })
|
|
538
684
|
] }) : null
|
|
539
685
|
] }),
|
|
540
|
-
quote.namedSeat ? /* @__PURE__ */
|
|
541
|
-
/* @__PURE__ */
|
|
542
|
-
/* @__PURE__ */
|
|
686
|
+
quote.namedSeat ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
687
|
+
/* @__PURE__ */ jsx8("dt", { children: "Additional member" }),
|
|
688
|
+
/* @__PURE__ */ jsx8("dd", { children: quote.lineItems.namedSeatCents === 0 ? "Included" : amount(quote.lineItems.namedSeatCents) })
|
|
543
689
|
] }) : null,
|
|
544
|
-
pickLater ? /* @__PURE__ */
|
|
545
|
-
/* @__PURE__ */
|
|
546
|
-
/* @__PURE__ */
|
|
690
|
+
pickLater ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
691
|
+
/* @__PURE__ */ jsx8("dt", { children: "Additional member" }),
|
|
692
|
+
/* @__PURE__ */ jsx8("dd", { children: "Pick later" })
|
|
547
693
|
] }) : null,
|
|
548
|
-
/* @__PURE__ */
|
|
549
|
-
/* @__PURE__ */
|
|
694
|
+
/* @__PURE__ */ jsx8("dt", { children: "Due today" }),
|
|
695
|
+
/* @__PURE__ */ jsx8("dd", { children: amount(quote.lineItems.dueTodayCents) })
|
|
550
696
|
] }),
|
|
551
|
-
quote.namedSeat && !
|
|
697
|
+
quote.namedSeat && !renderEditor ? /* @__PURE__ */ jsxs7("p", { children: [
|
|
552
698
|
"For ",
|
|
553
699
|
quote.namedSeat.recipientName,
|
|
554
700
|
" \xB7 ",
|
|
@@ -556,8 +702,8 @@ function MembershipPaymentStep(props) {
|
|
|
556
702
|
".",
|
|
557
703
|
props.renderPriceLines ? ` Additional member: ${quote.lineItems.namedSeatCents === 0 ? "included" : amount(quote.lineItems.namedSeatCents)} in the total above.` : ""
|
|
558
704
|
] }) : null,
|
|
559
|
-
quote.commercial ? /* @__PURE__ */
|
|
560
|
-
quote.commercial.initialTermEndsAt !== void 0 ? /* @__PURE__ */
|
|
705
|
+
quote.commercial ? /* @__PURE__ */ jsxs7("div", { role: "note", "aria-label": "Renewal terms", children: [
|
|
706
|
+
quote.commercial.initialTermEndsAt !== void 0 ? /* @__PURE__ */ jsxs7("p", { children: [
|
|
561
707
|
"First renewal: ",
|
|
562
708
|
new Intl.DateTimeFormat("en-US", {
|
|
563
709
|
dateStyle: "long",
|
|
@@ -565,23 +711,23 @@ function MembershipPaymentStep(props) {
|
|
|
565
711
|
}).format(quote.commercial.initialTermEndsAt),
|
|
566
712
|
"."
|
|
567
713
|
] }) : null,
|
|
568
|
-
/* @__PURE__ */
|
|
714
|
+
/* @__PURE__ */ jsxs7("p", { children: [
|
|
569
715
|
"Renews automatically at ",
|
|
570
716
|
amount(quote.commercial.renewalCents),
|
|
571
717
|
" per ",
|
|
572
718
|
quote.interval,
|
|
573
719
|
" unless canceled before renewal."
|
|
574
720
|
] }),
|
|
575
|
-
quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */
|
|
576
|
-
quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */
|
|
721
|
+
quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */ jsx8("p", { children: "The discount applies to your first paid term only." }) : null,
|
|
722
|
+
quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */ jsx8("p", { children: "The discounted rate continues while this membership stays active." }) : null
|
|
577
723
|
] }) : null,
|
|
578
|
-
quote.trustCopy ? /* @__PURE__ */
|
|
724
|
+
quote.trustCopy ? /* @__PURE__ */ jsx8("p", { className: "pay-trust", children: quote.trustCopy }) : null
|
|
579
725
|
] }),
|
|
580
|
-
quote.namedSeat &&
|
|
581
|
-
/* @__PURE__ */
|
|
582
|
-
/* @__PURE__ */
|
|
726
|
+
quote.namedSeat && renderEditor ? /* @__PURE__ */ jsxs7("details", { className: "checkout-seat-terms", children: [
|
|
727
|
+
/* @__PURE__ */ jsx8("summary", { children: "Additional-member terms" }),
|
|
728
|
+
/* @__PURE__ */ jsx8("p", { children: "For one named person, who completes their own application and any required interview. Non-transferable; renews and ends with your membership." })
|
|
583
729
|
] }) : null,
|
|
584
|
-
!editing ? /* @__PURE__ */
|
|
730
|
+
!editing ? /* @__PURE__ */ jsx8(
|
|
585
731
|
PaymentStep,
|
|
586
732
|
{
|
|
587
733
|
...props,
|
|
@@ -592,12 +738,12 @@ function MembershipPaymentStep(props) {
|
|
|
592
738
|
startCheckout
|
|
593
739
|
},
|
|
594
740
|
quote.digest
|
|
595
|
-
) : /* @__PURE__ */
|
|
741
|
+
) : /* @__PURE__ */ jsx8("p", { role: "status", children: "Save your member selection to continue to payment." })
|
|
596
742
|
] });
|
|
597
743
|
}
|
|
598
744
|
|
|
599
745
|
// src/ui/journey-frame.tsx
|
|
600
|
-
import { jsx as
|
|
746
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
601
747
|
var styles = `
|
|
602
748
|
.chapter-journey{color:var(--ui-text,#202827);font-family:var(--ui-font-sans,inherit);line-height:1.65;max-width:46rem;margin-inline:auto;min-width:0}
|
|
603
749
|
.chapter-journey *{box-sizing:border-box}
|
|
@@ -619,6 +765,14 @@ var styles = `
|
|
|
619
765
|
.chapter-journey :is(.slot-time,.slot-day):hover{background:var(--ui-surface-2,#f3f5f2);color:var(--ui-text,#202827);border-color:var(--ui-accent,#285c50)}
|
|
620
766
|
.chapter-journey :is(.slot-time,.slot-day)[aria-pressed=true]{background:var(--ui-accent,#285c50);color:var(--ui-on-accent,#fff)}
|
|
621
767
|
.chapter-journey button:disabled{opacity:.55;cursor:default}
|
|
768
|
+
.chapter-journey .chapter-form-primary{background:var(--ui-accent,#285c50);color:var(--ui-on-accent,#fff);width:100%;margin-top:1rem}
|
|
769
|
+
.chapter-journey .chapter-form-primary:hover:not(:disabled){filter:brightness(.92)}
|
|
770
|
+
.chapter-journey .chapter-form-primary:disabled{background:var(--ui-surface-2,#e3e8df);color:var(--ui-text-muted,#687361);opacity:1;cursor:not-allowed;transform:none;filter:none}
|
|
771
|
+
.chapter-journey .additional-member-details{padding:1rem;margin-top:1rem;background:var(--ui-surface-2,#f3f5f2);border:1px solid var(--ui-border,#dfe3df);border-radius:8px}
|
|
772
|
+
.chapter-journey .additional-member-details label:not(:first-child){margin-top:.6rem}
|
|
773
|
+
.chapter-journey .additional-member-actions .chapter-form-primary{width:auto;flex:1;margin-top:0}
|
|
774
|
+
.chapter-journey .additional-member-actions .journey-secondary{min-width:7rem}
|
|
775
|
+
@media(max-width:520px){.chapter-journey .additional-member-actions{flex-direction:column}}
|
|
622
776
|
.chapter-journey :where(.compliance-box,.journey-note){padding:1.2rem;background:var(--ui-surface-2,#f3f5f2);border-radius:10px;margin-block:1.2rem}
|
|
623
777
|
.chapter-journey :where(.compliance-box p:last-child,.journey-note p:last-child,.card p:last-child){margin-bottom:0}
|
|
624
778
|
.chapter-journey .journey-invitation{padding:1.1rem 1.3rem;border-left:3px solid var(--ui-accent,#285c50);background:var(--ui-surface-2,#f3f5f2);border-radius:0 10px 10px 0;margin-block:1rem}
|
|
@@ -634,21 +788,21 @@ var styles = `
|
|
|
634
788
|
@media(max-width:520px){.chapter-journey .journey-actions>*{width:100%}.chapter-journey .journey-summary{grid-template-columns:1fr}.chapter-journey .journey-summary dd{text-align:left}.chapter-journey :where(.card,.join-form,.payment-quote,.join-book){padding:1.25rem}}
|
|
635
789
|
`;
|
|
636
790
|
function JourneyFrame({ children }) {
|
|
637
|
-
return /* @__PURE__ */
|
|
638
|
-
/* @__PURE__ */
|
|
791
|
+
return /* @__PURE__ */ jsxs8("div", { className: "chapter-journey", children: [
|
|
792
|
+
/* @__PURE__ */ jsx9("style", { children: styles }),
|
|
639
793
|
children
|
|
640
794
|
] });
|
|
641
795
|
}
|
|
642
796
|
|
|
643
797
|
// src/ui/member-restart.tsx
|
|
644
|
-
import { jsx as
|
|
798
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
645
799
|
function MemberRestart(props) {
|
|
646
|
-
const [id, setId] =
|
|
647
|
-
const [busy, setBusy] =
|
|
648
|
-
const [error, setError] =
|
|
649
|
-
const [paid, setPaid] =
|
|
650
|
-
const [checking, setChecking] =
|
|
651
|
-
const [revision, setRevision] =
|
|
800
|
+
const [id, setId] = useState7(props.applicationId);
|
|
801
|
+
const [busy, setBusy] = useState7(false);
|
|
802
|
+
const [error, setError] = useState7("");
|
|
803
|
+
const [paid, setPaid] = useState7(false);
|
|
804
|
+
const [checking, setChecking] = useState7(false);
|
|
805
|
+
const [revision, setRevision] = useState7(0);
|
|
652
806
|
useEffect2(() => {
|
|
653
807
|
if (!paid) return;
|
|
654
808
|
let live = true, timer, attempt = 0;
|
|
@@ -686,40 +840,40 @@ function MemberRestart(props) {
|
|
|
686
840
|
setBusy(false);
|
|
687
841
|
}
|
|
688
842
|
};
|
|
689
|
-
return /* @__PURE__ */
|
|
690
|
-
/* @__PURE__ */
|
|
691
|
-
/* @__PURE__ */
|
|
692
|
-
/* @__PURE__ */
|
|
693
|
-
/* @__PURE__ */
|
|
694
|
-
/* @__PURE__ */
|
|
695
|
-
/* @__PURE__ */
|
|
696
|
-
/* @__PURE__ */
|
|
697
|
-
/* @__PURE__ */
|
|
843
|
+
return /* @__PURE__ */ jsx10(JourneyFrame, { children: /* @__PURE__ */ jsxs9("section", { className: "card", "aria-label": "Restart membership", children: [
|
|
844
|
+
/* @__PURE__ */ jsx10("p", { className: "card-label", children: "Welcome back" }),
|
|
845
|
+
/* @__PURE__ */ jsx10("h2", { children: "Restart your membership" }),
|
|
846
|
+
/* @__PURE__ */ jsx10("p", { children: "Your account is ready, and your previous approval still counts. No new application or interview is needed." }),
|
|
847
|
+
/* @__PURE__ */ jsxs9("dl", { className: "journey-summary", children: [
|
|
848
|
+
/* @__PURE__ */ jsx10("dt", { children: "Name" }),
|
|
849
|
+
/* @__PURE__ */ jsx10("dd", { children: [props.application.firstName, props.application.lastName].filter(Boolean).join(" ") }),
|
|
850
|
+
/* @__PURE__ */ jsx10("dt", { children: "Email" }),
|
|
851
|
+
/* @__PURE__ */ jsx10("dd", { children: props.application.email })
|
|
698
852
|
] }),
|
|
699
|
-
paid ? /* @__PURE__ */
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
/* @__PURE__ */
|
|
702
|
-
!checking ? /* @__PURE__ */
|
|
703
|
-
] }) : id ? /* @__PURE__ */
|
|
704
|
-
error ? /* @__PURE__ */
|
|
853
|
+
paid ? /* @__PURE__ */ jsxs9("div", { role: "status", children: [
|
|
854
|
+
/* @__PURE__ */ jsx10("h3", { children: "Confirming your membership" }),
|
|
855
|
+
/* @__PURE__ */ jsx10("p", { children: "We\u2019re waiting for payment confirmation. Your membership will open here as soon as it arrives." }),
|
|
856
|
+
!checking ? /* @__PURE__ */ jsx10("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Check membership" }) : null
|
|
857
|
+
] }) : id ? /* @__PURE__ */ jsx10(MembershipPaymentStep, { applicationId: id, refundPolicyText: "", onPaid: () => setPaid(true) }) : /* @__PURE__ */ jsx10("button", { type: "button", disabled: busy, onClick: () => void start(), children: busy ? "Preparing your membership\u2026" : "Review membership and payment" }),
|
|
858
|
+
error ? /* @__PURE__ */ jsx10("p", { role: "alert", children: error }) : null
|
|
705
859
|
] }) });
|
|
706
860
|
}
|
|
707
861
|
|
|
708
862
|
// src/ui/members.tsx
|
|
709
|
-
import { useEffect as useEffect6, useState as
|
|
863
|
+
import { useEffect as useEffect6, useState as useState12 } from "preact/hooks";
|
|
710
864
|
|
|
711
865
|
// src/ui/reschedule.tsx
|
|
712
|
-
import { useState as
|
|
713
|
-
import { jsx as
|
|
866
|
+
import { useState as useState8 } from "preact/hooks";
|
|
867
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
714
868
|
function Rescheduler(props) {
|
|
715
869
|
const inheritedCopy = useChapterCopy();
|
|
716
870
|
const copy = props.copy ?? inheritedCopy.members.reschedule;
|
|
717
871
|
const { api, applicationId, timezone, onRescheduled, label = copy.changeTime } = props;
|
|
718
|
-
const [open, setOpen] =
|
|
719
|
-
const [slots, setSlots] =
|
|
720
|
-
const [tz, setTz] =
|
|
721
|
-
const [busy, setBusy] =
|
|
722
|
-
const [msg, setMsg] =
|
|
872
|
+
const [open, setOpen] = useState8(false);
|
|
873
|
+
const [slots, setSlots] = useState8(null);
|
|
874
|
+
const [tz, setTz] = useState8(timezone);
|
|
875
|
+
const [busy, setBusy] = useState8(false);
|
|
876
|
+
const [msg, setMsg] = useState8(null);
|
|
723
877
|
const start = async () => {
|
|
724
878
|
setOpen(true);
|
|
725
879
|
setSlots(null);
|
|
@@ -752,7 +906,7 @@ function Rescheduler(props) {
|
|
|
752
906
|
}
|
|
753
907
|
};
|
|
754
908
|
if (!open) {
|
|
755
|
-
return /* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: /* @__PURE__ */ jsx11(
|
|
756
910
|
"a",
|
|
757
911
|
{
|
|
758
912
|
href: "#",
|
|
@@ -764,8 +918,8 @@ function Rescheduler(props) {
|
|
|
764
918
|
}
|
|
765
919
|
) });
|
|
766
920
|
}
|
|
767
|
-
return /* @__PURE__ */
|
|
768
|
-
slots === null ? /* @__PURE__ */
|
|
921
|
+
return /* @__PURE__ */ jsxs10("div", { className: "msched", children: [
|
|
922
|
+
slots === null ? /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: copy.loading }) : slots.length === 0 ? /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: msg ?? copy.noTimes }) : /* @__PURE__ */ jsx11(
|
|
769
923
|
SlotPicker,
|
|
770
924
|
{
|
|
771
925
|
slots,
|
|
@@ -774,9 +928,9 @@ function Rescheduler(props) {
|
|
|
774
928
|
onPick: (s) => void pick(s)
|
|
775
929
|
}
|
|
776
930
|
),
|
|
777
|
-
busy ? /* @__PURE__ */
|
|
778
|
-
msg && slots && slots.length > 0 ? /* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
931
|
+
busy ? /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: copy.rescheduling }) : null,
|
|
932
|
+
msg && slots && slots.length > 0 ? /* @__PURE__ */ jsx11("p", { className: "meeting-note error", children: msg }) : null,
|
|
933
|
+
/* @__PURE__ */ jsx11("p", { className: "meeting-note", children: /* @__PURE__ */ jsx11(
|
|
780
934
|
"a",
|
|
781
935
|
{
|
|
782
936
|
href: "#",
|
|
@@ -791,32 +945,32 @@ function Rescheduler(props) {
|
|
|
791
945
|
}
|
|
792
946
|
|
|
793
947
|
// src/ui/member-gifts.tsx
|
|
794
|
-
import { useEffect as useEffect3, useRef as
|
|
948
|
+
import { useEffect as useEffect3, useRef as useRef5, useState as useState9 } from "preact/hooks";
|
|
795
949
|
|
|
796
950
|
// src/ui/gift-offer-cards.tsx
|
|
797
|
-
import { jsx as
|
|
951
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "preact/jsx-runtime";
|
|
798
952
|
var price = (cents, currency) => currency === "usd" ? fmtMoney(cents) : new Intl.NumberFormat(void 0, { style: "currency", currency: currency.toUpperCase() }).format(cents / 100);
|
|
799
953
|
function GiftOfferCards(props) {
|
|
800
954
|
const mode = props.mode ?? "preview";
|
|
801
|
-
return /* @__PURE__ */
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
804
|
-
/* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ jsx12("section", { className: "chapter-gift-offers", "aria-label": props.ariaLabel ?? "Gift options", children: props.offers.map((offer) => /* @__PURE__ */ jsxs11("article", { className: "card chapter-gift-offer", "data-offer-id": offer.id, children: [
|
|
956
|
+
/* @__PURE__ */ jsx12("div", { className: "card-label", children: offer.title }),
|
|
957
|
+
/* @__PURE__ */ jsx12("p", { children: offer.description }),
|
|
958
|
+
/* @__PURE__ */ jsxs11("p", { className: "meeting-date", children: [
|
|
805
959
|
price(offer.priceCents, offer.currency),
|
|
806
960
|
offer.billingMode === "subscription" ? " recurring" : ""
|
|
807
961
|
] }),
|
|
808
|
-
mode === "select" ? /* @__PURE__ */
|
|
962
|
+
mode === "select" ? /* @__PURE__ */ jsx12("button", { type: "button", className: "btn secondary", "aria-pressed": props.selectedOfferId === offer.id, onClick: () => props.onSelect?.(offer.id), children: offer.ctaLabel }) : /* @__PURE__ */ jsx12("span", { className: "btn secondary", "aria-disabled": "true", children: offer.ctaLabel })
|
|
809
963
|
] }, offer.id)) });
|
|
810
964
|
}
|
|
811
965
|
|
|
812
966
|
// src/ui/member-gifts.tsx
|
|
813
|
-
import { jsx as
|
|
967
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
814
968
|
function GiftPurchases(props) {
|
|
815
|
-
const [data, setData] =
|
|
816
|
-
const [selected, setSelected] =
|
|
817
|
-
const [code, setCode] =
|
|
818
|
-
const [message, setMessage] =
|
|
819
|
-
const purchaseId =
|
|
969
|
+
const [data, setData] = useState9(null);
|
|
970
|
+
const [selected, setSelected] = useState9(null);
|
|
971
|
+
const [code, setCode] = useState9("");
|
|
972
|
+
const [message, setMessage] = useState9("");
|
|
973
|
+
const purchaseId = useRef5(crypto.randomUUID());
|
|
820
974
|
const load = async () => setData(await props.api("/api/gifts"));
|
|
821
975
|
useEffect3(() => {
|
|
822
976
|
void load().catch(() => setData({ offers: [], claims: [] }));
|
|
@@ -833,16 +987,16 @@ function GiftPurchases(props) {
|
|
|
833
987
|
if (!data) return null;
|
|
834
988
|
if (data.offers.length === 0 && data.claims.length === 0) return null;
|
|
835
989
|
const offer = data.offers.find((item) => item.id === selected);
|
|
836
|
-
return /* @__PURE__ */
|
|
837
|
-
data.offers.length ? /* @__PURE__ */
|
|
838
|
-
/* @__PURE__ */
|
|
839
|
-
/* @__PURE__ */
|
|
840
|
-
/* @__PURE__ */
|
|
990
|
+
return /* @__PURE__ */ jsxs12("section", { className: "member-gifts", children: [
|
|
991
|
+
data.offers.length ? /* @__PURE__ */ jsxs12("div", { className: "card", children: [
|
|
992
|
+
/* @__PURE__ */ jsx13("div", { className: "card-label", children: props.copy.title }),
|
|
993
|
+
/* @__PURE__ */ jsx13("p", { children: props.copy.body }),
|
|
994
|
+
/* @__PURE__ */ jsx13(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
|
|
841
995
|
setSelected(id);
|
|
842
996
|
setCode("");
|
|
843
997
|
purchaseId.current = crypto.randomUUID();
|
|
844
998
|
} }),
|
|
845
|
-
offer ? /* @__PURE__ */
|
|
999
|
+
offer ? /* @__PURE__ */ jsx13(
|
|
846
1000
|
PaymentStep,
|
|
847
1001
|
{
|
|
848
1002
|
applicationId: purchaseId.current,
|
|
@@ -862,27 +1016,27 @@ function GiftPurchases(props) {
|
|
|
862
1016
|
}
|
|
863
1017
|
}
|
|
864
1018
|
) : null,
|
|
865
|
-
code ? /* @__PURE__ */
|
|
866
|
-
/* @__PURE__ */
|
|
867
|
-
/* @__PURE__ */
|
|
1019
|
+
code ? /* @__PURE__ */ jsxs12("div", { className: "gift-code-once", children: [
|
|
1020
|
+
/* @__PURE__ */ jsx13("output", { children: code }),
|
|
1021
|
+
/* @__PURE__ */ jsx13("p", { children: props.copy.saveCode })
|
|
868
1022
|
] }) : null
|
|
869
1023
|
] }) : null,
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
872
|
-
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
/* @__PURE__ */
|
|
875
|
-
claim.status === "pending" ? /* @__PURE__ */
|
|
876
|
-
] }, claim.id)) : /* @__PURE__ */
|
|
877
|
-
message ? /* @__PURE__ */
|
|
1024
|
+
/* @__PURE__ */ jsxs12("div", { className: "card", children: [
|
|
1025
|
+
/* @__PURE__ */ jsx13("div", { className: "card-label", children: props.copy.purchases }),
|
|
1026
|
+
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs12("div", { className: "member-row", children: [
|
|
1027
|
+
/* @__PURE__ */ jsx13("span", { children: claim.offerId }),
|
|
1028
|
+
/* @__PURE__ */ jsx13("span", { children: props.copy[claim.status] }),
|
|
1029
|
+
claim.status === "pending" ? /* @__PURE__ */ jsx13("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
|
|
1030
|
+
] }, claim.id)) : /* @__PURE__ */ jsx13("p", { children: props.copy.noPurchases }),
|
|
1031
|
+
message ? /* @__PURE__ */ jsx13("p", { role: "status", children: message }) : null
|
|
878
1032
|
] })
|
|
879
1033
|
] });
|
|
880
1034
|
}
|
|
881
1035
|
var MemberGifts = GiftPurchases;
|
|
882
1036
|
|
|
883
1037
|
// src/ui/member-named-seat.tsx
|
|
884
|
-
import { useEffect as useEffect4, useState as
|
|
885
|
-
import { Fragment as
|
|
1038
|
+
import { useEffect as useEffect4, useState as useState10 } from "preact/hooks";
|
|
1039
|
+
import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
886
1040
|
var NAMED_SEAT_RECIPIENT_WORDS = {
|
|
887
1041
|
payment_pending: "payment in progress",
|
|
888
1042
|
invited: "invited, waiting for them to accept",
|
|
@@ -894,8 +1048,8 @@ var NAMED_SEAT_RECIPIENT_WORDS = {
|
|
|
894
1048
|
};
|
|
895
1049
|
var day = (at) => new Date(at).toLocaleDateString("en-US", { timeZone: "UTC" });
|
|
896
1050
|
function NamedSeatRecipientLine({ seat }) {
|
|
897
|
-
const words = NAMED_SEAT_RECIPIENT_WORDS[seat.recipientState] ?? seat.status.replaceAll("_", " ");
|
|
898
|
-
return /* @__PURE__ */
|
|
1051
|
+
const words = seat.invitationHeld ? "named; the invitation is sent once your membership is approved" : NAMED_SEAT_RECIPIENT_WORDS[seat.recipientState] ?? seat.status.replaceAll("_", " ");
|
|
1052
|
+
return /* @__PURE__ */ jsxs13("p", { className: "member-named-seat-recipient", children: [
|
|
899
1053
|
seat.recipientName,
|
|
900
1054
|
" \xB7 ",
|
|
901
1055
|
seat.recipientEmail,
|
|
@@ -905,9 +1059,10 @@ function NamedSeatRecipientLine({ seat }) {
|
|
|
905
1059
|
] });
|
|
906
1060
|
}
|
|
907
1061
|
function NamedSeatPurchase({ api }) {
|
|
908
|
-
const [data, setData] =
|
|
909
|
-
const [name, setName] =
|
|
910
|
-
const [terms, setTerms] =
|
|
1062
|
+
const [data, setData] = useState10(null), [error, setError] = useState10("");
|
|
1063
|
+
const [name, setName] = useState10(""), [email, setEmail] = useState10(""), [reviewing, setReviewing] = useState10(false);
|
|
1064
|
+
const [terms, setTerms] = useState10(false), [pending, setPending] = useState10(false), [granting, setGranting] = useState10(false);
|
|
1065
|
+
const [renaming, setRenaming] = useState10(false), [nextName, setNextName] = useState10(""), [nextEmail, setNextEmail] = useState10("");
|
|
911
1066
|
const load = async () => {
|
|
912
1067
|
try {
|
|
913
1068
|
const value = await api("/api/named-seat");
|
|
@@ -944,13 +1099,56 @@ function NamedSeatPurchase({ api }) {
|
|
|
944
1099
|
}
|
|
945
1100
|
};
|
|
946
1101
|
const money = data ? new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100) : "";
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1102
|
+
const regift = async (event) => {
|
|
1103
|
+
event.preventDefault();
|
|
1104
|
+
setGranting(true);
|
|
1105
|
+
setError("");
|
|
1106
|
+
try {
|
|
1107
|
+
await api("/api/named-seat/regift", {
|
|
1108
|
+
method: "POST",
|
|
1109
|
+
headers: { "content-type": "application/json" },
|
|
1110
|
+
body: JSON.stringify({ recipientName: nextName, recipientEmail: nextEmail })
|
|
1111
|
+
});
|
|
1112
|
+
setRenaming(false);
|
|
1113
|
+
await load();
|
|
1114
|
+
} catch {
|
|
1115
|
+
setError("The seat could not be given to someone else. Refresh to check its status before trying again.");
|
|
1116
|
+
} finally {
|
|
1117
|
+
setGranting(false);
|
|
1118
|
+
}
|
|
1119
|
+
};
|
|
1120
|
+
return /* @__PURE__ */ jsx14(JourneyFrame, { children: /* @__PURE__ */ jsxs13("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
|
|
1121
|
+
/* @__PURE__ */ jsx14("h2", { children: "Named additional seat" }),
|
|
1122
|
+
error ? /* @__PURE__ */ jsx14("p", { role: "alert", children: error }) : null,
|
|
1123
|
+
data ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1124
|
+
data.seat ? /* @__PURE__ */ jsx14(NamedSeatRecipientLine, { seat: data.seat }) : null,
|
|
1125
|
+
data.seat?.regiftable && !renaming ? /* @__PURE__ */ jsx14("button", { className: "btn secondary", type: "button", onClick: () => {
|
|
1126
|
+
setRenaming(true);
|
|
1127
|
+
setNextName("");
|
|
1128
|
+
setNextEmail("");
|
|
1129
|
+
}, children: "Give the seat to someone else" }) : null,
|
|
1130
|
+
data.seat?.regiftable && renaming ? /* @__PURE__ */ jsxs13("form", { className: "member-named-seat-regift", "aria-label": "Give the seat to someone else", onSubmit: (event) => void regift(event), children: [
|
|
1131
|
+
/* @__PURE__ */ jsxs13("p", { children: [
|
|
1132
|
+
"The seat moves to the person you name here. ",
|
|
1133
|
+
data.seat.recipientName,
|
|
1134
|
+
"'s invitation stops working, and nothing is charged or refunded."
|
|
1135
|
+
] }),
|
|
1136
|
+
/* @__PURE__ */ jsxs13("label", { children: [
|
|
1137
|
+
"New recipient name",
|
|
1138
|
+
/* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: nextName, onInput: (event) => setNextName(event.currentTarget.value) })
|
|
1139
|
+
] }),
|
|
1140
|
+
/* @__PURE__ */ jsxs13("label", { children: [
|
|
1141
|
+
"New recipient email",
|
|
1142
|
+
/* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: nextEmail, onInput: (event) => setNextEmail(event.currentTarget.value) })
|
|
1143
|
+
] }),
|
|
1144
|
+
/* @__PURE__ */ jsx14("button", { className: "btn primary", type: "submit", disabled: granting, children: granting ? "Changing the recipient\u2026" : "Give the seat to this person" }),
|
|
1145
|
+
/* @__PURE__ */ jsxs13("button", { className: "btn secondary", type: "button", disabled: granting, onClick: () => setRenaming(false), children: [
|
|
1146
|
+
"Keep ",
|
|
1147
|
+
data.seat.recipientName
|
|
1148
|
+
] })
|
|
1149
|
+
] }) : null,
|
|
1150
|
+
data.eligible ? /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1151
|
+
/* @__PURE__ */ jsxs13("p", { children: [
|
|
954
1152
|
data.included ? "Included with your membership at no charge." : `${money} paid in full now.`,
|
|
955
1153
|
" This seat ",
|
|
956
1154
|
data.autoRenew ? "renews with your primary membership" : "ends with your primary membership",
|
|
@@ -961,39 +1159,39 @@ function NamedSeatPurchase({ api }) {
|
|
|
961
1159
|
" ",
|
|
962
1160
|
"It belongs to one named person and cannot be reassigned."
|
|
963
1161
|
] }),
|
|
964
|
-
/* @__PURE__ */
|
|
965
|
-
!reviewing ? /* @__PURE__ */
|
|
1162
|
+
/* @__PURE__ */ jsx14("p", { children: "The recipient must accept and complete their own application and any required interview. The seat stays open for them while your membership is paid; it is not refunded automatically. Contact the chapter if you need a refund." }),
|
|
1163
|
+
!reviewing ? /* @__PURE__ */ jsxs13("form", { onSubmit: (event) => {
|
|
966
1164
|
event.preventDefault();
|
|
967
1165
|
setReviewing(true);
|
|
968
1166
|
setTerms(false);
|
|
969
1167
|
}, children: [
|
|
970
|
-
/* @__PURE__ */
|
|
1168
|
+
/* @__PURE__ */ jsxs13("label", { children: [
|
|
971
1169
|
"Recipient name",
|
|
972
|
-
/* @__PURE__ */
|
|
1170
|
+
/* @__PURE__ */ jsx14("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
|
|
973
1171
|
] }),
|
|
974
|
-
/* @__PURE__ */
|
|
1172
|
+
/* @__PURE__ */ jsxs13("label", { children: [
|
|
975
1173
|
"Recipient email",
|
|
976
|
-
/* @__PURE__ */
|
|
1174
|
+
/* @__PURE__ */ jsx14("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
|
|
977
1175
|
] }),
|
|
978
|
-
/* @__PURE__ */
|
|
979
|
-
] }) : /* @__PURE__ */
|
|
980
|
-
/* @__PURE__ */
|
|
1176
|
+
/* @__PURE__ */ jsx14("button", { className: "btn primary", type: "submit", children: "Review named seat" })
|
|
1177
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1178
|
+
/* @__PURE__ */ jsxs13("p", { children: [
|
|
981
1179
|
"For ",
|
|
982
1180
|
name,
|
|
983
1181
|
" \xB7 ",
|
|
984
1182
|
email
|
|
985
1183
|
] }),
|
|
986
|
-
/* @__PURE__ */
|
|
1184
|
+
/* @__PURE__ */ jsx14("button", { className: "btn secondary", type: "button", onClick: () => {
|
|
987
1185
|
setReviewing(false);
|
|
988
1186
|
setTerms(false);
|
|
989
1187
|
void load();
|
|
990
1188
|
}, children: "Back to recipient" }),
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
993
|
-
/* @__PURE__ */
|
|
1189
|
+
/* @__PURE__ */ jsxs13("label", { className: "journey-consent", children: [
|
|
1190
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
|
|
1191
|
+
/* @__PURE__ */ jsx14("span", { children: data.included ? "I agree to the seat terms and the refund policy; the seat is included with my membership and follows its renewal." : data.autoRenew ? "I agree to the full initial payment and automatic renewal with my membership; I can cancel renewal." : "I agree to the full initial payment and the displayed end date, with no automatic renewal while my membership renewal is canceled." })
|
|
994
1192
|
] }),
|
|
995
|
-
terms && data.included ? /* @__PURE__ */
|
|
996
|
-
terms && !data.included ? /* @__PURE__ */
|
|
1193
|
+
terms && data.included ? /* @__PURE__ */ jsx14("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
|
|
1194
|
+
terms && !data.included ? /* @__PURE__ */ jsx14(
|
|
997
1195
|
PaymentStep,
|
|
998
1196
|
{
|
|
999
1197
|
applicationId: data.membershipId,
|
|
@@ -1008,17 +1206,17 @@ function NamedSeatPurchase({ api }) {
|
|
|
1008
1206
|
}
|
|
1009
1207
|
) : null
|
|
1010
1208
|
] })
|
|
1011
|
-
] }) : !data.seat ? /* @__PURE__ */
|
|
1012
|
-
pending ? /* @__PURE__ */
|
|
1013
|
-
] }) : !error ? /* @__PURE__ */
|
|
1014
|
-
/* @__PURE__ */
|
|
1209
|
+
] }) : !data.seat ? /* @__PURE__ */ jsx14("p", { children: data.purchaseWindowed === false ? "An additional seat can be purchased for as long as your membership stays paid." : `Additional seats can be purchased until ${day(data.purchaseEndsAt)}.` }) : null,
|
|
1210
|
+
pending ? /* @__PURE__ */ jsx14("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
|
|
1211
|
+
] }) : !error ? /* @__PURE__ */ jsx14("p", { children: "Loading your seat terms\u2026" }) : null,
|
|
1212
|
+
/* @__PURE__ */ jsx14("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
|
|
1015
1213
|
] }) });
|
|
1016
1214
|
}
|
|
1017
1215
|
|
|
1018
1216
|
// src/ui/member-content.tsx
|
|
1019
|
-
import { useEffect as useEffect5, useMemo as useMemo2, useState as
|
|
1217
|
+
import { useEffect as useEffect5, useMemo as useMemo2, useState as useState11 } from "preact/hooks";
|
|
1020
1218
|
import { Markdown } from "@odla-ai/ui/components";
|
|
1021
|
-
import { Fragment as
|
|
1219
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
1022
1220
|
var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
|
|
1023
1221
|
function MemberContentArea(props) {
|
|
1024
1222
|
const {
|
|
@@ -1026,12 +1224,12 @@ function MemberContentArea(props) {
|
|
|
1026
1224
|
path = "/api/member-content",
|
|
1027
1225
|
upsellHref,
|
|
1028
1226
|
onUpsell,
|
|
1029
|
-
loadingContent = /* @__PURE__ */
|
|
1030
|
-
emptyContent = /* @__PURE__ */
|
|
1227
|
+
loadingContent = /* @__PURE__ */ jsx15("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
|
|
1228
|
+
emptyContent = /* @__PURE__ */ jsx15("p", { className: "meeting-note", children: "No member pages have been published yet." })
|
|
1031
1229
|
} = props;
|
|
1032
|
-
const [data, setData] =
|
|
1033
|
-
const [error, setError] =
|
|
1034
|
-
const [selectedId, setSelectedId] =
|
|
1230
|
+
const [data, setData] = useState11(props.initialData ?? null);
|
|
1231
|
+
const [error, setError] = useState11(null);
|
|
1232
|
+
const [selectedId, setSelectedId] = useState11(
|
|
1035
1233
|
props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
|
|
1036
1234
|
);
|
|
1037
1235
|
useEffect5(() => {
|
|
@@ -1056,18 +1254,18 @@ function MemberContentArea(props) {
|
|
|
1056
1254
|
}
|
|
1057
1255
|
return [...result.entries()];
|
|
1058
1256
|
}, [data]);
|
|
1059
|
-
if (error) return /* @__PURE__ */
|
|
1257
|
+
if (error) return /* @__PURE__ */ jsxs14("p", { className: "meeting-note", role: "alert", children: [
|
|
1060
1258
|
"Member pages could not be loaded: ",
|
|
1061
1259
|
error
|
|
1062
1260
|
] });
|
|
1063
|
-
if (!data) return /* @__PURE__ */
|
|
1064
|
-
if (data.pages.length === 0) return /* @__PURE__ */
|
|
1261
|
+
if (!data) return /* @__PURE__ */ jsx15(Fragment4, { children: loadingContent });
|
|
1262
|
+
if (data.pages.length === 0) return /* @__PURE__ */ jsx15(Fragment4, { children: emptyContent });
|
|
1065
1263
|
const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
|
|
1066
1264
|
const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
|
|
1067
|
-
return /* @__PURE__ */
|
|
1068
|
-
/* @__PURE__ */
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
/* @__PURE__ */
|
|
1265
|
+
return /* @__PURE__ */ jsxs14("div", { className: "chapter-member-content", "data-member-content": true, children: [
|
|
1266
|
+
/* @__PURE__ */ jsx15("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs14("section", { className: "chapter-member-content-section", children: [
|
|
1267
|
+
/* @__PURE__ */ jsx15("h2", { children: section }),
|
|
1268
|
+
/* @__PURE__ */ jsx15("ul", { children: pages.map((page) => /* @__PURE__ */ jsx15("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx15(
|
|
1071
1269
|
"button",
|
|
1072
1270
|
{
|
|
1073
1271
|
type: "button",
|
|
@@ -1077,23 +1275,23 @@ function MemberContentArea(props) {
|
|
|
1077
1275
|
}
|
|
1078
1276
|
) }, page.id)) })
|
|
1079
1277
|
] }, section)) }),
|
|
1080
|
-
/* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1082
|
-
/* @__PURE__ */
|
|
1278
|
+
/* @__PURE__ */ jsxs14("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
|
|
1279
|
+
/* @__PURE__ */ jsxs14("header", { children: [
|
|
1280
|
+
/* @__PURE__ */ jsxs14("div", { className: "card-label", children: [
|
|
1083
1281
|
selected.source.type === "parent" ? "Parent" : "Chapter",
|
|
1084
1282
|
" \xB7 ",
|
|
1085
1283
|
selected.access
|
|
1086
1284
|
] }),
|
|
1087
|
-
/* @__PURE__ */
|
|
1088
|
-
selected.summary ? /* @__PURE__ */
|
|
1285
|
+
/* @__PURE__ */ jsx15("h1", { children: selected.title }),
|
|
1286
|
+
selected.summary ? /* @__PURE__ */ jsx15("p", { children: selected.summary }) : null
|
|
1089
1287
|
] }),
|
|
1090
|
-
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */
|
|
1091
|
-
selected.teaserMarkdown ? /* @__PURE__ */
|
|
1092
|
-
selected.upsell ? /* @__PURE__ */
|
|
1093
|
-
/* @__PURE__ */
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
selected.upsell.bodyMarkdown ? /* @__PURE__ */
|
|
1096
|
-
href ? /* @__PURE__ */
|
|
1288
|
+
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs14("div", { className: "chapter-member-content-locked", children: [
|
|
1289
|
+
selected.teaserMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx15("p", { children: "This page is not included in your current membership." }),
|
|
1290
|
+
selected.upsell ? /* @__PURE__ */ jsxs14("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
|
|
1291
|
+
/* @__PURE__ */ jsx15("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
|
|
1292
|
+
/* @__PURE__ */ jsx15("p", { children: fmtMoney(selected.upsell.priceCents) }),
|
|
1293
|
+
selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx15(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
|
|
1294
|
+
href ? /* @__PURE__ */ jsx15("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx15("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
|
|
1097
1295
|
] }) : null
|
|
1098
1296
|
] })
|
|
1099
1297
|
] })
|
|
@@ -1101,12 +1299,12 @@ function MemberContentArea(props) {
|
|
|
1101
1299
|
}
|
|
1102
1300
|
|
|
1103
1301
|
// src/ui/members.tsx
|
|
1104
|
-
import { Fragment as
|
|
1302
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
1105
1303
|
function card(copy, kicker, body) {
|
|
1106
|
-
return /* @__PURE__ */
|
|
1107
|
-
/* @__PURE__ */
|
|
1108
|
-
/* @__PURE__ */
|
|
1109
|
-
/* @__PURE__ */
|
|
1304
|
+
return /* @__PURE__ */ jsxs15("div", { className: "card", children: [
|
|
1305
|
+
/* @__PURE__ */ jsx16("div", { className: "card-label", children: copy.provisional.cardLabel }),
|
|
1306
|
+
/* @__PURE__ */ jsxs15("div", { className: "meeting-block", children: [
|
|
1307
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-kicker", children: kicker }),
|
|
1110
1308
|
body
|
|
1111
1309
|
] })
|
|
1112
1310
|
] });
|
|
@@ -1117,9 +1315,9 @@ function ProvisionalCard(props) {
|
|
|
1117
1315
|
return card(
|
|
1118
1316
|
copy,
|
|
1119
1317
|
copy.provisional.applicationNeeded,
|
|
1120
|
-
/* @__PURE__ */
|
|
1121
|
-
/* @__PURE__ */
|
|
1122
|
-
/* @__PURE__ */
|
|
1318
|
+
/* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
1319
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
|
|
1320
|
+
/* @__PURE__ */ jsx16("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
|
|
1123
1321
|
] })
|
|
1124
1322
|
);
|
|
1125
1323
|
}
|
|
@@ -1127,19 +1325,19 @@ function ProvisionalCard(props) {
|
|
|
1127
1325
|
return card(
|
|
1128
1326
|
copy,
|
|
1129
1327
|
copy.provisional.refunded,
|
|
1130
|
-
/* @__PURE__ */
|
|
1328
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.refundedBody })
|
|
1131
1329
|
);
|
|
1132
1330
|
}
|
|
1133
|
-
const membership = application.paid ? /* @__PURE__ */
|
|
1331
|
+
const membership = application.paid ? /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
|
|
1134
1332
|
if (application.meetingAt) {
|
|
1135
1333
|
return card(
|
|
1136
1334
|
copy,
|
|
1137
1335
|
copy.provisional.introductionCall,
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1141
|
-
application.meetUrl ? /* @__PURE__ */
|
|
1142
|
-
/* @__PURE__ */
|
|
1336
|
+
/* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
1337
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
|
|
1338
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
|
|
1339
|
+
application.meetUrl ? /* @__PURE__ */ jsx16("div", { className: "meeting-note", children: /* @__PURE__ */ jsx16("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
|
|
1340
|
+
/* @__PURE__ */ jsx16(
|
|
1143
1341
|
Rescheduler,
|
|
1144
1342
|
{
|
|
1145
1343
|
api,
|
|
@@ -1156,9 +1354,9 @@ function ProvisionalCard(props) {
|
|
|
1156
1354
|
return card(
|
|
1157
1355
|
copy,
|
|
1158
1356
|
copy.provisional.bookCall,
|
|
1159
|
-
/* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1161
|
-
/* @__PURE__ */
|
|
1357
|
+
/* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
1358
|
+
/* @__PURE__ */ jsx16("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
|
|
1359
|
+
/* @__PURE__ */ jsx16(
|
|
1162
1360
|
Rescheduler,
|
|
1163
1361
|
{
|
|
1164
1362
|
api,
|
|
@@ -1185,8 +1383,8 @@ function MembersArea(props) {
|
|
|
1185
1383
|
renderProvisional
|
|
1186
1384
|
} = props;
|
|
1187
1385
|
const copy = props.copy ?? inheritedCopy.members;
|
|
1188
|
-
const [me, setMe] =
|
|
1189
|
-
const [error, setError] =
|
|
1386
|
+
const [me, setMe] = useState12(null);
|
|
1387
|
+
const [error, setError] = useState12(false);
|
|
1190
1388
|
const reload = async () => {
|
|
1191
1389
|
try {
|
|
1192
1390
|
setMe(await api("/api/me"));
|
|
@@ -1197,22 +1395,22 @@ function MembersArea(props) {
|
|
|
1197
1395
|
useEffect6(() => {
|
|
1198
1396
|
void reload();
|
|
1199
1397
|
}, []);
|
|
1200
|
-
if (error) return /* @__PURE__ */
|
|
1201
|
-
if (!me) return /* @__PURE__ */
|
|
1398
|
+
if (error) return /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: copy.loadFailed });
|
|
1399
|
+
if (!me) return /* @__PURE__ */ jsx16("p", { className: "meeting-note", children: inheritedCopy.common.loading });
|
|
1202
1400
|
const role = me.role || "provisional";
|
|
1203
|
-
return /* @__PURE__ */
|
|
1204
|
-
/* @__PURE__ */
|
|
1205
|
-
/* @__PURE__ */
|
|
1206
|
-
/* @__PURE__ */
|
|
1207
|
-
/* @__PURE__ */
|
|
1401
|
+
return /* @__PURE__ */ jsxs15(Fragment5, { children: [
|
|
1402
|
+
/* @__PURE__ */ jsxs15("div", { className: "card", children: [
|
|
1403
|
+
/* @__PURE__ */ jsxs15("div", { className: "member-row", children: [
|
|
1404
|
+
/* @__PURE__ */ jsx16("span", { className: "member-email", children: me.email }),
|
|
1405
|
+
/* @__PURE__ */ jsx16("span", { className: "role-badge " + role, children: role })
|
|
1208
1406
|
] }),
|
|
1209
|
-
/* @__PURE__ */
|
|
1210
|
-
/* @__PURE__ */
|
|
1211
|
-
me.authorized || me.superAdmin ? /* @__PURE__ */
|
|
1407
|
+
/* @__PURE__ */ jsxs15("div", { className: "account-actions", children: [
|
|
1408
|
+
/* @__PURE__ */ jsx16("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
|
|
1409
|
+
me.authorized || me.superAdmin ? /* @__PURE__ */ jsx16("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
|
|
1212
1410
|
] })
|
|
1213
1411
|
] }),
|
|
1214
|
-
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */
|
|
1215
|
-
const defaultContent = /* @__PURE__ */
|
|
1412
|
+
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx16(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
|
|
1413
|
+
const defaultContent = /* @__PURE__ */ jsx16(
|
|
1216
1414
|
ProvisionalCard,
|
|
1217
1415
|
{
|
|
1218
1416
|
api,
|
|
@@ -1229,30 +1427,30 @@ function MembersArea(props) {
|
|
|
1229
1427
|
reload,
|
|
1230
1428
|
defaultContent
|
|
1231
1429
|
}) ?? defaultContent;
|
|
1232
|
-
})() : memberContent ?? (memberPages ? /* @__PURE__ */
|
|
1430
|
+
})() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx16(
|
|
1233
1431
|
MemberContentArea,
|
|
1234
1432
|
{
|
|
1235
1433
|
api,
|
|
1236
1434
|
...memberPages === true ? {} : memberPages
|
|
1237
1435
|
}
|
|
1238
|
-
) : /* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
me.namedSeatsEnabled ? /* @__PURE__ */
|
|
1436
|
+
) : /* @__PURE__ */ jsx16("div", { className: "card", children: /* @__PURE__ */ jsx16("div", { className: "card-label", children: copy.full.welcome }) })),
|
|
1437
|
+
/* @__PURE__ */ jsx16(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
|
|
1438
|
+
me.namedSeatsEnabled ? /* @__PURE__ */ jsx16(NamedSeatPurchase, { api }) : null
|
|
1241
1439
|
] });
|
|
1242
1440
|
}
|
|
1243
1441
|
|
|
1244
1442
|
// src/ui/join.tsx
|
|
1245
|
-
import { useEffect as useEffect11, useRef as
|
|
1443
|
+
import { useEffect as useEffect11, useRef as useRef7, useState as useState20 } from "preact/hooks";
|
|
1246
1444
|
|
|
1247
1445
|
// src/ui/join-booking.tsx
|
|
1248
|
-
import { useEffect as useEffect7, useState as
|
|
1249
|
-
import { jsx as
|
|
1446
|
+
import { useEffect as useEffect7, useState as useState13 } from "preact/hooks";
|
|
1447
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "preact/jsx-runtime";
|
|
1250
1448
|
function JoinBooking(props) {
|
|
1251
1449
|
const { applicationId, copy, onBooked, simulation } = props;
|
|
1252
|
-
const [state, setState] =
|
|
1253
|
-
const [msg, setMsg] =
|
|
1254
|
-
const [busy, setBusy] =
|
|
1255
|
-
const [selected, setSelected] =
|
|
1450
|
+
const [state, setState] = useState13(null);
|
|
1451
|
+
const [msg, setMsg] = useState13(null);
|
|
1452
|
+
const [busy, setBusy] = useState13(false);
|
|
1453
|
+
const [selected, setSelected] = useState13(null);
|
|
1256
1454
|
const load = async () => {
|
|
1257
1455
|
setMsg(null);
|
|
1258
1456
|
try {
|
|
@@ -1309,11 +1507,11 @@ function JoinBooking(props) {
|
|
|
1309
1507
|
setBusy(false);
|
|
1310
1508
|
}
|
|
1311
1509
|
};
|
|
1312
|
-
if (!state) return /* @__PURE__ */
|
|
1313
|
-
return /* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1315
|
-
/* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1510
|
+
if (!state) return /* @__PURE__ */ jsx17("p", { className: "slots-status", children: msg ?? copy.loading });
|
|
1511
|
+
return /* @__PURE__ */ jsxs16("div", { className: "join-book", children: [
|
|
1512
|
+
/* @__PURE__ */ jsx17("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
|
|
1513
|
+
/* @__PURE__ */ jsx17("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
|
|
1514
|
+
/* @__PURE__ */ jsx17(
|
|
1317
1515
|
SlotPicker,
|
|
1318
1516
|
{
|
|
1319
1517
|
slots: state.slots,
|
|
@@ -1323,29 +1521,29 @@ function JoinBooking(props) {
|
|
|
1323
1521
|
onDayChange: () => setSelected(null)
|
|
1324
1522
|
}
|
|
1325
1523
|
),
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
msg ? /* @__PURE__ */
|
|
1524
|
+
/* @__PURE__ */ jsxs16("div", { className: "slot-confirm", hidden: !selected, children: [
|
|
1525
|
+
/* @__PURE__ */ jsx17("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
|
|
1526
|
+
msg ? /* @__PURE__ */ jsx17("p", { className: "step2-note", children: msg }) : null
|
|
1329
1527
|
] })
|
|
1330
1528
|
] });
|
|
1331
1529
|
}
|
|
1332
1530
|
|
|
1333
1531
|
// src/ui/join-accepted.tsx
|
|
1334
|
-
import { jsx as
|
|
1532
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
1335
1533
|
function JoinAccepted(props) {
|
|
1336
|
-
return /* @__PURE__ */
|
|
1337
|
-
/* @__PURE__ */
|
|
1338
|
-
/* @__PURE__ */
|
|
1339
|
-
/* @__PURE__ */
|
|
1534
|
+
return /* @__PURE__ */ jsxs17("div", { className: "join-done card", children: [
|
|
1535
|
+
/* @__PURE__ */ jsx18("div", { className: "card-label", children: props.copy.accepted.label }),
|
|
1536
|
+
/* @__PURE__ */ jsx18("p", { className: "meeting-note", children: props.copy.accepted.body }),
|
|
1537
|
+
/* @__PURE__ */ jsx18("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
|
|
1340
1538
|
] });
|
|
1341
1539
|
}
|
|
1342
1540
|
|
|
1343
1541
|
// src/ui/gift-claim-card.tsx
|
|
1344
|
-
import { useState as
|
|
1345
|
-
import { Fragment as
|
|
1542
|
+
import { useState as useState14 } from "preact/hooks";
|
|
1543
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs18 } from "preact/jsx-runtime";
|
|
1346
1544
|
function GiftClaimCard(props) {
|
|
1347
|
-
const [code, setCode] =
|
|
1348
|
-
const [error, setError] =
|
|
1545
|
+
const [code, setCode] = useState14(props.initialCode ?? "");
|
|
1546
|
+
const [error, setError] = useState14(false);
|
|
1349
1547
|
const rotate = async () => {
|
|
1350
1548
|
if (!props.claimId) return;
|
|
1351
1549
|
setError(false);
|
|
@@ -1358,24 +1556,27 @@ function GiftClaimCard(props) {
|
|
|
1358
1556
|
if (response.ok && body.code) setCode(body.code);
|
|
1359
1557
|
else setError(true);
|
|
1360
1558
|
};
|
|
1361
|
-
return /* @__PURE__ */
|
|
1362
|
-
/* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1364
|
-
code ? /* @__PURE__ */
|
|
1365
|
-
/* @__PURE__ */
|
|
1366
|
-
/* @__PURE__ */
|
|
1559
|
+
return /* @__PURE__ */ jsxs18("div", { className: "join-done card", children: [
|
|
1560
|
+
/* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.label }),
|
|
1561
|
+
/* @__PURE__ */ jsx19("p", { className: "meeting-note", children: props.copy.body }),
|
|
1562
|
+
code ? /* @__PURE__ */ jsxs18(Fragment6, { children: [
|
|
1563
|
+
/* @__PURE__ */ jsx19("output", { className: "gift-code", children: code }),
|
|
1564
|
+
/* @__PURE__ */ jsx19("p", { children: props.copy.save })
|
|
1367
1565
|
] }) : null,
|
|
1368
|
-
!code && props.claimId ? /* @__PURE__ */
|
|
1369
|
-
error ? /* @__PURE__ */
|
|
1566
|
+
!code && props.claimId ? /* @__PURE__ */ jsx19("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
|
|
1567
|
+
error ? /* @__PURE__ */ jsx19("p", { role: "alert", children: props.copy.rotateFailed }) : null
|
|
1370
1568
|
] });
|
|
1371
1569
|
}
|
|
1372
1570
|
|
|
1571
|
+
// src/ui/join-application-form.tsx
|
|
1572
|
+
import { useRef as useRef6 } from "preact/hooks";
|
|
1573
|
+
|
|
1373
1574
|
// src/ui/join-tiers.tsx
|
|
1374
|
-
import { useState as
|
|
1375
|
-
import { Fragment as
|
|
1575
|
+
import { useState as useState15 } from "preact/hooks";
|
|
1576
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs19 } from "preact/jsx-runtime";
|
|
1376
1577
|
var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
1377
1578
|
function useTierSelection(tiers, initialTierId) {
|
|
1378
|
-
const [selectedTierId, setSelectedTierId] =
|
|
1579
|
+
const [selectedTierId, setSelectedTierId] = useState15(() => {
|
|
1379
1580
|
const preset = tiers.find((tier) => tier.id === initialTierId);
|
|
1380
1581
|
if (preset) return preset.id;
|
|
1381
1582
|
return tiers.length === 1 ? tiers[0].id : null;
|
|
@@ -1390,10 +1591,10 @@ function useTierSelection(tiers, initialTierId) {
|
|
|
1390
1591
|
};
|
|
1391
1592
|
}
|
|
1392
1593
|
function TierPlaceholder(context) {
|
|
1393
|
-
return /* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1395
|
-
context.tiers.map((tier) => /* @__PURE__ */
|
|
1396
|
-
/* @__PURE__ */
|
|
1594
|
+
return /* @__PURE__ */ jsxs19("fieldset", { "data-chapter-placeholder": "tiers", children: [
|
|
1595
|
+
/* @__PURE__ */ jsx20("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
|
|
1596
|
+
context.tiers.map((tier) => /* @__PURE__ */ jsxs19("label", { children: [
|
|
1597
|
+
/* @__PURE__ */ jsx20(
|
|
1397
1598
|
"input",
|
|
1398
1599
|
{
|
|
1399
1600
|
type: "radio",
|
|
@@ -1404,13 +1605,13 @@ function TierPlaceholder(context) {
|
|
|
1404
1605
|
}
|
|
1405
1606
|
),
|
|
1406
1607
|
tier.name,
|
|
1407
|
-
tier.founding ? /* @__PURE__ */
|
|
1608
|
+
tier.founding ? /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1408
1609
|
" \u2014 ",
|
|
1409
1610
|
joinTierMoney(tier.founding.dueTodayCents),
|
|
1410
1611
|
" founding member rate (list ",
|
|
1411
1612
|
joinTierMoney(tier.priceCents),
|
|
1412
1613
|
")"
|
|
1413
|
-
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */
|
|
1614
|
+
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
1414
1615
|
" \u2014 ",
|
|
1415
1616
|
joinTierMoney(tier.priceCents)
|
|
1416
1617
|
] })
|
|
@@ -1422,19 +1623,28 @@ function tierNeedsPayment(selected, paymentsReady) {
|
|
|
1422
1623
|
}
|
|
1423
1624
|
|
|
1424
1625
|
// src/ui/join-application-form.tsx
|
|
1425
|
-
import { jsx as
|
|
1626
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "preact/jsx-runtime";
|
|
1426
1627
|
function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
|
|
1427
|
-
const
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1628
|
+
const form = useRef6(null);
|
|
1629
|
+
const ready = useFormReadiness(form);
|
|
1630
|
+
const disabled = submitting || props.submitDisabled === true || !ready || !validJoinRecipient(props.payment?.initialNamedSeat);
|
|
1631
|
+
return /* @__PURE__ */ jsxs20("form", { ref: form, className: "join-form", onSubmit: (event) => {
|
|
1632
|
+
if (!isFormReady(event.currentTarget)) {
|
|
1633
|
+
event.preventDefault();
|
|
1634
|
+
event.currentTarget.reportValidity();
|
|
1635
|
+
return;
|
|
1636
|
+
}
|
|
1637
|
+
void submit(event);
|
|
1638
|
+
}, children: [
|
|
1639
|
+
!requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs20("fieldset", { children: [
|
|
1640
|
+
/* @__PURE__ */ jsx21("legend", { children: copy.gift.optionsLabel }),
|
|
1641
|
+
/* @__PURE__ */ jsx21("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
|
|
1642
|
+
/* @__PURE__ */ jsx21(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
|
|
1433
1643
|
] }) : null,
|
|
1434
1644
|
!requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
|
|
1435
1645
|
typeof props.children === "function" ? props.children({ invitation }) : props.children,
|
|
1436
|
-
error ? /* @__PURE__ */
|
|
1437
|
-
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */
|
|
1646
|
+
error ? /* @__PURE__ */ jsx21("p", { className: "join-error", role: "alert", children: error }) : null,
|
|
1647
|
+
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx21(JoinSubmitButton, { disabled, children: submitting ? copy.form.submitting : copy.form.submit })
|
|
1438
1648
|
] });
|
|
1439
1649
|
}
|
|
1440
1650
|
|
|
@@ -1459,8 +1669,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
|
|
|
1459
1669
|
|
|
1460
1670
|
// src/ui/gift-code-redeemer.tsx
|
|
1461
1671
|
import { InlineActionField } from "@odla-ai/ui/components";
|
|
1462
|
-
import { useState as
|
|
1463
|
-
import { Fragment as
|
|
1672
|
+
import { useState as useState16 } from "preact/hooks";
|
|
1673
|
+
import { Fragment as Fragment8, jsx as jsx22, jsxs as jsxs21 } from "preact/jsx-runtime";
|
|
1464
1674
|
var GIFT_CODE_REDEEMER_CSS = `
|
|
1465
1675
|
.gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
|
|
1466
1676
|
.gift-code-redeemer .inline-action-field-label{display:block;color:var(--ui-text-muted,#66777f);font-size:var(--ui-text-xs,.72rem);font-weight:var(--ui-weight-strong,700);letter-spacing:var(--ui-tracking-caps,.08em);text-transform:uppercase}
|
|
@@ -1475,10 +1685,10 @@ var GIFT_CODE_REDEEMER_CSS = `
|
|
|
1475
1685
|
@container (max-width:26rem){.gift-code-redeemer .inline-action-field-row{grid-template-columns:minmax(0,1fr)}.gift-code-redeemer .inline-action-field-action{width:100%}}
|
|
1476
1686
|
`;
|
|
1477
1687
|
function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
1478
|
-
const [code, setCode] =
|
|
1479
|
-
const [loading, setLoading] =
|
|
1480
|
-
const [message, setMessage] =
|
|
1481
|
-
const [messageTone, setMessageTone] =
|
|
1688
|
+
const [code, setCode] = useState16("");
|
|
1689
|
+
const [loading, setLoading] = useState16(false);
|
|
1690
|
+
const [message, setMessage] = useState16("");
|
|
1691
|
+
const [messageTone, setMessageTone] = useState16("neutral");
|
|
1482
1692
|
const normalizedCode = code.trim();
|
|
1483
1693
|
const redeem = async () => {
|
|
1484
1694
|
if (!normalizedCode || loading) return;
|
|
@@ -1505,9 +1715,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
|
1505
1715
|
setLoading(false);
|
|
1506
1716
|
}
|
|
1507
1717
|
};
|
|
1508
|
-
return /* @__PURE__ */
|
|
1509
|
-
/* @__PURE__ */
|
|
1510
|
-
/* @__PURE__ */
|
|
1718
|
+
return /* @__PURE__ */ jsxs21(Fragment8, { children: [
|
|
1719
|
+
/* @__PURE__ */ jsx22("style", { children: GIFT_CODE_REDEEMER_CSS }),
|
|
1720
|
+
/* @__PURE__ */ jsx22(
|
|
1511
1721
|
InlineActionField,
|
|
1512
1722
|
{
|
|
1513
1723
|
id,
|
|
@@ -1563,12 +1773,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
|
|
|
1563
1773
|
}
|
|
1564
1774
|
|
|
1565
1775
|
// src/ui/join-gift-claim.tsx
|
|
1566
|
-
import { jsx as
|
|
1776
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "preact/jsx-runtime";
|
|
1567
1777
|
function JoinGiftClaim(props) {
|
|
1568
|
-
return /* @__PURE__ */
|
|
1569
|
-
/* @__PURE__ */
|
|
1570
|
-
/* @__PURE__ */
|
|
1571
|
-
/* @__PURE__ */
|
|
1778
|
+
return /* @__PURE__ */ jsxs22("section", { className: "join-gift-claim card", children: [
|
|
1779
|
+
/* @__PURE__ */ jsx23("div", { className: "card-label", children: props.copy.claimTitle }),
|
|
1780
|
+
/* @__PURE__ */ jsx23("p", { children: props.copy.claimBody }),
|
|
1781
|
+
/* @__PURE__ */ jsx23(
|
|
1572
1782
|
GiftCodeRedeemer,
|
|
1573
1783
|
{
|
|
1574
1784
|
api: props.api,
|
|
@@ -1592,21 +1802,21 @@ function JoinGiftClaim(props) {
|
|
|
1592
1802
|
}
|
|
1593
1803
|
|
|
1594
1804
|
// src/ui/join-named-seat.tsx
|
|
1595
|
-
import { useState as
|
|
1596
|
-
import { jsx as
|
|
1805
|
+
import { useState as useState17 } from "preact/hooks";
|
|
1806
|
+
import { jsx as jsx24, jsxs as jsxs23 } from "preact/jsx-runtime";
|
|
1597
1807
|
function JoinNamedSeat(props) {
|
|
1598
1808
|
const seatId = props.seatId ?? "";
|
|
1599
1809
|
const inherited = useChapterCopy(), copy = props.copy ?? inherited.join.namedSeat;
|
|
1600
|
-
const [accepted, setAccepted] =
|
|
1601
|
-
return /* @__PURE__ */
|
|
1602
|
-
/* @__PURE__ */
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
/* @__PURE__ */
|
|
1605
|
-
/* @__PURE__ */
|
|
1606
|
-
/* @__PURE__ */
|
|
1810
|
+
const [accepted, setAccepted] = useState17(false), [busy, setBusy] = useState17(false), [error, setError] = useState17("");
|
|
1811
|
+
return /* @__PURE__ */ jsxs23("section", { className: "join-named-seat card", children: [
|
|
1812
|
+
/* @__PURE__ */ jsx24("h2", { children: copy.title }),
|
|
1813
|
+
/* @__PURE__ */ jsx24("p", { children: copy.body }),
|
|
1814
|
+
/* @__PURE__ */ jsxs23("label", { className: "journey-consent", children: [
|
|
1815
|
+
/* @__PURE__ */ jsx24("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
|
|
1816
|
+
/* @__PURE__ */ jsx24("span", { children: copy.consent })
|
|
1607
1817
|
] }),
|
|
1608
|
-
error ? /* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1818
|
+
error ? /* @__PURE__ */ jsx24("p", { role: "alert", children: error }) : null,
|
|
1819
|
+
/* @__PURE__ */ jsx24("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
|
|
1610
1820
|
setBusy(true);
|
|
1611
1821
|
setError("");
|
|
1612
1822
|
try {
|
|
@@ -1626,12 +1836,12 @@ function JoinNamedSeat(props) {
|
|
|
1626
1836
|
}
|
|
1627
1837
|
|
|
1628
1838
|
// src/ui/join-invitation.tsx
|
|
1629
|
-
import { useEffect as useEffect8, useState as
|
|
1630
|
-
import { jsx as
|
|
1839
|
+
import { useEffect as useEffect8, useState as useState18 } from "preact/hooks";
|
|
1840
|
+
import { jsx as jsx25, jsxs as jsxs24 } from "preact/jsx-runtime";
|
|
1631
1841
|
function useJoinInvitation(seatId, api, fallback) {
|
|
1632
|
-
const [invitation, setInvitation] =
|
|
1633
|
-
const [error, setError] =
|
|
1634
|
-
const [revision, setRevision] =
|
|
1842
|
+
const [invitation, setInvitation] = useState18(null);
|
|
1843
|
+
const [error, setError] = useState18("");
|
|
1844
|
+
const [revision, setRevision] = useState18(0);
|
|
1635
1845
|
useEffect8(() => {
|
|
1636
1846
|
let live = true;
|
|
1637
1847
|
setInvitation(null);
|
|
@@ -1654,9 +1864,9 @@ function useJoinInvitation(seatId, api, fallback) {
|
|
|
1654
1864
|
return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
|
|
1655
1865
|
}
|
|
1656
1866
|
function JoinInvitationNotice(props) {
|
|
1657
|
-
return /* @__PURE__ */
|
|
1658
|
-
/* @__PURE__ */
|
|
1659
|
-
/* @__PURE__ */
|
|
1867
|
+
return /* @__PURE__ */ jsxs24("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
|
|
1868
|
+
/* @__PURE__ */ jsx25("p", { children: /* @__PURE__ */ jsx25("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
|
|
1869
|
+
/* @__PURE__ */ jsx25("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
|
|
1660
1870
|
] });
|
|
1661
1871
|
}
|
|
1662
1872
|
|
|
@@ -1696,14 +1906,14 @@ function useJoinPending(state, loadResume, setState) {
|
|
|
1696
1906
|
}
|
|
1697
1907
|
|
|
1698
1908
|
// src/ui/payment-receipt.tsx
|
|
1699
|
-
import { useEffect as useEffect10, useState as
|
|
1700
|
-
import { Fragment as
|
|
1909
|
+
import { useEffect as useEffect10, useState as useState19 } from "preact/hooks";
|
|
1910
|
+
import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs25 } from "preact/jsx-runtime";
|
|
1701
1911
|
function PaymentReceiptCard({ applicationId }) {
|
|
1702
|
-
const [receipt, setReceipt] =
|
|
1703
|
-
const [error, setError] =
|
|
1704
|
-
const [revision, setRevision] =
|
|
1705
|
-
const [emailState, setEmailState] =
|
|
1706
|
-
const [previewEmail, setPreviewEmail] =
|
|
1912
|
+
const [receipt, setReceipt] = useState19(null);
|
|
1913
|
+
const [error, setError] = useState19("");
|
|
1914
|
+
const [revision, setRevision] = useState19(0);
|
|
1915
|
+
const [emailState, setEmailState] = useState19("idle");
|
|
1916
|
+
const [previewEmail, setPreviewEmail] = useState19(false);
|
|
1707
1917
|
const endpoint = `/api/payments/receipt?application=${encodeURIComponent(applicationId)}`;
|
|
1708
1918
|
useEffect10(() => {
|
|
1709
1919
|
let live = true, timer;
|
|
@@ -1731,9 +1941,9 @@ function PaymentReceiptCard({ applicationId }) {
|
|
|
1731
1941
|
if (timer) clearTimeout(timer);
|
|
1732
1942
|
};
|
|
1733
1943
|
}, [endpoint, revision]);
|
|
1734
|
-
if (!receipt) return error ? /* @__PURE__ */
|
|
1735
|
-
/* @__PURE__ */
|
|
1736
|
-
/* @__PURE__ */
|
|
1944
|
+
if (!receipt) return error ? /* @__PURE__ */ jsxs25("section", { "aria-label": "Payment receipt", children: [
|
|
1945
|
+
/* @__PURE__ */ jsx26("p", { role: "status", children: error }),
|
|
1946
|
+
/* @__PURE__ */ jsx26("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
|
|
1737
1947
|
] }) : null;
|
|
1738
1948
|
const money = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: receipt.currency }).format(cents / 100);
|
|
1739
1949
|
const email = async () => {
|
|
@@ -1750,45 +1960,38 @@ function PaymentReceiptCard({ applicationId }) {
|
|
|
1750
1960
|
setError("We could not confirm email delivery. You can print or save your receipt.");
|
|
1751
1961
|
}
|
|
1752
1962
|
};
|
|
1753
|
-
return /* @__PURE__ */
|
|
1754
|
-
/* @__PURE__ */
|
|
1755
|
-
/* @__PURE__ */
|
|
1756
|
-
/* @__PURE__ */
|
|
1757
|
-
/* @__PURE__ */
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
receipt.namedSeat ? /* @__PURE__ */
|
|
1760
|
-
/* @__PURE__ */
|
|
1963
|
+
return /* @__PURE__ */ jsxs25("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
|
|
1964
|
+
/* @__PURE__ */ jsx26("h2", { children: "Payment received" }),
|
|
1965
|
+
/* @__PURE__ */ jsx26("p", { children: receipt.tierName }),
|
|
1966
|
+
/* @__PURE__ */ jsxs25("dl", { className: "journey-summary", children: [
|
|
1967
|
+
/* @__PURE__ */ jsx26("dt", { children: "Membership" }),
|
|
1968
|
+
/* @__PURE__ */ jsx26("dd", { children: money(receipt.membershipCents) }),
|
|
1969
|
+
receipt.namedSeat ? /* @__PURE__ */ jsxs25(Fragment9, { children: [
|
|
1970
|
+
/* @__PURE__ */ jsxs25("dt", { children: [
|
|
1761
1971
|
"Additional member \u2014 ",
|
|
1762
1972
|
receipt.namedSeat.recipientName
|
|
1763
1973
|
] }),
|
|
1764
|
-
/* @__PURE__ */
|
|
1974
|
+
/* @__PURE__ */ jsxs25("dd", { children: [
|
|
1765
1975
|
receipt.namedSeat.amountCents === 0 ? "Included \u2014 " : "",
|
|
1766
1976
|
money(receipt.namedSeat.amountCents)
|
|
1767
1977
|
] })
|
|
1768
1978
|
] }) : null,
|
|
1769
|
-
/* @__PURE__ */
|
|
1770
|
-
/* @__PURE__ */
|
|
1979
|
+
/* @__PURE__ */ jsx26("dt", { children: "Total paid" }),
|
|
1980
|
+
/* @__PURE__ */ jsx26("dd", { children: money(receipt.totalCents) })
|
|
1771
1981
|
] }),
|
|
1772
|
-
/* @__PURE__ */
|
|
1773
|
-
/* @__PURE__ */
|
|
1774
|
-
/* @__PURE__ */
|
|
1982
|
+
/* @__PURE__ */ jsxs25("div", { className: "journey-actions", children: [
|
|
1983
|
+
/* @__PURE__ */ jsx26("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
|
|
1984
|
+
/* @__PURE__ */ jsx26("button", { type: "button", disabled: emailState !== "idle", onClick: () => void email(), children: emailState === "sending" ? "Sending\u2026" : emailState === "sent" ? "Receipt emailed" : "Email me my receipt" })
|
|
1775
1985
|
] }),
|
|
1776
|
-
emailState === "sent" ? /* @__PURE__ */
|
|
1777
|
-
error ? /* @__PURE__ */
|
|
1986
|
+
emailState === "sent" ? /* @__PURE__ */ jsx26("p", { role: "status", children: previewEmail ? "Test receipt sent to the configured test inbox." : "Sent to the email used for your payment." }) : null,
|
|
1987
|
+
error ? /* @__PURE__ */ jsx26("p", { role: "alert", children: error }) : null
|
|
1778
1988
|
] });
|
|
1779
1989
|
}
|
|
1780
1990
|
|
|
1781
|
-
// src/ui/join-recipient.ts
|
|
1782
|
-
function validJoinRecipient(recipient) {
|
|
1783
|
-
if (!recipient) return true;
|
|
1784
|
-
const name = recipient.recipientName.trim(), email = recipient.recipientEmail.trim();
|
|
1785
|
-
return name.length >= 2 && name.length <= 160 && !/[\u0000-\u001f\u007f]/.test(name) && email.length <= 254 && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
1991
|
// src/ui/join.tsx
|
|
1789
|
-
import { Fragment as
|
|
1992
|
+
import { Fragment as Fragment10, jsx as jsx27, jsxs as jsxs26 } from "preact/jsx-runtime";
|
|
1790
1993
|
function JoinIsland(props) {
|
|
1791
|
-
return /* @__PURE__ */
|
|
1994
|
+
return /* @__PURE__ */ jsx27(JourneyFrame, { children: /* @__PURE__ */ jsx27(JoinFlow, { ...props }) });
|
|
1792
1995
|
}
|
|
1793
1996
|
function JoinFlow(props) {
|
|
1794
1997
|
const inheritedCopy = useChapterCopy();
|
|
@@ -1809,14 +2012,14 @@ function JoinFlow(props) {
|
|
|
1809
2012
|
const invitation = invitationState.invitation;
|
|
1810
2013
|
const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
|
|
1811
2014
|
const selectedTier = tiers.find((tier) => tier.id === selectedTierId) ?? tierSelection.selected;
|
|
1812
|
-
const [state, setState] =
|
|
1813
|
-
const [error, setError] =
|
|
1814
|
-
const [submitting, setSubmitting] =
|
|
1815
|
-
const [editingNamedSeat, setEditingNamedSeat] =
|
|
1816
|
-
const [giftOfferId, setGiftOfferId] =
|
|
2015
|
+
const [state, setState] = useState20(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
|
|
2016
|
+
const [error, setError] = useState20(null);
|
|
2017
|
+
const [submitting, setSubmitting] = useState20(false);
|
|
2018
|
+
const [editingNamedSeat, setEditingNamedSeat] = useState20(false);
|
|
2019
|
+
const [giftOfferId, setGiftOfferId] = useState20(props.initialGiftOfferId ?? null);
|
|
1817
2020
|
const simulatedPayment = joinSimulationPayment(props.simulation, selectedTier?.priceCents ?? 0);
|
|
1818
2021
|
const simulatedBooking = props.simulation ? props.simulation.booking ?? { slots: [], timezone: "UTC" } : void 0;
|
|
1819
|
-
const submissionId =
|
|
2022
|
+
const submissionId = useRef7(null);
|
|
1820
2023
|
useEffect11(() => {
|
|
1821
2024
|
if (props.simulation) return;
|
|
1822
2025
|
const resolver = requestedSeat ? () => invitation?.applicationId ? loadJoinResume(invitation.applicationId) : Promise.resolve(null) : props.loadResume ?? (() => {
|
|
@@ -1890,13 +2093,13 @@ function JoinFlow(props) {
|
|
|
1890
2093
|
setSubmitting(false);
|
|
1891
2094
|
}
|
|
1892
2095
|
};
|
|
1893
|
-
if (requestedSeat && !invitation) return /* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
invitationState.error ? /* @__PURE__ */
|
|
2096
|
+
if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs26("section", { className: "card", "aria-live": "polite", children: [
|
|
2097
|
+
/* @__PURE__ */ jsx27("h2", { children: seatCopy.title }),
|
|
2098
|
+
/* @__PURE__ */ jsx27("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
|
|
2099
|
+
invitationState.error ? /* @__PURE__ */ jsx27("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
|
|
1897
2100
|
] });
|
|
1898
|
-
const header = /* @__PURE__ */
|
|
1899
|
-
invitation ? /* @__PURE__ */
|
|
2101
|
+
const header = /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
2102
|
+
invitation ? /* @__PURE__ */ jsx27(
|
|
1900
2103
|
JoinInvitationNotice,
|
|
1901
2104
|
{
|
|
1902
2105
|
invitation,
|
|
@@ -1910,48 +2113,48 @@ function JoinFlow(props) {
|
|
|
1910
2113
|
...invitation ? { invitation } : {},
|
|
1911
2114
|
..."applicationId" in state ? { applicationId: state.applicationId } : {}
|
|
1912
2115
|
}),
|
|
1913
|
-
!props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */
|
|
2116
|
+
!props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx27(PaymentReceiptCard, { applicationId: state.applicationId }) : null
|
|
1914
2117
|
] });
|
|
1915
2118
|
if (state.step === "closed") {
|
|
1916
|
-
return /* @__PURE__ */
|
|
2119
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1917
2120
|
header,
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
2121
|
+
/* @__PURE__ */ jsxs26("section", { className: "card", "aria-label": "Application closed", children: [
|
|
2122
|
+
/* @__PURE__ */ jsx27("h2", { children: "This application is closed" }),
|
|
2123
|
+
/* @__PURE__ */ jsx27("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
|
|
2124
|
+
/* @__PURE__ */ jsx27("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
1922
2125
|
] })
|
|
1923
2126
|
] });
|
|
1924
2127
|
}
|
|
1925
2128
|
if (state.step === "done") {
|
|
1926
|
-
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
1929
|
-
/* @__PURE__ */
|
|
1930
|
-
/* @__PURE__ */
|
|
2129
|
+
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs26("div", { className: "join-done card", children: [
|
|
2130
|
+
/* @__PURE__ */ jsx27("div", { className: "card-label", children: copy.done.label }),
|
|
2131
|
+
/* @__PURE__ */ jsx27("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
|
|
2132
|
+
/* @__PURE__ */ jsx27("p", { className: "meeting-note", children: copy.done.calendarInvite }),
|
|
2133
|
+
/* @__PURE__ */ jsx27("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
1931
2134
|
] });
|
|
1932
|
-
return /* @__PURE__ */
|
|
2135
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1933
2136
|
header,
|
|
1934
2137
|
body
|
|
1935
2138
|
] });
|
|
1936
2139
|
}
|
|
1937
2140
|
if (state.step === "accepted") {
|
|
1938
|
-
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1939
|
-
return /* @__PURE__ */
|
|
2141
|
+
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx27(JoinAccepted, { copy, membersHref });
|
|
2142
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1940
2143
|
header,
|
|
1941
2144
|
body
|
|
1942
2145
|
] });
|
|
1943
2146
|
}
|
|
1944
2147
|
if (state.step === "gift") {
|
|
1945
|
-
const body = renderGift?.(state) ?? /* @__PURE__ */
|
|
1946
|
-
return /* @__PURE__ */
|
|
2148
|
+
const body = renderGift?.(state) ?? /* @__PURE__ */ jsx27(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
|
|
2149
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1947
2150
|
header,
|
|
1948
2151
|
body
|
|
1949
2152
|
] });
|
|
1950
2153
|
}
|
|
1951
2154
|
if (state.step === "booking") {
|
|
1952
|
-
return /* @__PURE__ */
|
|
2155
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1953
2156
|
header,
|
|
1954
|
-
/* @__PURE__ */
|
|
2157
|
+
/* @__PURE__ */ jsx27(
|
|
1955
2158
|
JoinBooking,
|
|
1956
2159
|
{
|
|
1957
2160
|
applicationId: state.applicationId,
|
|
@@ -1966,9 +2169,9 @@ function JoinFlow(props) {
|
|
|
1966
2169
|
}
|
|
1967
2170
|
if (state.step === "payment") {
|
|
1968
2171
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
|
|
1969
|
-
return /* @__PURE__ */
|
|
2172
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1970
2173
|
header,
|
|
1971
|
-
/* @__PURE__ */
|
|
2174
|
+
/* @__PURE__ */ jsx27(
|
|
1972
2175
|
JoinNamedSeat,
|
|
1973
2176
|
{
|
|
1974
2177
|
api: props.namedSeatClaimApi,
|
|
@@ -1981,9 +2184,9 @@ function JoinFlow(props) {
|
|
|
1981
2184
|
] });
|
|
1982
2185
|
}
|
|
1983
2186
|
const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
|
|
1984
|
-
return /* @__PURE__ */
|
|
2187
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
1985
2188
|
header,
|
|
1986
|
-
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */
|
|
2189
|
+
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx27(
|
|
1987
2190
|
JoinGiftClaim,
|
|
1988
2191
|
{
|
|
1989
2192
|
api: props.giftClaimApi,
|
|
@@ -1994,7 +2197,7 @@ function JoinFlow(props) {
|
|
|
1994
2197
|
onError: () => setError(copy.form.unexpectedFailure)
|
|
1995
2198
|
}
|
|
1996
2199
|
) : null,
|
|
1997
|
-
/* @__PURE__ */
|
|
2200
|
+
/* @__PURE__ */ jsx27(
|
|
1998
2201
|
Payment,
|
|
1999
2202
|
{
|
|
2000
2203
|
applicationId: state.applicationId,
|
|
@@ -2022,9 +2225,9 @@ function JoinFlow(props) {
|
|
|
2022
2225
|
}
|
|
2023
2226
|
if (state.step === "paymentPending") {
|
|
2024
2227
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
|
|
2025
|
-
return /* @__PURE__ */
|
|
2228
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
2026
2229
|
header,
|
|
2027
|
-
/* @__PURE__ */
|
|
2230
|
+
/* @__PURE__ */ jsx27(
|
|
2028
2231
|
JoinNamedSeat,
|
|
2029
2232
|
{
|
|
2030
2233
|
api: props.namedSeatClaimApi,
|
|
@@ -2036,14 +2239,14 @@ function JoinFlow(props) {
|
|
|
2036
2239
|
)
|
|
2037
2240
|
] });
|
|
2038
2241
|
}
|
|
2039
|
-
return /* @__PURE__ */
|
|
2242
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
2040
2243
|
header,
|
|
2041
|
-
/* @__PURE__ */
|
|
2244
|
+
/* @__PURE__ */ jsx27("p", { className: "pay-status", role: "status", children: copy.payment.pending })
|
|
2042
2245
|
] });
|
|
2043
2246
|
}
|
|
2044
|
-
return /* @__PURE__ */
|
|
2247
|
+
return /* @__PURE__ */ jsxs26(Fragment10, { children: [
|
|
2045
2248
|
header,
|
|
2046
|
-
/* @__PURE__ */
|
|
2249
|
+
/* @__PURE__ */ jsx27(
|
|
2047
2250
|
JoinApplicationForm,
|
|
2048
2251
|
{
|
|
2049
2252
|
props,
|
|
@@ -2233,7 +2436,7 @@ function membershipPageDocument(input, options = {}) {
|
|
|
2233
2436
|
}
|
|
2234
2437
|
|
|
2235
2438
|
// src/ui/membership-cards.tsx
|
|
2236
|
-
import { jsx as
|
|
2439
|
+
import { jsx as jsx28, jsxs as jsxs27 } from "preact/jsx-runtime";
|
|
2237
2440
|
var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
|
|
2238
2441
|
"--ui-membership-grid-gap": "1.4rem",
|
|
2239
2442
|
"--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
|
|
@@ -2302,67 +2505,67 @@ function membershipApplicationHref(applicationPath, tierId) {
|
|
|
2302
2505
|
}
|
|
2303
2506
|
function TierAction(props) {
|
|
2304
2507
|
if (props.mode === "select") {
|
|
2305
|
-
return /* @__PURE__ */
|
|
2508
|
+
return /* @__PURE__ */ jsxs27("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
|
|
2306
2509
|
props.label,
|
|
2307
|
-
/* @__PURE__ */
|
|
2510
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
|
|
2308
2511
|
] });
|
|
2309
2512
|
}
|
|
2310
2513
|
if (props.mode === "preview") {
|
|
2311
|
-
return /* @__PURE__ */
|
|
2514
|
+
return /* @__PURE__ */ jsxs27("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
|
|
2312
2515
|
props.label,
|
|
2313
|
-
/* @__PURE__ */
|
|
2516
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
|
|
2314
2517
|
] });
|
|
2315
2518
|
}
|
|
2316
|
-
return /* @__PURE__ */
|
|
2519
|
+
return /* @__PURE__ */ jsxs27("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
|
|
2317
2520
|
props.label,
|
|
2318
|
-
/* @__PURE__ */
|
|
2521
|
+
/* @__PURE__ */ jsx28("span", { "aria-hidden": "true", children: "\u2192" })
|
|
2319
2522
|
] });
|
|
2320
2523
|
}
|
|
2321
2524
|
function TierCard(props) {
|
|
2322
2525
|
const { tier, presentation } = props;
|
|
2323
2526
|
const summary = presentation.summaryMarkdown ?? tier.blurb;
|
|
2324
2527
|
const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
|
|
2325
|
-
return /* @__PURE__ */
|
|
2326
|
-
presentation.badge ? /* @__PURE__ */
|
|
2327
|
-
/* @__PURE__ */
|
|
2328
|
-
/* @__PURE__ */
|
|
2329
|
-
presentation.capacity ? /* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
2528
|
+
return /* @__PURE__ */ jsxs27("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
|
|
2529
|
+
presentation.badge ? /* @__PURE__ */ jsx28("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
|
|
2530
|
+
/* @__PURE__ */ jsx28("h3", { className: "chapter-membership-name", children: tier.name }),
|
|
2531
|
+
/* @__PURE__ */ jsxs27("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
|
|
2532
|
+
presentation.capacity ? /* @__PURE__ */ jsxs27("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
|
|
2533
|
+
/* @__PURE__ */ jsx28("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
|
|
2534
|
+
/* @__PURE__ */ jsx28("small", { children: presentation.capacity.label ?? "available" })
|
|
2332
2535
|
] }) : null,
|
|
2333
|
-
/* @__PURE__ */
|
|
2334
|
-
presentation.priceEyebrow ? /* @__PURE__ */
|
|
2335
|
-
/* @__PURE__ */
|
|
2336
|
-
tier.founding ? /* @__PURE__ */
|
|
2337
|
-
/* @__PURE__ */
|
|
2338
|
-
!tier.free && presentation.billingLabel ? /* @__PURE__ */
|
|
2536
|
+
/* @__PURE__ */ jsxs27("div", { className: "chapter-membership-price-stack", children: [
|
|
2537
|
+
presentation.priceEyebrow ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
|
|
2538
|
+
/* @__PURE__ */ jsxs27("div", { className: "chapter-membership-price-row", children: [
|
|
2539
|
+
tier.founding ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
|
|
2540
|
+
/* @__PURE__ */ jsx28("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
|
|
2541
|
+
!tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx28("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
|
|
2339
2542
|
] })
|
|
2340
2543
|
] })
|
|
2341
2544
|
] }),
|
|
2342
|
-
presentation.priceNoteMarkdown ? /* @__PURE__ */
|
|
2343
|
-
summary ? /* @__PURE__ */
|
|
2344
|
-
presentation.benefits?.length ? /* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2545
|
+
presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
|
|
2546
|
+
summary ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
|
|
2547
|
+
presentation.benefits?.length ? /* @__PURE__ */ jsx28("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs27("li", { children: [
|
|
2548
|
+
/* @__PURE__ */ jsx28("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
|
|
2549
|
+
/* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-benefit", source: benefit })
|
|
2347
2550
|
] }, `${tier.id}-benefit-${index}`)) }) : null,
|
|
2348
|
-
presentation.callout ? /* @__PURE__ */
|
|
2349
|
-
presentation.callout.label ? /* @__PURE__ */
|
|
2350
|
-
/* @__PURE__ */
|
|
2551
|
+
presentation.callout ? /* @__PURE__ */ jsxs27("aside", { className: "chapter-membership-callout", children: [
|
|
2552
|
+
presentation.callout.label ? /* @__PURE__ */ jsx28("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
|
|
2553
|
+
/* @__PURE__ */ jsx28(Markdown2, { source: presentation.callout.bodyMarkdown })
|
|
2351
2554
|
] }) : null,
|
|
2352
|
-
/* @__PURE__ */
|
|
2555
|
+
/* @__PURE__ */ jsx28(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
|
|
2353
2556
|
] });
|
|
2354
2557
|
}
|
|
2355
2558
|
function MembershipCards(props) {
|
|
2356
2559
|
const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
|
|
2357
2560
|
const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
|
|
2358
2561
|
const mode = props.mode ?? "link";
|
|
2359
|
-
return /* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2361
|
-
/* @__PURE__ */
|
|
2562
|
+
return /* @__PURE__ */ jsxs27("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
|
|
2563
|
+
/* @__PURE__ */ jsx28("style", { children: MEMBERSHIP_CARDS_CSS }),
|
|
2564
|
+
/* @__PURE__ */ jsx28("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
|
|
2362
2565
|
const tier = byId.get(presentation.tierId);
|
|
2363
|
-
return /* @__PURE__ */
|
|
2566
|
+
return /* @__PURE__ */ jsx28(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
|
|
2364
2567
|
}) }),
|
|
2365
|
-
document2.footnoteMarkdown ? /* @__PURE__ */
|
|
2568
|
+
document2.footnoteMarkdown ? /* @__PURE__ */ jsx28(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
|
|
2366
2569
|
] });
|
|
2367
2570
|
}
|
|
2368
2571
|
|
|
@@ -2376,6 +2579,11 @@ export {
|
|
|
2376
2579
|
fmtDate,
|
|
2377
2580
|
groupSlotsByDay,
|
|
2378
2581
|
SlotPicker,
|
|
2582
|
+
ADDITIONAL_MEMBER_COPY,
|
|
2583
|
+
additionalMemberSelection,
|
|
2584
|
+
AdditionalMemberFields,
|
|
2585
|
+
JoinSubmitButton,
|
|
2586
|
+
AdditionalMemberEditor,
|
|
2379
2587
|
PaymentStep,
|
|
2380
2588
|
JourneyFrame,
|
|
2381
2589
|
MemberRestart,
|
|
@@ -2398,4 +2606,4 @@ export {
|
|
|
2398
2606
|
membershipApplicationHref,
|
|
2399
2607
|
MembershipCards
|
|
2400
2608
|
};
|
|
2401
|
-
//# sourceMappingURL=chunk-
|
|
2609
|
+
//# sourceMappingURL=chunk-CKC6X5H2.js.map
|