@odla-ai/chapter 0.54.2 → 0.56.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 +32 -0
- package/dist/{chunk-SPEL4OGE.js → chunk-IQZWCG42.js} +581 -362
- package/dist/chunk-IQZWCG42.js.map +1 -0
- package/dist/index.cjs +522 -266
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +518 -262
- package/dist/index.js.map +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/member/index.d.ts +12 -1
- package/dist/ui/member/index.js +1 -1
- package/dist/worker/index.cjs +1110 -616
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +22 -1
- package/dist/worker/index.d.ts +22 -1
- package/dist/worker/index.js +1103 -609
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-SPEL4OGE.js.map +0 -1
|
@@ -111,10 +111,10 @@ 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 useState5 } from "preact/hooks";
|
|
115
115
|
|
|
116
116
|
// src/ui/membership-payment-step.tsx
|
|
117
|
-
import { useEffect, useState as
|
|
117
|
+
import { useEffect, useState as useState4 } from "preact/hooks";
|
|
118
118
|
|
|
119
119
|
// src/ui/payment-step.tsx
|
|
120
120
|
import { useRef, useState as useState2 } from "preact/hooks";
|
|
@@ -271,14 +271,95 @@ function PaymentStep(props) {
|
|
|
271
271
|
] });
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
// src/ui/
|
|
274
|
+
// src/ui/checkout-seat-choice.tsx
|
|
275
|
+
import { useState as useState3 } from "preact/hooks";
|
|
275
276
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
277
|
+
function CheckoutSeatChoice(props) {
|
|
278
|
+
const saved = props.quote.namedSeat;
|
|
279
|
+
const [selected, setSelected] = useState3(Boolean(saved || props.initial));
|
|
280
|
+
const [name, setName] = useState3(saved?.recipientName ?? props.initial?.recipientName ?? "");
|
|
281
|
+
const [email, setEmail] = useState3(saved?.recipientEmail ?? props.initial?.recipientEmail ?? "");
|
|
282
|
+
const [saving, setSaving] = useState3(false), [error, setError] = useState3("");
|
|
283
|
+
const amount = props.quote.seatOffer.amountCents;
|
|
284
|
+
const money = new Intl.NumberFormat("en-US", { style: "currency", currency: props.quote.currency }).format(amount / 100);
|
|
285
|
+
const dirty = selected !== Boolean(saved) || selected && (name !== saved?.recipientName || email !== saved?.recipientEmail);
|
|
286
|
+
const edit = (nextSelected, nextName = name, nextEmail = email) => {
|
|
287
|
+
props.onEditing(nextSelected !== Boolean(saved) || nextSelected && (nextName !== saved?.recipientName || nextEmail !== saved?.recipientEmail));
|
|
288
|
+
setError("");
|
|
289
|
+
};
|
|
290
|
+
return /* @__PURE__ */ jsx3("section", { className: "checkout-seat-choice", "aria-label": "Additional member", children: /* @__PURE__ */ jsxs3("form", { onSubmit: async (event) => {
|
|
291
|
+
event.preventDefault();
|
|
292
|
+
setSaving(true);
|
|
293
|
+
setError("");
|
|
294
|
+
try {
|
|
295
|
+
await props.onChange(selected ? { recipientName: name, recipientEmail: email } : null);
|
|
296
|
+
} catch (error2) {
|
|
297
|
+
setError(error2 instanceof Error ? error2.message : "Could not save your selection. Try again.");
|
|
298
|
+
} finally {
|
|
299
|
+
setSaving(false);
|
|
300
|
+
}
|
|
301
|
+
}, children: [
|
|
302
|
+
/* @__PURE__ */ jsxs3("fieldset", { disabled: props.locked || saving, children: [
|
|
303
|
+
/* @__PURE__ */ jsx3("legend", { children: amount === 0 ? "Included additional member" : "Add an additional member" }),
|
|
304
|
+
/* @__PURE__ */ jsx3("p", { children: amount === 0 ? "Your membership includes one additional member at no extra charge." : `Additional-member rate: ${money} per ${props.quote.interval}, paid together with your membership.` }),
|
|
305
|
+
/* @__PURE__ */ jsxs3("label", { children: [
|
|
306
|
+
/* @__PURE__ */ jsx3("input", { type: "checkbox", checked: selected, onChange: (event) => {
|
|
307
|
+
setSelected(event.currentTarget.checked);
|
|
308
|
+
edit(event.currentTarget.checked);
|
|
309
|
+
} }),
|
|
310
|
+
amount === 0 ? "Include my additional member" : "Add one member to my payment"
|
|
311
|
+
] }),
|
|
312
|
+
selected ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
313
|
+
/* @__PURE__ */ jsxs3("label", { children: [
|
|
314
|
+
"Full name",
|
|
315
|
+
/* @__PURE__ */ jsx3(
|
|
316
|
+
"input",
|
|
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
|
|
348
|
+
] }),
|
|
349
|
+
error ? /* @__PURE__ */ jsx3("p", { role: "alert", children: error }) : null
|
|
350
|
+
] }) });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/ui/membership-payment-step.tsx
|
|
354
|
+
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
276
355
|
function MembershipPaymentStep(props) {
|
|
277
356
|
const inherited = useChapterCopy();
|
|
278
357
|
const copy = props.copy ?? inherited.join.payment;
|
|
279
|
-
const [quote, setQuote] =
|
|
280
|
-
const [
|
|
281
|
-
const [
|
|
358
|
+
const [quote, setQuote] = useState4(null);
|
|
359
|
+
const [locked, setLocked] = useState4(false), [editing, setEditing] = useState4(Boolean(props.initialNamedSeat));
|
|
360
|
+
const [prefillConsumed, setPrefillConsumed] = useState4(false);
|
|
361
|
+
const [error, setError] = useState4(false);
|
|
362
|
+
const [revision, setRevision] = useState4(0);
|
|
282
363
|
useEffect(() => {
|
|
283
364
|
let live = true;
|
|
284
365
|
setQuote(null);
|
|
@@ -286,8 +367,13 @@ function MembershipPaymentStep(props) {
|
|
|
286
367
|
void fetch(`/api/payments/quote?application=${encodeURIComponent(props.applicationId)}`, { method: "POST", cache: "no-store" }).then(async (response) => {
|
|
287
368
|
if (!response.ok) throw new Error("quote unavailable");
|
|
288
369
|
const value = await response.json();
|
|
370
|
+
value.checkoutStarted = response.headers.get("x-chapter-checkout-started") === "true";
|
|
289
371
|
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");
|
|
290
|
-
if (live)
|
|
372
|
+
if (live) {
|
|
373
|
+
setQuote(value);
|
|
374
|
+
setLocked(Boolean(value.checkoutStarted));
|
|
375
|
+
setEditing(Boolean(props.initialNamedSeat && !prefillConsumed && !value.namedSeat && !value.checkoutStarted && value.seatOffer));
|
|
376
|
+
}
|
|
291
377
|
}).catch(() => {
|
|
292
378
|
if (live) setError(true);
|
|
293
379
|
});
|
|
@@ -299,16 +385,22 @@ function MembershipPaymentStep(props) {
|
|
|
299
385
|
setQuote(null);
|
|
300
386
|
setRevision((value) => value + 1);
|
|
301
387
|
};
|
|
302
|
-
if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */
|
|
303
|
-
props.merchantDisclosureText ? /* @__PURE__ */
|
|
304
|
-
/* @__PURE__ */
|
|
305
|
-
error ? /* @__PURE__ */
|
|
388
|
+
if (!quote || quote.applicationId !== props.applicationId) return /* @__PURE__ */ jsxs4("div", { className: "join-pay", role: "status", children: [
|
|
389
|
+
props.merchantDisclosureText ? /* @__PURE__ */ jsx4("p", { className: "compliance-merchant", children: props.merchantDisclosureText }) : null,
|
|
390
|
+
/* @__PURE__ */ jsx4("p", { children: error ? copy.setupFailed : copy.preparing }),
|
|
391
|
+
error ? /* @__PURE__ */ jsx4("button", { type: "button", onClick: refresh, children: "Reload payment terms" }) : null
|
|
306
392
|
] });
|
|
307
393
|
const startCheckout = async () => {
|
|
394
|
+
setLocked(true);
|
|
308
395
|
const response = await fetch("/api/payments/subscription", {
|
|
309
396
|
method: "POST",
|
|
310
397
|
headers: { "content-type": "application/json" },
|
|
311
|
-
body: JSON.stringify({
|
|
398
|
+
body: JSON.stringify({
|
|
399
|
+
applicationId: props.applicationId,
|
|
400
|
+
refundPolicyAck: true,
|
|
401
|
+
quoteDigest: quote.digest,
|
|
402
|
+
...quote.namedSeat ? { seatTermsAck: true } : {}
|
|
403
|
+
})
|
|
312
404
|
});
|
|
313
405
|
if (!response.ok) {
|
|
314
406
|
if (response.status === 409) refresh();
|
|
@@ -317,45 +409,85 @@ function MembershipPaymentStep(props) {
|
|
|
317
409
|
return response.json();
|
|
318
410
|
};
|
|
319
411
|
const amount = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: quote.currency }).format(cents / 100);
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
412
|
+
const changeSeat = async (namedSeat) => {
|
|
413
|
+
const response = await fetch(`/api/payments/quote?application=${encodeURIComponent(props.applicationId)}`, {
|
|
414
|
+
method: "POST",
|
|
415
|
+
cache: "no-store",
|
|
416
|
+
headers: { "content-type": "application/json" },
|
|
417
|
+
body: JSON.stringify({ namedSeat })
|
|
418
|
+
});
|
|
419
|
+
if (!response.ok) {
|
|
420
|
+
if (response.status === 409) refresh();
|
|
421
|
+
throw new Error(response.status === 400 ? "Enter a different recipient's name and valid email." : "Could not save your selection. Reload payment terms and try again.");
|
|
422
|
+
}
|
|
423
|
+
const value = await response.json();
|
|
424
|
+
if (value.applicationId !== props.applicationId || !/^[a-f0-9]{64}$/.test(value.digest)) throw new Error(copy.setupFailed);
|
|
425
|
+
setQuote(value);
|
|
426
|
+
setEditing(false);
|
|
427
|
+
setPrefillConsumed(true);
|
|
428
|
+
};
|
|
429
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
430
|
+
quote.seatOffer ? /* @__PURE__ */ jsx4(
|
|
431
|
+
CheckoutSeatChoice,
|
|
432
|
+
{
|
|
433
|
+
quote,
|
|
434
|
+
locked,
|
|
435
|
+
onChange: changeSeat,
|
|
436
|
+
initial: quote.namedSeat || locked || prefillConsumed ? void 0 : props.initialNamedSeat,
|
|
437
|
+
onEditing: setEditing
|
|
438
|
+
},
|
|
439
|
+
quote.digest
|
|
440
|
+
) : null,
|
|
441
|
+
/* @__PURE__ */ jsxs4("section", { className: "payment-quote", "aria-label": "Membership price", children: [
|
|
442
|
+
/* @__PURE__ */ jsx4("h3", { children: quote.tierName }),
|
|
443
|
+
quote.founding ? /* @__PURE__ */ jsx4("p", { className: "payment-founding", role: "note", "aria-label": "Founding member", children: copy.foundingMember }) : null,
|
|
324
444
|
props.renderPriceLines ? props.renderPriceLines({
|
|
325
445
|
...quote.lineItems,
|
|
326
446
|
...quote.founding ? { founding: quote.founding } : {},
|
|
327
447
|
...quote.presentation ? { presentation: quote.presentation } : {}
|
|
328
|
-
}) : /* @__PURE__ */
|
|
329
|
-
quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */
|
|
330
|
-
/* @__PURE__ */
|
|
331
|
-
/* @__PURE__ */
|
|
448
|
+
}) : /* @__PURE__ */ jsxs4("dl", { children: [
|
|
449
|
+
quote.lineItems.discountCents > 0 && !quote.founding && quote.presentation ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
450
|
+
/* @__PURE__ */ jsx4("dt", { children: copy.standardRate }),
|
|
451
|
+
/* @__PURE__ */ jsxs4("dd", { children: [
|
|
332
452
|
amount(quote.lineItems.standardCents),
|
|
333
453
|
" per ",
|
|
334
454
|
quote.interval
|
|
335
455
|
] }),
|
|
336
|
-
/* @__PURE__ */
|
|
337
|
-
/* @__PURE__ */
|
|
338
|
-
amount(quote.lineItems.dueTodayCents),
|
|
456
|
+
/* @__PURE__ */ jsx4("dt", { children: copy.yourRate }),
|
|
457
|
+
/* @__PURE__ */ jsxs4("dd", { children: [
|
|
458
|
+
amount(quote.lineItems.dueTodayCents - (quote.lineItems.namedSeatCents ?? 0)),
|
|
339
459
|
" per ",
|
|
340
460
|
quote.interval
|
|
341
461
|
] })
|
|
342
|
-
] }) : /* @__PURE__ */
|
|
343
|
-
/* @__PURE__ */
|
|
344
|
-
/* @__PURE__ */
|
|
462
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
463
|
+
/* @__PURE__ */ jsx4("dt", { children: "Membership price" }),
|
|
464
|
+
/* @__PURE__ */ jsxs4("dd", { children: [
|
|
345
465
|
amount(quote.lineItems.standardCents),
|
|
346
466
|
" per ",
|
|
347
467
|
quote.interval
|
|
348
468
|
] }),
|
|
349
|
-
quote.lineItems.discountCents > 0 ? /* @__PURE__ */
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
469
|
+
quote.lineItems.discountCents > 0 ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
470
|
+
/* @__PURE__ */ jsx4("dt", { children: quote.founding ? copy.foundingDiscount : "Discount" }),
|
|
471
|
+
/* @__PURE__ */ jsx4("dd", { children: amount(quote.lineItems.discountCents) })
|
|
352
472
|
] }) : null
|
|
353
473
|
] }),
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
|
|
474
|
+
quote.namedSeat ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
475
|
+
/* @__PURE__ */ jsx4("dt", { children: "Additional member" }),
|
|
476
|
+
/* @__PURE__ */ jsx4("dd", { children: quote.lineItems.namedSeatCents === 0 ? "Included" : amount(quote.lineItems.namedSeatCents) })
|
|
477
|
+
] }) : null,
|
|
478
|
+
/* @__PURE__ */ jsx4("dt", { children: "Due today" }),
|
|
479
|
+
/* @__PURE__ */ jsx4("dd", { children: amount(quote.lineItems.dueTodayCents) })
|
|
356
480
|
] }),
|
|
357
|
-
quote.
|
|
358
|
-
|
|
481
|
+
quote.namedSeat ? /* @__PURE__ */ jsxs4("p", { children: [
|
|
482
|
+
"For ",
|
|
483
|
+
quote.namedSeat.recipientName,
|
|
484
|
+
" \xB7 ",
|
|
485
|
+
quote.namedSeat.recipientEmail,
|
|
486
|
+
".",
|
|
487
|
+
props.renderPriceLines ? ` Additional member: ${quote.lineItems.namedSeatCents === 0 ? "included" : amount(quote.lineItems.namedSeatCents)} in the total above.` : ""
|
|
488
|
+
] }) : null,
|
|
489
|
+
quote.commercial ? /* @__PURE__ */ jsxs4("div", { role: "note", "aria-label": "Renewal terms", children: [
|
|
490
|
+
quote.commercial.initialTermEndsAt !== void 0 ? /* @__PURE__ */ jsxs4("p", { children: [
|
|
359
491
|
"First renewal: ",
|
|
360
492
|
new Intl.DateTimeFormat("en-US", {
|
|
361
493
|
dateStyle: "long",
|
|
@@ -363,33 +495,35 @@ function MembershipPaymentStep(props) {
|
|
|
363
495
|
}).format(quote.commercial.initialTermEndsAt),
|
|
364
496
|
"."
|
|
365
497
|
] }) : null,
|
|
366
|
-
/* @__PURE__ */
|
|
498
|
+
/* @__PURE__ */ jsxs4("p", { children: [
|
|
367
499
|
"Renews automatically at ",
|
|
368
500
|
amount(quote.commercial.renewalCents),
|
|
369
501
|
" per ",
|
|
370
502
|
quote.interval,
|
|
371
503
|
" unless canceled before renewal."
|
|
372
504
|
] }),
|
|
373
|
-
quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */
|
|
374
|
-
quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */
|
|
505
|
+
quote.commercial.discountDuration === "first_term" ? /* @__PURE__ */ jsx4("p", { children: "The discount applies to your first paid term only." }) : null,
|
|
506
|
+
quote.commercial.discountDuration === "while_active" ? /* @__PURE__ */ jsx4("p", { children: "The discounted rate continues while this membership stays active." }) : null
|
|
375
507
|
] }) : null,
|
|
376
|
-
quote.trustCopy ? /* @__PURE__ */
|
|
508
|
+
quote.trustCopy ? /* @__PURE__ */ jsx4("p", { className: "pay-trust", children: quote.trustCopy }) : null
|
|
377
509
|
] }),
|
|
378
|
-
/* @__PURE__ */
|
|
510
|
+
!editing ? /* @__PURE__ */ jsx4(
|
|
379
511
|
PaymentStep,
|
|
380
512
|
{
|
|
381
513
|
...props,
|
|
382
514
|
refundPolicyText: quote.refundPolicyText,
|
|
383
515
|
merchantDisclosureText: quote.merchantDisclosureText,
|
|
516
|
+
copy: { ...copy, consent: quote.namedSeat ? "I agree to the refund policy, renewal terms, and additional-member terms above." : "I agree to the refund policy and renewal terms above." },
|
|
384
517
|
renderPriceLines: void 0,
|
|
385
518
|
startCheckout
|
|
386
|
-
}
|
|
387
|
-
|
|
519
|
+
},
|
|
520
|
+
quote.digest
|
|
521
|
+
) : /* @__PURE__ */ jsx4("p", { role: "status", children: "Save your member selection to continue to payment." })
|
|
388
522
|
] });
|
|
389
523
|
}
|
|
390
524
|
|
|
391
525
|
// src/ui/journey-frame.tsx
|
|
392
|
-
import { jsx as
|
|
526
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
393
527
|
var styles = `
|
|
394
528
|
.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}
|
|
395
529
|
.chapter-journey *{box-sizing:border-box}
|
|
@@ -424,21 +558,21 @@ var styles = `
|
|
|
424
558
|
@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}}
|
|
425
559
|
`;
|
|
426
560
|
function JourneyFrame({ children }) {
|
|
427
|
-
return /* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
561
|
+
return /* @__PURE__ */ jsxs5("div", { className: "chapter-journey", children: [
|
|
562
|
+
/* @__PURE__ */ jsx5("style", { children: styles }),
|
|
429
563
|
children
|
|
430
564
|
] });
|
|
431
565
|
}
|
|
432
566
|
|
|
433
567
|
// src/ui/member-restart.tsx
|
|
434
|
-
import { jsx as
|
|
568
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
435
569
|
function MemberRestart(props) {
|
|
436
|
-
const [id, setId] =
|
|
437
|
-
const [busy, setBusy] =
|
|
438
|
-
const [error, setError] =
|
|
439
|
-
const [paid, setPaid] =
|
|
440
|
-
const [checking, setChecking] =
|
|
441
|
-
const [revision, setRevision] =
|
|
570
|
+
const [id, setId] = useState5(props.applicationId);
|
|
571
|
+
const [busy, setBusy] = useState5(false);
|
|
572
|
+
const [error, setError] = useState5("");
|
|
573
|
+
const [paid, setPaid] = useState5(false);
|
|
574
|
+
const [checking, setChecking] = useState5(false);
|
|
575
|
+
const [revision, setRevision] = useState5(0);
|
|
442
576
|
useEffect2(() => {
|
|
443
577
|
if (!paid) return;
|
|
444
578
|
let live = true, timer, attempt = 0;
|
|
@@ -476,40 +610,40 @@ function MemberRestart(props) {
|
|
|
476
610
|
setBusy(false);
|
|
477
611
|
}
|
|
478
612
|
};
|
|
479
|
-
return /* @__PURE__ */
|
|
480
|
-
/* @__PURE__ */
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
484
|
-
/* @__PURE__ */
|
|
485
|
-
/* @__PURE__ */
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
/* @__PURE__ */
|
|
613
|
+
return /* @__PURE__ */ jsx6(JourneyFrame, { children: /* @__PURE__ */ jsxs6("section", { className: "card", "aria-label": "Restart membership", children: [
|
|
614
|
+
/* @__PURE__ */ jsx6("p", { className: "card-label", children: "Welcome back" }),
|
|
615
|
+
/* @__PURE__ */ jsx6("h2", { children: "Restart your membership" }),
|
|
616
|
+
/* @__PURE__ */ jsx6("p", { children: "Your account is ready, and your previous approval still counts. No new application or interview is needed." }),
|
|
617
|
+
/* @__PURE__ */ jsxs6("dl", { className: "journey-summary", children: [
|
|
618
|
+
/* @__PURE__ */ jsx6("dt", { children: "Name" }),
|
|
619
|
+
/* @__PURE__ */ jsx6("dd", { children: [props.application.firstName, props.application.lastName].filter(Boolean).join(" ") }),
|
|
620
|
+
/* @__PURE__ */ jsx6("dt", { children: "Email" }),
|
|
621
|
+
/* @__PURE__ */ jsx6("dd", { children: props.application.email })
|
|
488
622
|
] }),
|
|
489
|
-
paid ? /* @__PURE__ */
|
|
490
|
-
/* @__PURE__ */
|
|
491
|
-
/* @__PURE__ */
|
|
492
|
-
!checking ? /* @__PURE__ */
|
|
493
|
-
] }) : id ? /* @__PURE__ */
|
|
494
|
-
error ? /* @__PURE__ */
|
|
623
|
+
paid ? /* @__PURE__ */ jsxs6("div", { role: "status", children: [
|
|
624
|
+
/* @__PURE__ */ jsx6("h3", { children: "Confirming your membership" }),
|
|
625
|
+
/* @__PURE__ */ jsx6("p", { children: "We\u2019re waiting for payment confirmation. Your membership will open here as soon as it arrives." }),
|
|
626
|
+
!checking ? /* @__PURE__ */ jsx6("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Check membership" }) : null
|
|
627
|
+
] }) : id ? /* @__PURE__ */ jsx6(MembershipPaymentStep, { applicationId: id, refundPolicyText: "", onPaid: () => setPaid(true) }) : /* @__PURE__ */ jsx6("button", { type: "button", disabled: busy, onClick: () => void start(), children: busy ? "Preparing your membership\u2026" : "Review membership and payment" }),
|
|
628
|
+
error ? /* @__PURE__ */ jsx6("p", { role: "alert", children: error }) : null
|
|
495
629
|
] }) });
|
|
496
630
|
}
|
|
497
631
|
|
|
498
632
|
// src/ui/members.tsx
|
|
499
|
-
import { useEffect as useEffect6, useState as
|
|
633
|
+
import { useEffect as useEffect6, useState as useState10 } from "preact/hooks";
|
|
500
634
|
|
|
501
635
|
// src/ui/reschedule.tsx
|
|
502
|
-
import { useState as
|
|
503
|
-
import { jsx as
|
|
636
|
+
import { useState as useState6 } from "preact/hooks";
|
|
637
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
504
638
|
function Rescheduler(props) {
|
|
505
639
|
const inheritedCopy = useChapterCopy();
|
|
506
640
|
const copy = props.copy ?? inheritedCopy.members.reschedule;
|
|
507
641
|
const { api, applicationId, timezone, onRescheduled, label = copy.changeTime } = props;
|
|
508
|
-
const [open, setOpen] =
|
|
509
|
-
const [slots, setSlots] =
|
|
510
|
-
const [tz, setTz] =
|
|
511
|
-
const [busy, setBusy] =
|
|
512
|
-
const [msg, setMsg] =
|
|
642
|
+
const [open, setOpen] = useState6(false);
|
|
643
|
+
const [slots, setSlots] = useState6(null);
|
|
644
|
+
const [tz, setTz] = useState6(timezone);
|
|
645
|
+
const [busy, setBusy] = useState6(false);
|
|
646
|
+
const [msg, setMsg] = useState6(null);
|
|
513
647
|
const start = async () => {
|
|
514
648
|
setOpen(true);
|
|
515
649
|
setSlots(null);
|
|
@@ -542,7 +676,7 @@ function Rescheduler(props) {
|
|
|
542
676
|
}
|
|
543
677
|
};
|
|
544
678
|
if (!open) {
|
|
545
|
-
return /* @__PURE__ */
|
|
679
|
+
return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: /* @__PURE__ */ jsx7(
|
|
546
680
|
"a",
|
|
547
681
|
{
|
|
548
682
|
href: "#",
|
|
@@ -554,8 +688,8 @@ function Rescheduler(props) {
|
|
|
554
688
|
}
|
|
555
689
|
) });
|
|
556
690
|
}
|
|
557
|
-
return /* @__PURE__ */
|
|
558
|
-
slots === null ? /* @__PURE__ */
|
|
691
|
+
return /* @__PURE__ */ jsxs7("div", { className: "msched", children: [
|
|
692
|
+
slots === null ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.loading }) : slots.length === 0 ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: msg ?? copy.noTimes }) : /* @__PURE__ */ jsx7(
|
|
559
693
|
SlotPicker,
|
|
560
694
|
{
|
|
561
695
|
slots,
|
|
@@ -564,9 +698,9 @@ function Rescheduler(props) {
|
|
|
564
698
|
onPick: (s) => void pick(s)
|
|
565
699
|
}
|
|
566
700
|
),
|
|
567
|
-
busy ? /* @__PURE__ */
|
|
568
|
-
msg && slots && slots.length > 0 ? /* @__PURE__ */
|
|
569
|
-
/* @__PURE__ */
|
|
701
|
+
busy ? /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.rescheduling }) : null,
|
|
702
|
+
msg && slots && slots.length > 0 ? /* @__PURE__ */ jsx7("p", { className: "meeting-note error", children: msg }) : null,
|
|
703
|
+
/* @__PURE__ */ jsx7("p", { className: "meeting-note", children: /* @__PURE__ */ jsx7(
|
|
570
704
|
"a",
|
|
571
705
|
{
|
|
572
706
|
href: "#",
|
|
@@ -581,31 +715,31 @@ function Rescheduler(props) {
|
|
|
581
715
|
}
|
|
582
716
|
|
|
583
717
|
// src/ui/member-gifts.tsx
|
|
584
|
-
import { useEffect as useEffect3, useRef as useRef2, useState as
|
|
718
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState7 } from "preact/hooks";
|
|
585
719
|
|
|
586
720
|
// src/ui/gift-offer-cards.tsx
|
|
587
|
-
import { jsx as
|
|
721
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
588
722
|
var price = (cents, currency) => currency === "usd" ? fmtMoney(cents) : new Intl.NumberFormat(void 0, { style: "currency", currency: currency.toUpperCase() }).format(cents / 100);
|
|
589
723
|
function GiftOfferCards(props) {
|
|
590
724
|
const mode = props.mode ?? "preview";
|
|
591
|
-
return /* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
/* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
725
|
+
return /* @__PURE__ */ jsx8("section", { className: "chapter-gift-offers", "aria-label": props.ariaLabel ?? "Gift options", children: props.offers.map((offer) => /* @__PURE__ */ jsxs8("article", { className: "card chapter-gift-offer", "data-offer-id": offer.id, children: [
|
|
726
|
+
/* @__PURE__ */ jsx8("div", { className: "card-label", children: offer.title }),
|
|
727
|
+
/* @__PURE__ */ jsx8("p", { children: offer.description }),
|
|
728
|
+
/* @__PURE__ */ jsxs8("p", { className: "meeting-date", children: [
|
|
595
729
|
price(offer.priceCents, offer.currency),
|
|
596
730
|
offer.billingMode === "subscription" ? " recurring" : ""
|
|
597
731
|
] }),
|
|
598
|
-
mode === "select" ? /* @__PURE__ */
|
|
732
|
+
mode === "select" ? /* @__PURE__ */ jsx8("button", { type: "button", className: "btn secondary", "aria-pressed": props.selectedOfferId === offer.id, onClick: () => props.onSelect?.(offer.id), children: offer.ctaLabel }) : /* @__PURE__ */ jsx8("span", { className: "btn secondary", "aria-disabled": "true", children: offer.ctaLabel })
|
|
599
733
|
] }, offer.id)) });
|
|
600
734
|
}
|
|
601
735
|
|
|
602
736
|
// src/ui/member-gifts.tsx
|
|
603
|
-
import { jsx as
|
|
737
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
604
738
|
function GiftPurchases(props) {
|
|
605
|
-
const [data, setData] =
|
|
606
|
-
const [selected, setSelected] =
|
|
607
|
-
const [code, setCode] =
|
|
608
|
-
const [message, setMessage] =
|
|
739
|
+
const [data, setData] = useState7(null);
|
|
740
|
+
const [selected, setSelected] = useState7(null);
|
|
741
|
+
const [code, setCode] = useState7("");
|
|
742
|
+
const [message, setMessage] = useState7("");
|
|
609
743
|
const purchaseId = useRef2(crypto.randomUUID());
|
|
610
744
|
const load = async () => setData(await props.api("/api/gifts"));
|
|
611
745
|
useEffect3(() => {
|
|
@@ -623,16 +757,16 @@ function GiftPurchases(props) {
|
|
|
623
757
|
if (!data) return null;
|
|
624
758
|
if (data.offers.length === 0 && data.claims.length === 0) return null;
|
|
625
759
|
const offer = data.offers.find((item) => item.id === selected);
|
|
626
|
-
return /* @__PURE__ */
|
|
627
|
-
data.offers.length ? /* @__PURE__ */
|
|
628
|
-
/* @__PURE__ */
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
760
|
+
return /* @__PURE__ */ jsxs9("section", { className: "member-gifts", children: [
|
|
761
|
+
data.offers.length ? /* @__PURE__ */ jsxs9("div", { className: "card", children: [
|
|
762
|
+
/* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.title }),
|
|
763
|
+
/* @__PURE__ */ jsx9("p", { children: props.copy.body }),
|
|
764
|
+
/* @__PURE__ */ jsx9(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
|
|
631
765
|
setSelected(id);
|
|
632
766
|
setCode("");
|
|
633
767
|
purchaseId.current = crypto.randomUUID();
|
|
634
768
|
} }),
|
|
635
|
-
offer ? /* @__PURE__ */
|
|
769
|
+
offer ? /* @__PURE__ */ jsx9(
|
|
636
770
|
PaymentStep,
|
|
637
771
|
{
|
|
638
772
|
applicationId: purchaseId.current,
|
|
@@ -652,27 +786,27 @@ function GiftPurchases(props) {
|
|
|
652
786
|
}
|
|
653
787
|
}
|
|
654
788
|
) : null,
|
|
655
|
-
code ? /* @__PURE__ */
|
|
656
|
-
/* @__PURE__ */
|
|
657
|
-
/* @__PURE__ */
|
|
789
|
+
code ? /* @__PURE__ */ jsxs9("div", { className: "gift-code-once", children: [
|
|
790
|
+
/* @__PURE__ */ jsx9("output", { children: code }),
|
|
791
|
+
/* @__PURE__ */ jsx9("p", { children: props.copy.saveCode })
|
|
658
792
|
] }) : null
|
|
659
793
|
] }) : null,
|
|
660
|
-
/* @__PURE__ */
|
|
661
|
-
/* @__PURE__ */
|
|
662
|
-
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
claim.status === "pending" ? /* @__PURE__ */
|
|
666
|
-
] }, claim.id)) : /* @__PURE__ */
|
|
667
|
-
message ? /* @__PURE__ */
|
|
794
|
+
/* @__PURE__ */ jsxs9("div", { className: "card", children: [
|
|
795
|
+
/* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.purchases }),
|
|
796
|
+
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs9("div", { className: "member-row", children: [
|
|
797
|
+
/* @__PURE__ */ jsx9("span", { children: claim.offerId }),
|
|
798
|
+
/* @__PURE__ */ jsx9("span", { children: props.copy[claim.status] }),
|
|
799
|
+
claim.status === "pending" ? /* @__PURE__ */ jsx9("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
|
|
800
|
+
] }, claim.id)) : /* @__PURE__ */ jsx9("p", { children: props.copy.noPurchases }),
|
|
801
|
+
message ? /* @__PURE__ */ jsx9("p", { role: "status", children: message }) : null
|
|
668
802
|
] })
|
|
669
803
|
] });
|
|
670
804
|
}
|
|
671
805
|
var MemberGifts = GiftPurchases;
|
|
672
806
|
|
|
673
807
|
// src/ui/member-named-seat.tsx
|
|
674
|
-
import { useEffect as useEffect4, useState as
|
|
675
|
-
import { Fragment as
|
|
808
|
+
import { useEffect as useEffect4, useState as useState8 } from "preact/hooks";
|
|
809
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
676
810
|
var NAMED_SEAT_RECIPIENT_WORDS = {
|
|
677
811
|
payment_pending: "payment in progress",
|
|
678
812
|
invited: "invited, waiting for them to accept",
|
|
@@ -685,7 +819,7 @@ var NAMED_SEAT_RECIPIENT_WORDS = {
|
|
|
685
819
|
var day = (at) => new Date(at).toLocaleDateString("en-US", { timeZone: "UTC" });
|
|
686
820
|
function NamedSeatRecipientLine({ seat }) {
|
|
687
821
|
const words = NAMED_SEAT_RECIPIENT_WORDS[seat.recipientState] ?? seat.status.replaceAll("_", " ");
|
|
688
|
-
return /* @__PURE__ */
|
|
822
|
+
return /* @__PURE__ */ jsxs10("p", { className: "member-named-seat-recipient", children: [
|
|
689
823
|
seat.recipientName,
|
|
690
824
|
" \xB7 ",
|
|
691
825
|
seat.recipientEmail,
|
|
@@ -695,9 +829,9 @@ function NamedSeatRecipientLine({ seat }) {
|
|
|
695
829
|
] });
|
|
696
830
|
}
|
|
697
831
|
function NamedSeatPurchase({ api }) {
|
|
698
|
-
const [data, setData] =
|
|
699
|
-
const [name, setName] =
|
|
700
|
-
const [terms, setTerms] =
|
|
832
|
+
const [data, setData] = useState8(null), [error, setError] = useState8("");
|
|
833
|
+
const [name, setName] = useState8(""), [email, setEmail] = useState8(""), [reviewing, setReviewing] = useState8(false);
|
|
834
|
+
const [terms, setTerms] = useState8(false), [pending, setPending] = useState8(false), [granting, setGranting] = useState8(false);
|
|
701
835
|
const load = async () => {
|
|
702
836
|
try {
|
|
703
837
|
const value = await api("/api/named-seat");
|
|
@@ -734,13 +868,13 @@ function NamedSeatPurchase({ api }) {
|
|
|
734
868
|
}
|
|
735
869
|
};
|
|
736
870
|
const money = data ? new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100) : "";
|
|
737
|
-
return /* @__PURE__ */
|
|
738
|
-
/* @__PURE__ */
|
|
739
|
-
error ? /* @__PURE__ */
|
|
740
|
-
data ? /* @__PURE__ */
|
|
741
|
-
data.seat ? /* @__PURE__ */
|
|
742
|
-
data.eligible ? /* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ jsx10(JourneyFrame, { children: /* @__PURE__ */ jsxs10("section", { className: "card member-named-seat", "aria-label": "Named additional seat", children: [
|
|
872
|
+
/* @__PURE__ */ jsx10("h2", { children: "Named additional seat" }),
|
|
873
|
+
error ? /* @__PURE__ */ jsx10("p", { role: "alert", children: error }) : null,
|
|
874
|
+
data ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
875
|
+
data.seat ? /* @__PURE__ */ jsx10(NamedSeatRecipientLine, { seat: data.seat }) : null,
|
|
876
|
+
data.eligible ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
877
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
744
878
|
data.included ? "Included with your membership at no charge." : `${money} paid in full now.`,
|
|
745
879
|
" This seat ",
|
|
746
880
|
data.autoRenew ? "renews with your primary membership" : "ends with your primary membership",
|
|
@@ -751,39 +885,39 @@ function NamedSeatPurchase({ api }) {
|
|
|
751
885
|
" ",
|
|
752
886
|
"It belongs to one named person and cannot be reassigned."
|
|
753
887
|
] }),
|
|
754
|
-
/* @__PURE__ */
|
|
755
|
-
!reviewing ? /* @__PURE__ */
|
|
888
|
+
/* @__PURE__ */ jsx10("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." }),
|
|
889
|
+
!reviewing ? /* @__PURE__ */ jsxs10("form", { onSubmit: (event) => {
|
|
756
890
|
event.preventDefault();
|
|
757
891
|
setReviewing(true);
|
|
758
892
|
setTerms(false);
|
|
759
893
|
}, children: [
|
|
760
|
-
/* @__PURE__ */
|
|
894
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
761
895
|
"Recipient name",
|
|
762
|
-
/* @__PURE__ */
|
|
896
|
+
/* @__PURE__ */ jsx10("input", { required: true, maxLength: 160, value: name, disabled: Boolean(data.seat), onInput: (event) => setName(event.currentTarget.value) })
|
|
763
897
|
] }),
|
|
764
|
-
/* @__PURE__ */
|
|
898
|
+
/* @__PURE__ */ jsxs10("label", { children: [
|
|
765
899
|
"Recipient email",
|
|
766
|
-
/* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ jsx10("input", { required: true, type: "email", maxLength: 254, value: email, disabled: Boolean(data.seat), onInput: (event) => setEmail(event.currentTarget.value) })
|
|
767
901
|
] }),
|
|
768
|
-
/* @__PURE__ */
|
|
769
|
-
] }) : /* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
902
|
+
/* @__PURE__ */ jsx10("button", { className: "btn primary", type: "submit", children: "Review named seat" })
|
|
903
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
904
|
+
/* @__PURE__ */ jsxs10("p", { children: [
|
|
771
905
|
"For ",
|
|
772
906
|
name,
|
|
773
907
|
" \xB7 ",
|
|
774
908
|
email
|
|
775
909
|
] }),
|
|
776
|
-
/* @__PURE__ */
|
|
910
|
+
/* @__PURE__ */ jsx10("button", { className: "btn secondary", type: "button", onClick: () => {
|
|
777
911
|
setReviewing(false);
|
|
778
912
|
setTerms(false);
|
|
779
913
|
void load();
|
|
780
914
|
}, children: "Back to recipient" }),
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
/* @__PURE__ */
|
|
915
|
+
/* @__PURE__ */ jsxs10("label", { className: "journey-consent", children: [
|
|
916
|
+
/* @__PURE__ */ jsx10("input", { type: "checkbox", checked: terms, onChange: (event) => setTerms(event.currentTarget.checked) }),
|
|
917
|
+
/* @__PURE__ */ jsx10("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." })
|
|
784
918
|
] }),
|
|
785
|
-
terms && data.included ? /* @__PURE__ */
|
|
786
|
-
terms && !data.included ? /* @__PURE__ */
|
|
919
|
+
terms && data.included ? /* @__PURE__ */ jsx10("button", { className: "btn primary", type: "button", disabled: granting, onClick: () => void grant(), children: granting ? "Sending the invitation\u2026" : "Send the invitation" }) : null,
|
|
920
|
+
terms && !data.included ? /* @__PURE__ */ jsx10(
|
|
787
921
|
PaymentStep,
|
|
788
922
|
{
|
|
789
923
|
applicationId: data.membershipId,
|
|
@@ -798,17 +932,17 @@ function NamedSeatPurchase({ api }) {
|
|
|
798
932
|
}
|
|
799
933
|
) : null
|
|
800
934
|
] })
|
|
801
|
-
] }) : !data.seat ? /* @__PURE__ */
|
|
802
|
-
pending ? /* @__PURE__ */
|
|
803
|
-
] }) : !error ? /* @__PURE__ */
|
|
804
|
-
/* @__PURE__ */
|
|
935
|
+
] }) : !data.seat ? /* @__PURE__ */ jsx10("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,
|
|
936
|
+
pending ? /* @__PURE__ */ jsx10("p", { role: "status", children: "Payment confirmation is being reconciled. The recipient\u2019s access begins only after their own acceptance and approval." }) : null
|
|
937
|
+
] }) : !error ? /* @__PURE__ */ jsx10("p", { children: "Loading your seat terms\u2026" }) : null,
|
|
938
|
+
/* @__PURE__ */ jsx10("button", { className: "btn secondary", onClick: () => void load(), children: "Refresh seat status" })
|
|
805
939
|
] }) });
|
|
806
940
|
}
|
|
807
941
|
|
|
808
942
|
// src/ui/member-content.tsx
|
|
809
|
-
import { useEffect as useEffect5, useMemo as useMemo2, useState as
|
|
943
|
+
import { useEffect as useEffect5, useMemo as useMemo2, useState as useState9 } from "preact/hooks";
|
|
810
944
|
import { Markdown } from "@odla-ai/ui/components";
|
|
811
|
-
import { Fragment as
|
|
945
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
|
|
812
946
|
var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
|
|
813
947
|
function MemberContentArea(props) {
|
|
814
948
|
const {
|
|
@@ -816,12 +950,12 @@ function MemberContentArea(props) {
|
|
|
816
950
|
path = "/api/member-content",
|
|
817
951
|
upsellHref,
|
|
818
952
|
onUpsell,
|
|
819
|
-
loadingContent = /* @__PURE__ */
|
|
820
|
-
emptyContent = /* @__PURE__ */
|
|
953
|
+
loadingContent = /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
|
|
954
|
+
emptyContent = /* @__PURE__ */ jsx11("p", { className: "meeting-note", children: "No member pages have been published yet." })
|
|
821
955
|
} = props;
|
|
822
|
-
const [data, setData] =
|
|
823
|
-
const [error, setError] =
|
|
824
|
-
const [selectedId, setSelectedId] =
|
|
956
|
+
const [data, setData] = useState9(props.initialData ?? null);
|
|
957
|
+
const [error, setError] = useState9(null);
|
|
958
|
+
const [selectedId, setSelectedId] = useState9(
|
|
825
959
|
props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
|
|
826
960
|
);
|
|
827
961
|
useEffect5(() => {
|
|
@@ -846,18 +980,18 @@ function MemberContentArea(props) {
|
|
|
846
980
|
}
|
|
847
981
|
return [...result.entries()];
|
|
848
982
|
}, [data]);
|
|
849
|
-
if (error) return /* @__PURE__ */
|
|
983
|
+
if (error) return /* @__PURE__ */ jsxs11("p", { className: "meeting-note", role: "alert", children: [
|
|
850
984
|
"Member pages could not be loaded: ",
|
|
851
985
|
error
|
|
852
986
|
] });
|
|
853
|
-
if (!data) return /* @__PURE__ */
|
|
854
|
-
if (data.pages.length === 0) return /* @__PURE__ */
|
|
987
|
+
if (!data) return /* @__PURE__ */ jsx11(Fragment5, { children: loadingContent });
|
|
988
|
+
if (data.pages.length === 0) return /* @__PURE__ */ jsx11(Fragment5, { children: emptyContent });
|
|
855
989
|
const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
|
|
856
990
|
const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
|
|
857
|
-
return /* @__PURE__ */
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
991
|
+
return /* @__PURE__ */ jsxs11("div", { className: "chapter-member-content", "data-member-content": true, children: [
|
|
992
|
+
/* @__PURE__ */ jsx11("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs11("section", { className: "chapter-member-content-section", children: [
|
|
993
|
+
/* @__PURE__ */ jsx11("h2", { children: section }),
|
|
994
|
+
/* @__PURE__ */ jsx11("ul", { children: pages.map((page) => /* @__PURE__ */ jsx11("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx11(
|
|
861
995
|
"button",
|
|
862
996
|
{
|
|
863
997
|
type: "button",
|
|
@@ -867,23 +1001,23 @@ function MemberContentArea(props) {
|
|
|
867
1001
|
}
|
|
868
1002
|
) }, page.id)) })
|
|
869
1003
|
] }, section)) }),
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
872
|
-
/* @__PURE__ */
|
|
1004
|
+
/* @__PURE__ */ jsxs11("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
|
|
1005
|
+
/* @__PURE__ */ jsxs11("header", { children: [
|
|
1006
|
+
/* @__PURE__ */ jsxs11("div", { className: "card-label", children: [
|
|
873
1007
|
selected.source.type === "parent" ? "Parent" : "Chapter",
|
|
874
1008
|
" \xB7 ",
|
|
875
1009
|
selected.access
|
|
876
1010
|
] }),
|
|
877
|
-
/* @__PURE__ */
|
|
878
|
-
selected.summary ? /* @__PURE__ */
|
|
1011
|
+
/* @__PURE__ */ jsx11("h1", { children: selected.title }),
|
|
1012
|
+
selected.summary ? /* @__PURE__ */ jsx11("p", { children: selected.summary }) : null
|
|
879
1013
|
] }),
|
|
880
|
-
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */
|
|
881
|
-
selected.teaserMarkdown ? /* @__PURE__ */
|
|
882
|
-
selected.upsell ? /* @__PURE__ */
|
|
883
|
-
/* @__PURE__ */
|
|
884
|
-
/* @__PURE__ */
|
|
885
|
-
selected.upsell.bodyMarkdown ? /* @__PURE__ */
|
|
886
|
-
href ? /* @__PURE__ */
|
|
1014
|
+
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs11("div", { className: "chapter-member-content-locked", children: [
|
|
1015
|
+
selected.teaserMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx11("p", { children: "This page is not included in your current membership." }),
|
|
1016
|
+
selected.upsell ? /* @__PURE__ */ jsxs11("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
|
|
1017
|
+
/* @__PURE__ */ jsx11("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
|
|
1018
|
+
/* @__PURE__ */ jsx11("p", { children: fmtMoney(selected.upsell.priceCents) }),
|
|
1019
|
+
selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx11(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
|
|
1020
|
+
href ? /* @__PURE__ */ jsx11("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx11("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
|
|
887
1021
|
] }) : null
|
|
888
1022
|
] })
|
|
889
1023
|
] })
|
|
@@ -891,12 +1025,12 @@ function MemberContentArea(props) {
|
|
|
891
1025
|
}
|
|
892
1026
|
|
|
893
1027
|
// src/ui/members.tsx
|
|
894
|
-
import { Fragment as
|
|
1028
|
+
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
895
1029
|
function card(copy, kicker, body) {
|
|
896
|
-
return /* @__PURE__ */
|
|
897
|
-
/* @__PURE__ */
|
|
898
|
-
/* @__PURE__ */
|
|
899
|
-
/* @__PURE__ */
|
|
1030
|
+
return /* @__PURE__ */ jsxs12("div", { className: "card", children: [
|
|
1031
|
+
/* @__PURE__ */ jsx12("div", { className: "card-label", children: copy.provisional.cardLabel }),
|
|
1032
|
+
/* @__PURE__ */ jsxs12("div", { className: "meeting-block", children: [
|
|
1033
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-kicker", children: kicker }),
|
|
900
1034
|
body
|
|
901
1035
|
] })
|
|
902
1036
|
] });
|
|
@@ -907,9 +1041,9 @@ function ProvisionalCard(props) {
|
|
|
907
1041
|
return card(
|
|
908
1042
|
copy,
|
|
909
1043
|
copy.provisional.applicationNeeded,
|
|
910
|
-
/* @__PURE__ */
|
|
911
|
-
/* @__PURE__ */
|
|
912
|
-
/* @__PURE__ */
|
|
1044
|
+
/* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1045
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
|
|
1046
|
+
/* @__PURE__ */ jsx12("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
|
|
913
1047
|
] })
|
|
914
1048
|
);
|
|
915
1049
|
}
|
|
@@ -917,19 +1051,19 @@ function ProvisionalCard(props) {
|
|
|
917
1051
|
return card(
|
|
918
1052
|
copy,
|
|
919
1053
|
copy.provisional.refunded,
|
|
920
|
-
/* @__PURE__ */
|
|
1054
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.refundedBody })
|
|
921
1055
|
);
|
|
922
1056
|
}
|
|
923
|
-
const membership = application.paid ? /* @__PURE__ */
|
|
1057
|
+
const membership = application.paid ? /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
|
|
924
1058
|
if (application.meetingAt) {
|
|
925
1059
|
return card(
|
|
926
1060
|
copy,
|
|
927
1061
|
copy.provisional.introductionCall,
|
|
928
|
-
/* @__PURE__ */
|
|
929
|
-
/* @__PURE__ */
|
|
930
|
-
/* @__PURE__ */
|
|
931
|
-
application.meetUrl ? /* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
1062
|
+
/* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1063
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
|
|
1064
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
|
|
1065
|
+
application.meetUrl ? /* @__PURE__ */ jsx12("div", { className: "meeting-note", children: /* @__PURE__ */ jsx12("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
|
|
1066
|
+
/* @__PURE__ */ jsx12(
|
|
933
1067
|
Rescheduler,
|
|
934
1068
|
{
|
|
935
1069
|
api,
|
|
@@ -946,9 +1080,9 @@ function ProvisionalCard(props) {
|
|
|
946
1080
|
return card(
|
|
947
1081
|
copy,
|
|
948
1082
|
copy.provisional.bookCall,
|
|
949
|
-
/* @__PURE__ */
|
|
950
|
-
/* @__PURE__ */
|
|
951
|
-
/* @__PURE__ */
|
|
1083
|
+
/* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1084
|
+
/* @__PURE__ */ jsx12("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
|
|
1085
|
+
/* @__PURE__ */ jsx12(
|
|
952
1086
|
Rescheduler,
|
|
953
1087
|
{
|
|
954
1088
|
api,
|
|
@@ -975,8 +1109,8 @@ function MembersArea(props) {
|
|
|
975
1109
|
renderProvisional
|
|
976
1110
|
} = props;
|
|
977
1111
|
const copy = props.copy ?? inheritedCopy.members;
|
|
978
|
-
const [me, setMe] =
|
|
979
|
-
const [error, setError] =
|
|
1112
|
+
const [me, setMe] = useState10(null);
|
|
1113
|
+
const [error, setError] = useState10(false);
|
|
980
1114
|
const reload = async () => {
|
|
981
1115
|
try {
|
|
982
1116
|
setMe(await api("/api/me"));
|
|
@@ -987,22 +1121,22 @@ function MembersArea(props) {
|
|
|
987
1121
|
useEffect6(() => {
|
|
988
1122
|
void reload();
|
|
989
1123
|
}, []);
|
|
990
|
-
if (error) return /* @__PURE__ */
|
|
991
|
-
if (!me) return /* @__PURE__ */
|
|
1124
|
+
if (error) return /* @__PURE__ */ jsx12("p", { className: "meeting-note", children: copy.loadFailed });
|
|
1125
|
+
if (!me) return /* @__PURE__ */ jsx12("p", { className: "meeting-note", children: inheritedCopy.common.loading });
|
|
992
1126
|
const role = me.role || "provisional";
|
|
993
|
-
return /* @__PURE__ */
|
|
994
|
-
/* @__PURE__ */
|
|
995
|
-
/* @__PURE__ */
|
|
996
|
-
/* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ jsxs12(Fragment6, { children: [
|
|
1128
|
+
/* @__PURE__ */ jsxs12("div", { className: "card", children: [
|
|
1129
|
+
/* @__PURE__ */ jsxs12("div", { className: "member-row", children: [
|
|
1130
|
+
/* @__PURE__ */ jsx12("span", { className: "member-email", children: me.email }),
|
|
1131
|
+
/* @__PURE__ */ jsx12("span", { className: "role-badge " + role, children: role })
|
|
998
1132
|
] }),
|
|
999
|
-
/* @__PURE__ */
|
|
1000
|
-
/* @__PURE__ */
|
|
1001
|
-
me.authorized || me.superAdmin ? /* @__PURE__ */
|
|
1133
|
+
/* @__PURE__ */ jsxs12("div", { className: "account-actions", children: [
|
|
1134
|
+
/* @__PURE__ */ jsx12("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
|
|
1135
|
+
me.authorized || me.superAdmin ? /* @__PURE__ */ jsx12("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
|
|
1002
1136
|
] })
|
|
1003
1137
|
] }),
|
|
1004
|
-
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */
|
|
1005
|
-
const defaultContent = /* @__PURE__ */
|
|
1138
|
+
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx12(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
|
|
1139
|
+
const defaultContent = /* @__PURE__ */ jsx12(
|
|
1006
1140
|
ProvisionalCard,
|
|
1007
1141
|
{
|
|
1008
1142
|
api,
|
|
@@ -1019,30 +1153,30 @@ function MembersArea(props) {
|
|
|
1019
1153
|
reload,
|
|
1020
1154
|
defaultContent
|
|
1021
1155
|
}) ?? defaultContent;
|
|
1022
|
-
})() : memberContent ?? (memberPages ? /* @__PURE__ */
|
|
1156
|
+
})() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx12(
|
|
1023
1157
|
MemberContentArea,
|
|
1024
1158
|
{
|
|
1025
1159
|
api,
|
|
1026
1160
|
...memberPages === true ? {} : memberPages
|
|
1027
1161
|
}
|
|
1028
|
-
) : /* @__PURE__ */
|
|
1029
|
-
/* @__PURE__ */
|
|
1030
|
-
me.namedSeatsEnabled ? /* @__PURE__ */
|
|
1162
|
+
) : /* @__PURE__ */ jsx12("div", { className: "card", children: /* @__PURE__ */ jsx12("div", { className: "card-label", children: copy.full.welcome }) })),
|
|
1163
|
+
/* @__PURE__ */ jsx12(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
|
|
1164
|
+
me.namedSeatsEnabled ? /* @__PURE__ */ jsx12(NamedSeatPurchase, { api }) : null
|
|
1031
1165
|
] });
|
|
1032
1166
|
}
|
|
1033
1167
|
|
|
1034
1168
|
// src/ui/join.tsx
|
|
1035
|
-
import { useEffect as
|
|
1169
|
+
import { useEffect as useEffect11, useRef as useRef3, useState as useState18 } from "preact/hooks";
|
|
1036
1170
|
|
|
1037
1171
|
// src/ui/join-booking.tsx
|
|
1038
|
-
import { useEffect as useEffect7, useState as
|
|
1039
|
-
import { jsx as
|
|
1172
|
+
import { useEffect as useEffect7, useState as useState11 } from "preact/hooks";
|
|
1173
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
1040
1174
|
function JoinBooking(props) {
|
|
1041
1175
|
const { applicationId, copy, onBooked, simulation } = props;
|
|
1042
|
-
const [state, setState] =
|
|
1043
|
-
const [msg, setMsg] =
|
|
1044
|
-
const [busy, setBusy] =
|
|
1045
|
-
const [selected, setSelected] =
|
|
1176
|
+
const [state, setState] = useState11(null);
|
|
1177
|
+
const [msg, setMsg] = useState11(null);
|
|
1178
|
+
const [busy, setBusy] = useState11(false);
|
|
1179
|
+
const [selected, setSelected] = useState11(null);
|
|
1046
1180
|
const load = async () => {
|
|
1047
1181
|
setMsg(null);
|
|
1048
1182
|
try {
|
|
@@ -1099,11 +1233,11 @@ function JoinBooking(props) {
|
|
|
1099
1233
|
setBusy(false);
|
|
1100
1234
|
}
|
|
1101
1235
|
};
|
|
1102
|
-
if (!state) return /* @__PURE__ */
|
|
1103
|
-
return /* @__PURE__ */
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1236
|
+
if (!state) return /* @__PURE__ */ jsx13("p", { className: "slots-status", children: msg ?? copy.loading });
|
|
1237
|
+
return /* @__PURE__ */ jsxs13("div", { className: "join-book", children: [
|
|
1238
|
+
/* @__PURE__ */ jsx13("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
|
|
1239
|
+
/* @__PURE__ */ jsx13("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
|
|
1240
|
+
/* @__PURE__ */ jsx13(
|
|
1107
1241
|
SlotPicker,
|
|
1108
1242
|
{
|
|
1109
1243
|
slots: state.slots,
|
|
@@ -1113,29 +1247,29 @@ function JoinBooking(props) {
|
|
|
1113
1247
|
onDayChange: () => setSelected(null)
|
|
1114
1248
|
}
|
|
1115
1249
|
),
|
|
1116
|
-
/* @__PURE__ */
|
|
1117
|
-
/* @__PURE__ */
|
|
1118
|
-
msg ? /* @__PURE__ */
|
|
1250
|
+
/* @__PURE__ */ jsxs13("div", { className: "slot-confirm", hidden: !selected, children: [
|
|
1251
|
+
/* @__PURE__ */ jsx13("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
|
|
1252
|
+
msg ? /* @__PURE__ */ jsx13("p", { className: "step2-note", children: msg }) : null
|
|
1119
1253
|
] })
|
|
1120
1254
|
] });
|
|
1121
1255
|
}
|
|
1122
1256
|
|
|
1123
1257
|
// src/ui/join-accepted.tsx
|
|
1124
|
-
import { jsx as
|
|
1258
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
1125
1259
|
function JoinAccepted(props) {
|
|
1126
|
-
return /* @__PURE__ */
|
|
1127
|
-
/* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
/* @__PURE__ */
|
|
1260
|
+
return /* @__PURE__ */ jsxs14("div", { className: "join-done card", children: [
|
|
1261
|
+
/* @__PURE__ */ jsx14("div", { className: "card-label", children: props.copy.accepted.label }),
|
|
1262
|
+
/* @__PURE__ */ jsx14("p", { className: "meeting-note", children: props.copy.accepted.body }),
|
|
1263
|
+
/* @__PURE__ */ jsx14("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
|
|
1130
1264
|
] });
|
|
1131
1265
|
}
|
|
1132
1266
|
|
|
1133
1267
|
// src/ui/gift-claim-card.tsx
|
|
1134
|
-
import { useState as
|
|
1135
|
-
import { Fragment as
|
|
1268
|
+
import { useState as useState12 } from "preact/hooks";
|
|
1269
|
+
import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
1136
1270
|
function GiftClaimCard(props) {
|
|
1137
|
-
const [code, setCode] =
|
|
1138
|
-
const [error, setError] =
|
|
1271
|
+
const [code, setCode] = useState12(props.initialCode ?? "");
|
|
1272
|
+
const [error, setError] = useState12(false);
|
|
1139
1273
|
const rotate = async () => {
|
|
1140
1274
|
if (!props.claimId) return;
|
|
1141
1275
|
setError(false);
|
|
@@ -1148,30 +1282,30 @@ function GiftClaimCard(props) {
|
|
|
1148
1282
|
if (response.ok && body.code) setCode(body.code);
|
|
1149
1283
|
else setError(true);
|
|
1150
1284
|
};
|
|
1151
|
-
return /* @__PURE__ */
|
|
1152
|
-
/* @__PURE__ */
|
|
1153
|
-
/* @__PURE__ */
|
|
1154
|
-
code ? /* @__PURE__ */
|
|
1155
|
-
/* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1285
|
+
return /* @__PURE__ */ jsxs15("div", { className: "join-done card", children: [
|
|
1286
|
+
/* @__PURE__ */ jsx15("div", { className: "card-label", children: props.copy.label }),
|
|
1287
|
+
/* @__PURE__ */ jsx15("p", { className: "meeting-note", children: props.copy.body }),
|
|
1288
|
+
code ? /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
1289
|
+
/* @__PURE__ */ jsx15("output", { className: "gift-code", children: code }),
|
|
1290
|
+
/* @__PURE__ */ jsx15("p", { children: props.copy.save })
|
|
1157
1291
|
] }) : null,
|
|
1158
|
-
!code && props.claimId ? /* @__PURE__ */
|
|
1159
|
-
error ? /* @__PURE__ */
|
|
1292
|
+
!code && props.claimId ? /* @__PURE__ */ jsx15("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
|
|
1293
|
+
error ? /* @__PURE__ */ jsx15("p", { role: "alert", children: props.copy.rotateFailed }) : null
|
|
1160
1294
|
] });
|
|
1161
1295
|
}
|
|
1162
1296
|
|
|
1163
1297
|
// src/ui/join-tiers.tsx
|
|
1164
|
-
import { useState as
|
|
1165
|
-
import { Fragment as
|
|
1298
|
+
import { useState as useState13 } from "preact/hooks";
|
|
1299
|
+
import { Fragment as Fragment8, jsx as jsx16, jsxs as jsxs16 } from "preact/jsx-runtime";
|
|
1166
1300
|
var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
1167
1301
|
function useTierSelection(tiers, initialTierId) {
|
|
1168
|
-
const [selectedTierId, setSelectedTierId] =
|
|
1302
|
+
const [selectedTierId, setSelectedTierId] = useState13(() => {
|
|
1169
1303
|
const preset = tiers.find((tier) => tier.id === initialTierId);
|
|
1170
1304
|
if (preset) return preset.id;
|
|
1171
1305
|
return tiers.length === 1 ? tiers[0].id : null;
|
|
1172
1306
|
});
|
|
1173
1307
|
return {
|
|
1174
|
-
tiers,
|
|
1308
|
+
tiers: [...tiers].sort((a, b) => Number(b.id === selectedTierId) - Number(a.id === selectedTierId)),
|
|
1175
1309
|
selected: tiers.find((tier) => tier.id === selectedTierId) ?? null,
|
|
1176
1310
|
selectedTierId,
|
|
1177
1311
|
selectTier: (tierId) => {
|
|
@@ -1180,10 +1314,10 @@ function useTierSelection(tiers, initialTierId) {
|
|
|
1180
1314
|
};
|
|
1181
1315
|
}
|
|
1182
1316
|
function TierPlaceholder(context) {
|
|
1183
|
-
return /* @__PURE__ */
|
|
1184
|
-
/* @__PURE__ */
|
|
1185
|
-
context.tiers.map((tier) => /* @__PURE__ */
|
|
1186
|
-
/* @__PURE__ */
|
|
1317
|
+
return /* @__PURE__ */ jsxs16("fieldset", { "data-chapter-placeholder": "tiers", children: [
|
|
1318
|
+
/* @__PURE__ */ jsx16("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
|
|
1319
|
+
context.tiers.map((tier) => /* @__PURE__ */ jsxs16("label", { children: [
|
|
1320
|
+
/* @__PURE__ */ jsx16(
|
|
1187
1321
|
"input",
|
|
1188
1322
|
{
|
|
1189
1323
|
type: "radio",
|
|
@@ -1194,13 +1328,13 @@ function TierPlaceholder(context) {
|
|
|
1194
1328
|
}
|
|
1195
1329
|
),
|
|
1196
1330
|
tier.name,
|
|
1197
|
-
tier.founding ? /* @__PURE__ */
|
|
1331
|
+
tier.founding ? /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
1198
1332
|
" \u2014 ",
|
|
1199
1333
|
joinTierMoney(tier.founding.dueTodayCents),
|
|
1200
1334
|
" founding member rate (list ",
|
|
1201
1335
|
joinTierMoney(tier.priceCents),
|
|
1202
1336
|
")"
|
|
1203
|
-
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */
|
|
1337
|
+
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs16(Fragment8, { children: [
|
|
1204
1338
|
" \u2014 ",
|
|
1205
1339
|
joinTierMoney(tier.priceCents)
|
|
1206
1340
|
] })
|
|
@@ -1212,19 +1346,19 @@ function tierNeedsPayment(selected, paymentsReady) {
|
|
|
1212
1346
|
}
|
|
1213
1347
|
|
|
1214
1348
|
// src/ui/join-application-form.tsx
|
|
1215
|
-
import { jsx as
|
|
1349
|
+
import { jsx as jsx17, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
1216
1350
|
function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
|
|
1217
1351
|
const disabled = submitting || props.submitDisabled === true;
|
|
1218
|
-
return /* @__PURE__ */
|
|
1219
|
-
!requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1221
|
-
/* @__PURE__ */
|
|
1222
|
-
/* @__PURE__ */
|
|
1352
|
+
return /* @__PURE__ */ jsxs17("form", { className: "join-form", onSubmit: (event) => void submit(event), children: [
|
|
1353
|
+
!requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs17("fieldset", { children: [
|
|
1354
|
+
/* @__PURE__ */ jsx17("legend", { children: copy.gift.optionsLabel }),
|
|
1355
|
+
/* @__PURE__ */ jsx17("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
|
|
1356
|
+
/* @__PURE__ */ jsx17(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
|
|
1223
1357
|
] }) : null,
|
|
1224
1358
|
!requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
|
|
1225
1359
|
typeof props.children === "function" ? props.children({ invitation }) : props.children,
|
|
1226
|
-
error ? /* @__PURE__ */
|
|
1227
|
-
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */
|
|
1360
|
+
error ? /* @__PURE__ */ jsx17("p", { className: "join-error", role: "alert", children: error }) : null,
|
|
1361
|
+
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx17("button", { className: "submit-btn", type: "submit", disabled, children: submitting ? copy.form.submitting : copy.form.submit })
|
|
1228
1362
|
] });
|
|
1229
1363
|
}
|
|
1230
1364
|
|
|
@@ -1249,8 +1383,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
|
|
|
1249
1383
|
|
|
1250
1384
|
// src/ui/gift-code-redeemer.tsx
|
|
1251
1385
|
import { InlineActionField } from "@odla-ai/ui/components";
|
|
1252
|
-
import { useState as
|
|
1253
|
-
import { Fragment as
|
|
1386
|
+
import { useState as useState14 } from "preact/hooks";
|
|
1387
|
+
import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs18 } from "preact/jsx-runtime";
|
|
1254
1388
|
var GIFT_CODE_REDEEMER_CSS = `
|
|
1255
1389
|
.gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
|
|
1256
1390
|
.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}
|
|
@@ -1265,10 +1399,10 @@ var GIFT_CODE_REDEEMER_CSS = `
|
|
|
1265
1399
|
@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%}}
|
|
1266
1400
|
`;
|
|
1267
1401
|
function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
1268
|
-
const [code, setCode] =
|
|
1269
|
-
const [loading, setLoading] =
|
|
1270
|
-
const [message, setMessage] =
|
|
1271
|
-
const [messageTone, setMessageTone] =
|
|
1402
|
+
const [code, setCode] = useState14("");
|
|
1403
|
+
const [loading, setLoading] = useState14(false);
|
|
1404
|
+
const [message, setMessage] = useState14("");
|
|
1405
|
+
const [messageTone, setMessageTone] = useState14("neutral");
|
|
1272
1406
|
const normalizedCode = code.trim();
|
|
1273
1407
|
const redeem = async () => {
|
|
1274
1408
|
if (!normalizedCode || loading) return;
|
|
@@ -1295,9 +1429,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
|
1295
1429
|
setLoading(false);
|
|
1296
1430
|
}
|
|
1297
1431
|
};
|
|
1298
|
-
return /* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1300
|
-
/* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
1433
|
+
/* @__PURE__ */ jsx18("style", { children: GIFT_CODE_REDEEMER_CSS }),
|
|
1434
|
+
/* @__PURE__ */ jsx18(
|
|
1301
1435
|
InlineActionField,
|
|
1302
1436
|
{
|
|
1303
1437
|
id,
|
|
@@ -1353,12 +1487,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
|
|
|
1353
1487
|
}
|
|
1354
1488
|
|
|
1355
1489
|
// src/ui/join-gift-claim.tsx
|
|
1356
|
-
import { jsx as
|
|
1490
|
+
import { jsx as jsx19, jsxs as jsxs19 } from "preact/jsx-runtime";
|
|
1357
1491
|
function JoinGiftClaim(props) {
|
|
1358
|
-
return /* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
1361
|
-
/* @__PURE__ */
|
|
1492
|
+
return /* @__PURE__ */ jsxs19("section", { className: "join-gift-claim card", children: [
|
|
1493
|
+
/* @__PURE__ */ jsx19("div", { className: "card-label", children: props.copy.claimTitle }),
|
|
1494
|
+
/* @__PURE__ */ jsx19("p", { children: props.copy.claimBody }),
|
|
1495
|
+
/* @__PURE__ */ jsx19(
|
|
1362
1496
|
GiftCodeRedeemer,
|
|
1363
1497
|
{
|
|
1364
1498
|
api: props.api,
|
|
@@ -1382,21 +1516,21 @@ function JoinGiftClaim(props) {
|
|
|
1382
1516
|
}
|
|
1383
1517
|
|
|
1384
1518
|
// src/ui/join-named-seat.tsx
|
|
1385
|
-
import { useState as
|
|
1386
|
-
import { jsx as
|
|
1519
|
+
import { useState as useState15 } from "preact/hooks";
|
|
1520
|
+
import { jsx as jsx20, jsxs as jsxs20 } from "preact/jsx-runtime";
|
|
1387
1521
|
function JoinNamedSeat(props) {
|
|
1388
1522
|
const seatId = props.seatId ?? "";
|
|
1389
1523
|
const inherited = useChapterCopy(), copy = props.copy ?? inherited.join.namedSeat;
|
|
1390
|
-
const [accepted, setAccepted] =
|
|
1391
|
-
return /* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1394
|
-
/* @__PURE__ */
|
|
1395
|
-
/* @__PURE__ */
|
|
1396
|
-
/* @__PURE__ */
|
|
1524
|
+
const [accepted, setAccepted] = useState15(false), [busy, setBusy] = useState15(false), [error, setError] = useState15("");
|
|
1525
|
+
return /* @__PURE__ */ jsxs20("section", { className: "join-named-seat card", children: [
|
|
1526
|
+
/* @__PURE__ */ jsx20("h2", { children: copy.title }),
|
|
1527
|
+
/* @__PURE__ */ jsx20("p", { children: copy.body }),
|
|
1528
|
+
/* @__PURE__ */ jsxs20("label", { className: "journey-consent", children: [
|
|
1529
|
+
/* @__PURE__ */ jsx20("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
|
|
1530
|
+
/* @__PURE__ */ jsx20("span", { children: copy.consent })
|
|
1397
1531
|
] }),
|
|
1398
|
-
error ? /* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1532
|
+
error ? /* @__PURE__ */ jsx20("p", { role: "alert", children: error }) : null,
|
|
1533
|
+
/* @__PURE__ */ jsx20("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
|
|
1400
1534
|
setBusy(true);
|
|
1401
1535
|
setError("");
|
|
1402
1536
|
try {
|
|
@@ -1416,12 +1550,12 @@ function JoinNamedSeat(props) {
|
|
|
1416
1550
|
}
|
|
1417
1551
|
|
|
1418
1552
|
// src/ui/join-invitation.tsx
|
|
1419
|
-
import { useEffect as useEffect8, useState as
|
|
1420
|
-
import { jsx as
|
|
1553
|
+
import { useEffect as useEffect8, useState as useState16 } from "preact/hooks";
|
|
1554
|
+
import { jsx as jsx21, jsxs as jsxs21 } from "preact/jsx-runtime";
|
|
1421
1555
|
function useJoinInvitation(seatId, api, fallback) {
|
|
1422
|
-
const [invitation, setInvitation] =
|
|
1423
|
-
const [error, setError] =
|
|
1424
|
-
const [revision, setRevision] =
|
|
1556
|
+
const [invitation, setInvitation] = useState16(null);
|
|
1557
|
+
const [error, setError] = useState16("");
|
|
1558
|
+
const [revision, setRevision] = useState16(0);
|
|
1425
1559
|
useEffect8(() => {
|
|
1426
1560
|
let live = true;
|
|
1427
1561
|
setInvitation(null);
|
|
@@ -1444,9 +1578,9 @@ function useJoinInvitation(seatId, api, fallback) {
|
|
|
1444
1578
|
return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
|
|
1445
1579
|
}
|
|
1446
1580
|
function JoinInvitationNotice(props) {
|
|
1447
|
-
return /* @__PURE__ */
|
|
1448
|
-
/* @__PURE__ */
|
|
1449
|
-
/* @__PURE__ */
|
|
1581
|
+
return /* @__PURE__ */ jsxs21("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
|
|
1582
|
+
/* @__PURE__ */ jsx21("p", { children: /* @__PURE__ */ jsx21("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
|
|
1583
|
+
/* @__PURE__ */ jsx21("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
|
|
1450
1584
|
] });
|
|
1451
1585
|
}
|
|
1452
1586
|
|
|
@@ -1475,10 +1609,93 @@ function useJoinPending(state, loadResume, setState) {
|
|
|
1475
1609
|
}, [state, loadResume]);
|
|
1476
1610
|
}
|
|
1477
1611
|
|
|
1612
|
+
// src/ui/payment-receipt.tsx
|
|
1613
|
+
import { useEffect as useEffect10, useState as useState17 } from "preact/hooks";
|
|
1614
|
+
import { Fragment as Fragment10, jsx as jsx22, jsxs as jsxs22 } from "preact/jsx-runtime";
|
|
1615
|
+
function PaymentReceiptCard({ applicationId }) {
|
|
1616
|
+
const [receipt, setReceipt] = useState17(null);
|
|
1617
|
+
const [error, setError] = useState17("");
|
|
1618
|
+
const [revision, setRevision] = useState17(0);
|
|
1619
|
+
const [emailState, setEmailState] = useState17("idle");
|
|
1620
|
+
const [previewEmail, setPreviewEmail] = useState17(false);
|
|
1621
|
+
const endpoint = `/api/payments/receipt?application=${encodeURIComponent(applicationId)}`;
|
|
1622
|
+
useEffect10(() => {
|
|
1623
|
+
let live = true, timer;
|
|
1624
|
+
setReceipt(null);
|
|
1625
|
+
setError("");
|
|
1626
|
+
setEmailState("idle");
|
|
1627
|
+
const read = async () => {
|
|
1628
|
+
try {
|
|
1629
|
+
const response = await fetch(endpoint, { cache: "no-store" });
|
|
1630
|
+
if (!live || response.status === 404) return;
|
|
1631
|
+
if (response.status === 202) {
|
|
1632
|
+
timer = setTimeout(() => void read(), 2e3);
|
|
1633
|
+
return;
|
|
1634
|
+
}
|
|
1635
|
+
if (!response.ok) throw new Error();
|
|
1636
|
+
const data = await response.json();
|
|
1637
|
+
if (live) setReceipt(data.receipt);
|
|
1638
|
+
} catch {
|
|
1639
|
+
if (live) setError("Your receipt is temporarily unavailable.");
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
void read();
|
|
1643
|
+
return () => {
|
|
1644
|
+
live = false;
|
|
1645
|
+
if (timer) clearTimeout(timer);
|
|
1646
|
+
};
|
|
1647
|
+
}, [endpoint, revision]);
|
|
1648
|
+
if (!receipt) return error ? /* @__PURE__ */ jsxs22("section", { "aria-label": "Payment receipt", children: [
|
|
1649
|
+
/* @__PURE__ */ jsx22("p", { role: "status", children: error }),
|
|
1650
|
+
/* @__PURE__ */ jsx22("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
|
|
1651
|
+
] }) : null;
|
|
1652
|
+
const money = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: receipt.currency }).format(cents / 100);
|
|
1653
|
+
const email = async () => {
|
|
1654
|
+
setEmailState("sending");
|
|
1655
|
+
setError("");
|
|
1656
|
+
try {
|
|
1657
|
+
const response = await fetch(endpoint, { method: "POST" });
|
|
1658
|
+
if (!response.ok) throw new Error();
|
|
1659
|
+
const result = await response.json();
|
|
1660
|
+
setPreviewEmail(result.preview === true);
|
|
1661
|
+
setEmailState("sent");
|
|
1662
|
+
} catch {
|
|
1663
|
+
setEmailState("idle");
|
|
1664
|
+
setError("We could not confirm email delivery. You can print or save your receipt.");
|
|
1665
|
+
}
|
|
1666
|
+
};
|
|
1667
|
+
return /* @__PURE__ */ jsxs22("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
|
|
1668
|
+
/* @__PURE__ */ jsx22("h2", { children: "Payment received" }),
|
|
1669
|
+
/* @__PURE__ */ jsx22("p", { children: receipt.tierName }),
|
|
1670
|
+
/* @__PURE__ */ jsxs22("dl", { className: "journey-summary", children: [
|
|
1671
|
+
/* @__PURE__ */ jsx22("dt", { children: "Membership" }),
|
|
1672
|
+
/* @__PURE__ */ jsx22("dd", { children: money(receipt.membershipCents) }),
|
|
1673
|
+
receipt.namedSeat ? /* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
1674
|
+
/* @__PURE__ */ jsxs22("dt", { children: [
|
|
1675
|
+
"Additional member \u2014 ",
|
|
1676
|
+
receipt.namedSeat.recipientName
|
|
1677
|
+
] }),
|
|
1678
|
+
/* @__PURE__ */ jsxs22("dd", { children: [
|
|
1679
|
+
receipt.namedSeat.amountCents === 0 ? "Included \u2014 " : "",
|
|
1680
|
+
money(receipt.namedSeat.amountCents)
|
|
1681
|
+
] })
|
|
1682
|
+
] }) : null,
|
|
1683
|
+
/* @__PURE__ */ jsx22("dt", { children: "Total paid" }),
|
|
1684
|
+
/* @__PURE__ */ jsx22("dd", { children: money(receipt.totalCents) })
|
|
1685
|
+
] }),
|
|
1686
|
+
/* @__PURE__ */ jsxs22("div", { className: "journey-actions", children: [
|
|
1687
|
+
/* @__PURE__ */ jsx22("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
|
|
1688
|
+
/* @__PURE__ */ jsx22("button", { type: "button", disabled: emailState !== "idle", onClick: () => void email(), children: emailState === "sending" ? "Sending\u2026" : emailState === "sent" ? "Receipt emailed" : "Email me my receipt" })
|
|
1689
|
+
] }),
|
|
1690
|
+
emailState === "sent" ? /* @__PURE__ */ jsx22("p", { role: "status", children: previewEmail ? "Test receipt sent to the configured test inbox." : "Sent to the email used for your payment." }) : null,
|
|
1691
|
+
error ? /* @__PURE__ */ jsx22("p", { role: "alert", children: error }) : null
|
|
1692
|
+
] });
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1478
1695
|
// src/ui/join.tsx
|
|
1479
|
-
import { Fragment as
|
|
1696
|
+
import { Fragment as Fragment11, jsx as jsx23, jsxs as jsxs23 } from "preact/jsx-runtime";
|
|
1480
1697
|
function JoinIsland(props) {
|
|
1481
|
-
return /* @__PURE__ */
|
|
1698
|
+
return /* @__PURE__ */ jsx23(JourneyFrame, { children: /* @__PURE__ */ jsx23(JoinFlow, { ...props }) });
|
|
1482
1699
|
}
|
|
1483
1700
|
function JoinFlow(props) {
|
|
1484
1701
|
const inheritedCopy = useChapterCopy();
|
|
@@ -1499,10 +1716,10 @@ function JoinFlow(props) {
|
|
|
1499
1716
|
const invitation = invitationState.invitation;
|
|
1500
1717
|
const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
|
|
1501
1718
|
const selectedTier = tiers.find((tier) => tier.id === selectedTierId) ?? tierSelection.selected;
|
|
1502
|
-
const [state, setState] =
|
|
1503
|
-
const [error, setError] =
|
|
1504
|
-
const [submitting, setSubmitting] =
|
|
1505
|
-
const [giftOfferId, setGiftOfferId] =
|
|
1719
|
+
const [state, setState] = useState18(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
|
|
1720
|
+
const [error, setError] = useState18(null);
|
|
1721
|
+
const [submitting, setSubmitting] = useState18(false);
|
|
1722
|
+
const [giftOfferId, setGiftOfferId] = useState18(props.initialGiftOfferId ?? null);
|
|
1506
1723
|
const simulatedPayment = props.simulation ? props.simulation.payment ?? {
|
|
1507
1724
|
lineItems: {
|
|
1508
1725
|
standardCents: selectedTier?.priceCents ?? 0,
|
|
@@ -1512,7 +1729,7 @@ function JoinFlow(props) {
|
|
|
1512
1729
|
} : void 0;
|
|
1513
1730
|
const simulatedBooking = props.simulation ? props.simulation.booking ?? { slots: [], timezone: "UTC" } : void 0;
|
|
1514
1731
|
const submissionId = useRef3(null);
|
|
1515
|
-
|
|
1732
|
+
useEffect11(() => {
|
|
1516
1733
|
if (props.simulation) return;
|
|
1517
1734
|
const resolver = requestedSeat ? () => invitation?.applicationId ? loadJoinResume(invitation.applicationId) : Promise.resolve(null) : props.loadResume ?? (() => {
|
|
1518
1735
|
if (typeof window === "undefined") return Promise.resolve(null);
|
|
@@ -1581,13 +1798,13 @@ function JoinFlow(props) {
|
|
|
1581
1798
|
setSubmitting(false);
|
|
1582
1799
|
}
|
|
1583
1800
|
};
|
|
1584
|
-
if (requestedSeat && !invitation) return /* @__PURE__ */
|
|
1585
|
-
/* @__PURE__ */
|
|
1586
|
-
/* @__PURE__ */
|
|
1587
|
-
invitationState.error ? /* @__PURE__ */
|
|
1801
|
+
if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs23("section", { className: "card", "aria-live": "polite", children: [
|
|
1802
|
+
/* @__PURE__ */ jsx23("h2", { children: seatCopy.title }),
|
|
1803
|
+
/* @__PURE__ */ jsx23("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
|
|
1804
|
+
invitationState.error ? /* @__PURE__ */ jsx23("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
|
|
1588
1805
|
] });
|
|
1589
|
-
const header = /* @__PURE__ */
|
|
1590
|
-
invitation ? /* @__PURE__ */
|
|
1806
|
+
const header = /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1807
|
+
invitation ? /* @__PURE__ */ jsx23(
|
|
1591
1808
|
JoinInvitationNotice,
|
|
1592
1809
|
{
|
|
1593
1810
|
invitation,
|
|
@@ -1599,48 +1816,49 @@ function JoinFlow(props) {
|
|
|
1599
1816
|
state,
|
|
1600
1817
|
...invitation ? { invitation } : {},
|
|
1601
1818
|
..."applicationId" in state ? { applicationId: state.applicationId } : {}
|
|
1602
|
-
})
|
|
1819
|
+
}),
|
|
1820
|
+
!props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx23(PaymentReceiptCard, { applicationId: state.applicationId }) : null
|
|
1603
1821
|
] });
|
|
1604
1822
|
if (state.step === "closed") {
|
|
1605
|
-
return /* @__PURE__ */
|
|
1823
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1606
1824
|
header,
|
|
1607
|
-
/* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1610
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsxs23("section", { className: "card", "aria-label": "Application closed", children: [
|
|
1826
|
+
/* @__PURE__ */ jsx23("h2", { children: "This application is closed" }),
|
|
1827
|
+
/* @__PURE__ */ jsx23("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
|
|
1828
|
+
/* @__PURE__ */ jsx23("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
1611
1829
|
] })
|
|
1612
1830
|
] });
|
|
1613
1831
|
}
|
|
1614
1832
|
if (state.step === "done") {
|
|
1615
|
-
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1616
|
-
/* @__PURE__ */
|
|
1617
|
-
/* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
/* @__PURE__ */
|
|
1833
|
+
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs23("div", { className: "join-done card", children: [
|
|
1834
|
+
/* @__PURE__ */ jsx23("div", { className: "card-label", children: copy.done.label }),
|
|
1835
|
+
/* @__PURE__ */ jsx23("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
|
|
1836
|
+
/* @__PURE__ */ jsx23("p", { className: "meeting-note", children: copy.done.calendarInvite }),
|
|
1837
|
+
/* @__PURE__ */ jsx23("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
1620
1838
|
] });
|
|
1621
|
-
return /* @__PURE__ */
|
|
1839
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1622
1840
|
header,
|
|
1623
1841
|
body
|
|
1624
1842
|
] });
|
|
1625
1843
|
}
|
|
1626
1844
|
if (state.step === "accepted") {
|
|
1627
|
-
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1628
|
-
return /* @__PURE__ */
|
|
1845
|
+
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx23(JoinAccepted, { copy, membersHref });
|
|
1846
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1629
1847
|
header,
|
|
1630
1848
|
body
|
|
1631
1849
|
] });
|
|
1632
1850
|
}
|
|
1633
1851
|
if (state.step === "gift") {
|
|
1634
|
-
const body = renderGift?.(state) ?? /* @__PURE__ */
|
|
1635
|
-
return /* @__PURE__ */
|
|
1852
|
+
const body = renderGift?.(state) ?? /* @__PURE__ */ jsx23(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
|
|
1853
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1636
1854
|
header,
|
|
1637
1855
|
body
|
|
1638
1856
|
] });
|
|
1639
1857
|
}
|
|
1640
1858
|
if (state.step === "booking") {
|
|
1641
|
-
return /* @__PURE__ */
|
|
1859
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1642
1860
|
header,
|
|
1643
|
-
/* @__PURE__ */
|
|
1861
|
+
/* @__PURE__ */ jsx23(
|
|
1644
1862
|
JoinBooking,
|
|
1645
1863
|
{
|
|
1646
1864
|
applicationId: state.applicationId,
|
|
@@ -1655,9 +1873,9 @@ function JoinFlow(props) {
|
|
|
1655
1873
|
}
|
|
1656
1874
|
if (state.step === "payment") {
|
|
1657
1875
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
|
|
1658
|
-
return /* @__PURE__ */
|
|
1876
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1659
1877
|
header,
|
|
1660
|
-
/* @__PURE__ */
|
|
1878
|
+
/* @__PURE__ */ jsx23(
|
|
1661
1879
|
JoinNamedSeat,
|
|
1662
1880
|
{
|
|
1663
1881
|
api: props.namedSeatClaimApi,
|
|
@@ -1670,9 +1888,9 @@ function JoinFlow(props) {
|
|
|
1670
1888
|
] });
|
|
1671
1889
|
}
|
|
1672
1890
|
const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
|
|
1673
|
-
return /* @__PURE__ */
|
|
1891
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1674
1892
|
header,
|
|
1675
|
-
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */
|
|
1893
|
+
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx23(
|
|
1676
1894
|
JoinGiftClaim,
|
|
1677
1895
|
{
|
|
1678
1896
|
api: props.giftClaimApi,
|
|
@@ -1683,7 +1901,7 @@ function JoinFlow(props) {
|
|
|
1683
1901
|
onError: () => setError(copy.form.unexpectedFailure)
|
|
1684
1902
|
}
|
|
1685
1903
|
) : null,
|
|
1686
|
-
/* @__PURE__ */
|
|
1904
|
+
/* @__PURE__ */ jsx23(
|
|
1687
1905
|
Payment,
|
|
1688
1906
|
{
|
|
1689
1907
|
applicationId: state.applicationId,
|
|
@@ -1691,6 +1909,7 @@ function JoinFlow(props) {
|
|
|
1691
1909
|
merchantDisclosureText: config.merchantDisclosureText,
|
|
1692
1910
|
copy: copy.payment,
|
|
1693
1911
|
appearance: props.payment?.appearance,
|
|
1912
|
+
initialNamedSeat: props.payment?.initialNamedSeat,
|
|
1694
1913
|
fonts: props.payment?.fonts,
|
|
1695
1914
|
renderPriceLines: props.payment?.renderPriceLines,
|
|
1696
1915
|
simulation: simulatedPayment,
|
|
@@ -1712,9 +1931,9 @@ function JoinFlow(props) {
|
|
|
1712
1931
|
}
|
|
1713
1932
|
if (state.step === "paymentPending") {
|
|
1714
1933
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
|
|
1715
|
-
return /* @__PURE__ */
|
|
1934
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1716
1935
|
header,
|
|
1717
|
-
/* @__PURE__ */
|
|
1936
|
+
/* @__PURE__ */ jsx23(
|
|
1718
1937
|
JoinNamedSeat,
|
|
1719
1938
|
{
|
|
1720
1939
|
api: props.namedSeatClaimApi,
|
|
@@ -1726,14 +1945,14 @@ function JoinFlow(props) {
|
|
|
1726
1945
|
)
|
|
1727
1946
|
] });
|
|
1728
1947
|
}
|
|
1729
|
-
return /* @__PURE__ */
|
|
1948
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1730
1949
|
header,
|
|
1731
|
-
/* @__PURE__ */
|
|
1950
|
+
/* @__PURE__ */ jsx23("p", { className: "pay-status", role: "status", children: copy.payment.pending })
|
|
1732
1951
|
] });
|
|
1733
1952
|
}
|
|
1734
|
-
return /* @__PURE__ */
|
|
1953
|
+
return /* @__PURE__ */ jsxs23(Fragment11, { children: [
|
|
1735
1954
|
header,
|
|
1736
|
-
/* @__PURE__ */
|
|
1955
|
+
/* @__PURE__ */ jsx23(
|
|
1737
1956
|
JoinApplicationForm,
|
|
1738
1957
|
{
|
|
1739
1958
|
props,
|
|
@@ -1923,7 +2142,7 @@ function membershipPageDocument(input, options = {}) {
|
|
|
1923
2142
|
}
|
|
1924
2143
|
|
|
1925
2144
|
// src/ui/membership-cards.tsx
|
|
1926
|
-
import { jsx as
|
|
2145
|
+
import { jsx as jsx24, jsxs as jsxs24 } from "preact/jsx-runtime";
|
|
1927
2146
|
var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
|
|
1928
2147
|
"--ui-membership-grid-gap": "1.4rem",
|
|
1929
2148
|
"--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
|
|
@@ -1992,67 +2211,67 @@ function membershipApplicationHref(applicationPath, tierId) {
|
|
|
1992
2211
|
}
|
|
1993
2212
|
function TierAction(props) {
|
|
1994
2213
|
if (props.mode === "select") {
|
|
1995
|
-
return /* @__PURE__ */
|
|
2214
|
+
return /* @__PURE__ */ jsxs24("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
|
|
1996
2215
|
props.label,
|
|
1997
|
-
/* @__PURE__ */
|
|
2216
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": "true", children: "\u2192" })
|
|
1998
2217
|
] });
|
|
1999
2218
|
}
|
|
2000
2219
|
if (props.mode === "preview") {
|
|
2001
|
-
return /* @__PURE__ */
|
|
2220
|
+
return /* @__PURE__ */ jsxs24("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
|
|
2002
2221
|
props.label,
|
|
2003
|
-
/* @__PURE__ */
|
|
2222
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": "true", children: "\u2192" })
|
|
2004
2223
|
] });
|
|
2005
2224
|
}
|
|
2006
|
-
return /* @__PURE__ */
|
|
2225
|
+
return /* @__PURE__ */ jsxs24("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
|
|
2007
2226
|
props.label,
|
|
2008
|
-
/* @__PURE__ */
|
|
2227
|
+
/* @__PURE__ */ jsx24("span", { "aria-hidden": "true", children: "\u2192" })
|
|
2009
2228
|
] });
|
|
2010
2229
|
}
|
|
2011
2230
|
function TierCard(props) {
|
|
2012
2231
|
const { tier, presentation } = props;
|
|
2013
2232
|
const summary = presentation.summaryMarkdown ?? tier.blurb;
|
|
2014
2233
|
const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
|
|
2015
|
-
return /* @__PURE__ */
|
|
2016
|
-
presentation.badge ? /* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
presentation.capacity ? /* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2021
|
-
/* @__PURE__ */
|
|
2234
|
+
return /* @__PURE__ */ jsxs24("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
|
|
2235
|
+
presentation.badge ? /* @__PURE__ */ jsx24("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
|
|
2236
|
+
/* @__PURE__ */ jsx24("h3", { className: "chapter-membership-name", children: tier.name }),
|
|
2237
|
+
/* @__PURE__ */ jsxs24("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
|
|
2238
|
+
presentation.capacity ? /* @__PURE__ */ jsxs24("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
|
|
2239
|
+
/* @__PURE__ */ jsx24("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
|
|
2240
|
+
/* @__PURE__ */ jsx24("small", { children: presentation.capacity.label ?? "available" })
|
|
2022
2241
|
] }) : null,
|
|
2023
|
-
/* @__PURE__ */
|
|
2024
|
-
presentation.priceEyebrow ? /* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2026
|
-
tier.founding ? /* @__PURE__ */
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
!tier.free && presentation.billingLabel ? /* @__PURE__ */
|
|
2242
|
+
/* @__PURE__ */ jsxs24("div", { className: "chapter-membership-price-stack", children: [
|
|
2243
|
+
presentation.priceEyebrow ? /* @__PURE__ */ jsx24("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx24("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
|
|
2244
|
+
/* @__PURE__ */ jsxs24("div", { className: "chapter-membership-price-row", children: [
|
|
2245
|
+
tier.founding ? /* @__PURE__ */ jsx24("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx24("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
|
|
2246
|
+
/* @__PURE__ */ jsx24("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
|
|
2247
|
+
!tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx24("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
|
|
2029
2248
|
] })
|
|
2030
2249
|
] })
|
|
2031
2250
|
] }),
|
|
2032
|
-
presentation.priceNoteMarkdown ? /* @__PURE__ */
|
|
2033
|
-
summary ? /* @__PURE__ */
|
|
2034
|
-
presentation.benefits?.length ? /* @__PURE__ */
|
|
2035
|
-
/* @__PURE__ */
|
|
2036
|
-
/* @__PURE__ */
|
|
2251
|
+
presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx24(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
|
|
2252
|
+
summary ? /* @__PURE__ */ jsx24(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
|
|
2253
|
+
presentation.benefits?.length ? /* @__PURE__ */ jsx24("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs24("li", { children: [
|
|
2254
|
+
/* @__PURE__ */ jsx24("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
|
|
2255
|
+
/* @__PURE__ */ jsx24(Markdown2, { className: "chapter-membership-benefit", source: benefit })
|
|
2037
2256
|
] }, `${tier.id}-benefit-${index}`)) }) : null,
|
|
2038
|
-
presentation.callout ? /* @__PURE__ */
|
|
2039
|
-
presentation.callout.label ? /* @__PURE__ */
|
|
2040
|
-
/* @__PURE__ */
|
|
2257
|
+
presentation.callout ? /* @__PURE__ */ jsxs24("aside", { className: "chapter-membership-callout", children: [
|
|
2258
|
+
presentation.callout.label ? /* @__PURE__ */ jsx24("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
|
|
2259
|
+
/* @__PURE__ */ jsx24(Markdown2, { source: presentation.callout.bodyMarkdown })
|
|
2041
2260
|
] }) : null,
|
|
2042
|
-
/* @__PURE__ */
|
|
2261
|
+
/* @__PURE__ */ jsx24(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
|
|
2043
2262
|
] });
|
|
2044
2263
|
}
|
|
2045
2264
|
function MembershipCards(props) {
|
|
2046
2265
|
const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
|
|
2047
2266
|
const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
|
|
2048
2267
|
const mode = props.mode ?? "link";
|
|
2049
|
-
return /* @__PURE__ */
|
|
2050
|
-
/* @__PURE__ */
|
|
2051
|
-
/* @__PURE__ */
|
|
2268
|
+
return /* @__PURE__ */ jsxs24("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
|
|
2269
|
+
/* @__PURE__ */ jsx24("style", { children: MEMBERSHIP_CARDS_CSS }),
|
|
2270
|
+
/* @__PURE__ */ jsx24("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
|
|
2052
2271
|
const tier = byId.get(presentation.tierId);
|
|
2053
|
-
return /* @__PURE__ */
|
|
2272
|
+
return /* @__PURE__ */ jsx24(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
|
|
2054
2273
|
}) }),
|
|
2055
|
-
document2.footnoteMarkdown ? /* @__PURE__ */
|
|
2274
|
+
document2.footnoteMarkdown ? /* @__PURE__ */ jsx24(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
|
|
2056
2275
|
] });
|
|
2057
2276
|
}
|
|
2058
2277
|
|
|
@@ -2088,4 +2307,4 @@ export {
|
|
|
2088
2307
|
membershipApplicationHref,
|
|
2089
2308
|
MembershipCards
|
|
2090
2309
|
};
|
|
2091
|
-
//# sourceMappingURL=chunk-
|
|
2310
|
+
//# sourceMappingURL=chunk-IQZWCG42.js.map
|