@odla-ai/chapter 0.41.1 → 0.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -12
- package/dist/{chunk-IAWBE5PX.js → chunk-JXFYOUDL.js} +8 -2
- package/dist/chunk-JXFYOUDL.js.map +1 -0
- package/dist/{chunk-O22RRPBT.js → chunk-MMDWXTJU.js} +2 -2
- package/dist/{chunk-PCRYLPMQ.js → chunk-S7CND3R5.js} +373 -327
- package/dist/chunk-S7CND3R5.js.map +1 -0
- package/dist/{copy-context-B14OOiYq.d.ts → copy-context-BNUzbL5g.d.ts} +19 -1
- package/dist/index.cjs +67 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -2
- package/dist/index.d.ts +66 -2
- package/dist/index.js +67 -11
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +2 -2
- package/dist/ui/admin/index.js +2 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +5 -3
- package/dist/ui/member/index.d.ts +37 -9
- package/dist/ui/member/index.js +4 -2
- package/dist/worker/index.cjs +368 -62
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +19 -1
- package/dist/worker/index.d.ts +19 -1
- package/dist/worker/index.js +361 -55
- package/dist/worker/index.js.map +1 -1
- package/package.json +2 -2
- package/runbooks/greenfield.md +3 -0
- package/dist/chunk-IAWBE5PX.js.map +0 -1
- package/dist/chunk-PCRYLPMQ.js.map +0 -1
- /package/dist/{chunk-O22RRPBT.js.map → chunk-MMDWXTJU.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
formatChapterCopy,
|
|
3
3
|
useChapterCopy
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-JXFYOUDL.js";
|
|
5
5
|
import {
|
|
6
6
|
collectFormFields
|
|
7
7
|
} from "./chunk-IVXVECKR.js";
|
|
@@ -110,7 +110,7 @@ function SlotPicker(props) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// src/ui/members.tsx
|
|
113
|
-
import { useEffect as useEffect3, useState as
|
|
113
|
+
import { useEffect as useEffect3, useState as useState6 } from "preact/hooks";
|
|
114
114
|
|
|
115
115
|
// src/ui/reschedule.tsx
|
|
116
116
|
import { useState as useState2 } from "preact/hooks";
|
|
@@ -195,7 +195,7 @@ function Rescheduler(props) {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// src/ui/member-gifts.tsx
|
|
198
|
-
import { useEffect, useRef as useRef2, useState as
|
|
198
|
+
import { useEffect, useRef as useRef2, useState as useState4 } from "preact/hooks";
|
|
199
199
|
|
|
200
200
|
// src/ui/gift-offer-cards.tsx
|
|
201
201
|
import { jsx as jsx3, jsxs as jsxs3 } from "preact/jsx-runtime";
|
|
@@ -213,94 +213,9 @@ function GiftOfferCards(props) {
|
|
|
213
213
|
] }, offer.id)) });
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
// src/ui/gift-code-redeemer.tsx
|
|
217
|
-
import { InlineActionField } from "@odla-ai/ui/components";
|
|
218
|
-
import { useState as useState3 } from "preact/hooks";
|
|
219
|
-
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
220
|
-
var GIFT_CODE_REDEEMER_CSS = `
|
|
221
|
-
.gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
|
|
222
|
-
.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}
|
|
223
|
-
.gift-code-redeemer .inline-action-field-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--ui-space-2,.65rem);align-items:stretch}
|
|
224
|
-
.gift-code-redeemer .inline-action-field-input,.gift-code-redeemer .inline-action-field-action{min-height:var(--ui-inline-action-control-height,38px)}
|
|
225
|
-
.gift-code-redeemer .inline-action-field-input.code{font-family:var(--ui-font-mono,ui-monospace,monospace);font-variant-ligatures:none;letter-spacing:var(--ui-tracking-wide,.04em)}
|
|
226
|
-
.gift-code-redeemer .inline-action-field-input:focus-visible{outline:none;border-color:var(--ui-accent,#168c84);box-shadow:var(--ui-focus,0 0 0 3px rgb(22 140 132 / .18))}
|
|
227
|
-
.gift-code-redeemer .inline-action-field-action{white-space:nowrap}
|
|
228
|
-
.gift-code-redeemer .inline-action-field-status{display:block;min-block-size:1.4em;margin:0;color:var(--ui-text-muted,#66777f);font-size:var(--ui-text-sm,.8rem);line-height:1.4}
|
|
229
|
-
.gift-code-redeemer .inline-action-field-status.success{color:var(--ui-good,#1f7a52)}
|
|
230
|
-
.gift-code-redeemer .inline-action-field-status.error{color:var(--ui-danger,#b42318)}
|
|
231
|
-
@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%}}
|
|
232
|
-
`;
|
|
233
|
-
function GiftCodeRedeemer({ api, copy, id, onRedeemed }) {
|
|
234
|
-
const [code, setCode] = useState3("");
|
|
235
|
-
const [loading, setLoading] = useState3(false);
|
|
236
|
-
const [message, setMessage] = useState3("");
|
|
237
|
-
const [messageTone, setMessageTone] = useState3("neutral");
|
|
238
|
-
const normalizedCode = code.trim();
|
|
239
|
-
const redeem = async () => {
|
|
240
|
-
if (!normalizedCode || loading) return;
|
|
241
|
-
setLoading(true);
|
|
242
|
-
setMessage("");
|
|
243
|
-
setMessageTone("neutral");
|
|
244
|
-
try {
|
|
245
|
-
await api("/api/gifts/redeem", {
|
|
246
|
-
method: "POST",
|
|
247
|
-
headers: { "content-type": "application/json" },
|
|
248
|
-
body: JSON.stringify({ code: normalizedCode })
|
|
249
|
-
});
|
|
250
|
-
setCode("");
|
|
251
|
-
setMessage(copy.redeemed);
|
|
252
|
-
setMessageTone("success");
|
|
253
|
-
try {
|
|
254
|
-
await onRedeemed?.();
|
|
255
|
-
} catch {
|
|
256
|
-
}
|
|
257
|
-
} catch {
|
|
258
|
-
setMessage(copy.redeemFailed);
|
|
259
|
-
setMessageTone("error");
|
|
260
|
-
} finally {
|
|
261
|
-
setLoading(false);
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
265
|
-
/* @__PURE__ */ jsx4("style", { children: GIFT_CODE_REDEEMER_CSS }),
|
|
266
|
-
/* @__PURE__ */ jsx4(
|
|
267
|
-
InlineActionField,
|
|
268
|
-
{
|
|
269
|
-
id,
|
|
270
|
-
className: "gift-code-redeemer",
|
|
271
|
-
label: copy.code,
|
|
272
|
-
value: code,
|
|
273
|
-
code: true,
|
|
274
|
-
actionLabel: copy.redeem,
|
|
275
|
-
loadingLabel: `${copy.redeem}\u2026`,
|
|
276
|
-
loading,
|
|
277
|
-
actionDisabled: !normalizedCode,
|
|
278
|
-
message,
|
|
279
|
-
messageTone,
|
|
280
|
-
inputProps: {
|
|
281
|
-
name: "giftCode",
|
|
282
|
-
maxLength: 64,
|
|
283
|
-
autoComplete: "one-time-code",
|
|
284
|
-
autoCapitalize: "none",
|
|
285
|
-
autocorrect: "off",
|
|
286
|
-
spellcheck: false
|
|
287
|
-
},
|
|
288
|
-
onValueChange: (value) => {
|
|
289
|
-
setCode(value);
|
|
290
|
-
if (message) {
|
|
291
|
-
setMessage("");
|
|
292
|
-
setMessageTone("neutral");
|
|
293
|
-
}
|
|
294
|
-
},
|
|
295
|
-
onAction: () => void redeem()
|
|
296
|
-
}
|
|
297
|
-
)
|
|
298
|
-
] });
|
|
299
|
-
}
|
|
300
|
-
|
|
301
216
|
// src/ui/payment-step.tsx
|
|
302
|
-
import { useRef, useState as
|
|
303
|
-
import { jsx as
|
|
217
|
+
import { useRef, useState as useState3 } from "preact/hooks";
|
|
218
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "preact/jsx-runtime";
|
|
304
219
|
var loader = null;
|
|
305
220
|
function loadStripe() {
|
|
306
221
|
const existing = globalThis.Stripe;
|
|
@@ -334,9 +249,9 @@ function PaymentStep(props) {
|
|
|
334
249
|
simulation
|
|
335
250
|
} = props;
|
|
336
251
|
const copy = props.copy ?? inheritedCopy.join.payment;
|
|
337
|
-
const [status, setStatus] =
|
|
338
|
-
const [error, setError] =
|
|
339
|
-
const [lineItems, setLineItems] =
|
|
252
|
+
const [status, setStatus] = useState3("idle");
|
|
253
|
+
const [error, setError] = useState3(null);
|
|
254
|
+
const [lineItems, setLineItems] = useState3(null);
|
|
340
255
|
const mountRef = useRef(null);
|
|
341
256
|
const stripeRef = useRef(null);
|
|
342
257
|
const elementsRef = useRef(null);
|
|
@@ -410,12 +325,12 @@ function PaymentStep(props) {
|
|
|
410
325
|
setStatus("ready");
|
|
411
326
|
}
|
|
412
327
|
};
|
|
413
|
-
return /* @__PURE__ */
|
|
414
|
-
/* @__PURE__ */
|
|
415
|
-
merchantDisclosureText ? /* @__PURE__ */
|
|
416
|
-
/* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
418
|
-
/* @__PURE__ */
|
|
328
|
+
return /* @__PURE__ */ jsxs4("div", { className: "join-pay", children: [
|
|
329
|
+
/* @__PURE__ */ jsxs4("div", { className: "compliance-box", children: [
|
|
330
|
+
merchantDisclosureText ? /* @__PURE__ */ jsx4("p", { className: "compliance-merchant", children: merchantDisclosureText }) : null,
|
|
331
|
+
/* @__PURE__ */ jsx4("p", { className: "compliance-policy", children: refundPolicyText }),
|
|
332
|
+
/* @__PURE__ */ jsxs4("label", { className: "compliance-check", children: [
|
|
333
|
+
/* @__PURE__ */ jsx4(
|
|
419
334
|
"input",
|
|
420
335
|
{
|
|
421
336
|
type: "checkbox",
|
|
@@ -425,41 +340,41 @@ function PaymentStep(props) {
|
|
|
425
340
|
}
|
|
426
341
|
}
|
|
427
342
|
),
|
|
428
|
-
copy.consent ? /* @__PURE__ */
|
|
343
|
+
copy.consent ? /* @__PURE__ */ jsx4("span", { children: copy.consent }) : null
|
|
429
344
|
] })
|
|
430
345
|
] }),
|
|
431
|
-
status === "loading" ? /* @__PURE__ */
|
|
346
|
+
status === "loading" ? /* @__PURE__ */ jsx4("p", { className: "pay-status", children: copy.preparing }) : null,
|
|
432
347
|
lineItems && renderPriceLines ? renderPriceLines(lineItems) : null,
|
|
433
348
|
children,
|
|
434
|
-
simulation && (status === "ready" || status === "confirming") ? /* @__PURE__ */
|
|
435
|
-
/* @__PURE__ */
|
|
436
|
-
/* @__PURE__ */
|
|
349
|
+
simulation && (status === "ready" || status === "confirming") ? /* @__PURE__ */ jsxs4("fieldset", { className: "join-pay-simulation", children: [
|
|
350
|
+
/* @__PURE__ */ jsx4("legend", { children: "Payment details" }),
|
|
351
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
437
352
|
"Card number",
|
|
438
|
-
/* @__PURE__ */
|
|
353
|
+
/* @__PURE__ */ jsx4("input", { name: "simulationCardNumber", inputMode: "numeric", autoComplete: "off", defaultValue: "4242 4242 4242 4242" })
|
|
439
354
|
] }),
|
|
440
|
-
/* @__PURE__ */
|
|
355
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
441
356
|
"Expiration",
|
|
442
|
-
/* @__PURE__ */
|
|
357
|
+
/* @__PURE__ */ jsx4("input", { name: "simulationCardExpiry", inputMode: "numeric", autoComplete: "off", defaultValue: "12 / 34" })
|
|
443
358
|
] }),
|
|
444
|
-
/* @__PURE__ */
|
|
359
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
445
360
|
"Security code",
|
|
446
|
-
/* @__PURE__ */
|
|
361
|
+
/* @__PURE__ */ jsx4("input", { name: "simulationCardCvc", inputMode: "numeric", autoComplete: "off", defaultValue: "123" })
|
|
447
362
|
] }),
|
|
448
|
-
/* @__PURE__ */
|
|
363
|
+
/* @__PURE__ */ jsx4("p", { children: "This is a simulation. No card data is sent and no charge is created." })
|
|
449
364
|
] }) : null,
|
|
450
|
-
/* @__PURE__ */
|
|
451
|
-
status === "ready" || status === "confirming" ? /* @__PURE__ */
|
|
452
|
-
error ? /* @__PURE__ */
|
|
365
|
+
/* @__PURE__ */ jsx4("div", { ref: mountRef, hidden: status === "idle" || status === "loading" }),
|
|
366
|
+
status === "ready" || status === "confirming" ? /* @__PURE__ */ jsx4("button", { className: "submit-btn", disabled: status === "confirming", onClick: () => void pay(), children: status === "confirming" ? copy.processing : copy.payAndContinue }) : null,
|
|
367
|
+
error ? /* @__PURE__ */ jsx4("p", { className: "pay-error", children: error }) : null
|
|
453
368
|
] });
|
|
454
369
|
}
|
|
455
370
|
|
|
456
371
|
// src/ui/member-gifts.tsx
|
|
457
|
-
import { jsx as
|
|
458
|
-
function
|
|
459
|
-
const [data, setData] =
|
|
460
|
-
const [selected, setSelected] =
|
|
461
|
-
const [code, setCode] =
|
|
462
|
-
const [message, setMessage] =
|
|
372
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
|
|
373
|
+
function GiftPurchases(props) {
|
|
374
|
+
const [data, setData] = useState4(null);
|
|
375
|
+
const [selected, setSelected] = useState4(null);
|
|
376
|
+
const [code, setCode] = useState4("");
|
|
377
|
+
const [message, setMessage] = useState4("");
|
|
463
378
|
const purchaseId = useRef2(crypto.randomUUID());
|
|
464
379
|
const load = async () => setData(await props.api("/api/gifts"));
|
|
465
380
|
useEffect(() => {
|
|
@@ -475,17 +390,18 @@ function MemberGifts(props) {
|
|
|
475
390
|
}
|
|
476
391
|
};
|
|
477
392
|
if (!data) return null;
|
|
393
|
+
if (data.offers.length === 0 && data.claims.length === 0) return null;
|
|
478
394
|
const offer = data.offers.find((item) => item.id === selected);
|
|
479
|
-
return /* @__PURE__ */
|
|
480
|
-
/* @__PURE__ */
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
|
|
395
|
+
return /* @__PURE__ */ jsxs5("section", { className: "member-gifts", children: [
|
|
396
|
+
data.offers.length ? /* @__PURE__ */ jsxs5("div", { className: "card", children: [
|
|
397
|
+
/* @__PURE__ */ jsx5("div", { className: "card-label", children: props.copy.title }),
|
|
398
|
+
/* @__PURE__ */ jsx5("p", { children: props.copy.body }),
|
|
399
|
+
/* @__PURE__ */ jsx5(GiftOfferCards, { offers: data.offers, mode: "select", selectedOfferId: selected, onSelect: (id) => {
|
|
484
400
|
setSelected(id);
|
|
485
401
|
setCode("");
|
|
486
402
|
purchaseId.current = crypto.randomUUID();
|
|
487
|
-
} })
|
|
488
|
-
offer ? /* @__PURE__ */
|
|
403
|
+
} }),
|
|
404
|
+
offer ? /* @__PURE__ */ jsx5(
|
|
489
405
|
PaymentStep,
|
|
490
406
|
{
|
|
491
407
|
applicationId: purchaseId.current,
|
|
@@ -505,31 +421,28 @@ function MemberGifts(props) {
|
|
|
505
421
|
}
|
|
506
422
|
}
|
|
507
423
|
) : null,
|
|
508
|
-
code ? /* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
510
|
-
/* @__PURE__ */
|
|
424
|
+
code ? /* @__PURE__ */ jsxs5("div", { className: "gift-code-once", children: [
|
|
425
|
+
/* @__PURE__ */ jsx5("output", { children: code }),
|
|
426
|
+
/* @__PURE__ */ jsx5("p", { children: props.copy.saveCode })
|
|
511
427
|
] }) : null
|
|
512
|
-
] }),
|
|
513
|
-
/* @__PURE__ */
|
|
514
|
-
/* @__PURE__ */
|
|
515
|
-
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */
|
|
516
|
-
/* @__PURE__ */
|
|
517
|
-
/* @__PURE__ */
|
|
518
|
-
claim.status === "pending" ? /* @__PURE__ */
|
|
519
|
-
] }, claim.id)) : /* @__PURE__ */
|
|
520
|
-
|
|
521
|
-
/* @__PURE__ */ jsxs6("div", { className: "card", children: [
|
|
522
|
-
/* @__PURE__ */ jsx6("div", { className: "card-label", children: props.copy.redeemTitle }),
|
|
523
|
-
/* @__PURE__ */ jsx6(GiftCodeRedeemer, { api: props.api, copy: props.copy, onRedeemed: load }),
|
|
524
|
-
message ? /* @__PURE__ */ jsx6("p", { role: "status", children: message }) : null
|
|
428
|
+
] }) : null,
|
|
429
|
+
/* @__PURE__ */ jsxs5("div", { className: "card", children: [
|
|
430
|
+
/* @__PURE__ */ jsx5("div", { className: "card-label", children: props.copy.purchases }),
|
|
431
|
+
data.claims.length ? data.claims.map((claim) => /* @__PURE__ */ jsxs5("div", { className: "member-row", children: [
|
|
432
|
+
/* @__PURE__ */ jsx5("span", { children: claim.offerId }),
|
|
433
|
+
/* @__PURE__ */ jsx5("span", { children: props.copy[claim.status] }),
|
|
434
|
+
claim.status === "pending" ? /* @__PURE__ */ jsx5("button", { className: "btn secondary mini", onClick: () => void rotate(claim.id), children: props.copy.rotate }) : null
|
|
435
|
+
] }, claim.id)) : /* @__PURE__ */ jsx5("p", { children: props.copy.noPurchases }),
|
|
436
|
+
message ? /* @__PURE__ */ jsx5("p", { role: "status", children: message }) : null
|
|
525
437
|
] })
|
|
526
438
|
] });
|
|
527
439
|
}
|
|
440
|
+
var MemberGifts = GiftPurchases;
|
|
528
441
|
|
|
529
442
|
// src/ui/member-content.tsx
|
|
530
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useState as
|
|
443
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState5 } from "preact/hooks";
|
|
531
444
|
import { Markdown } from "@odla-ai/ui/components";
|
|
532
|
-
import { Fragment as
|
|
445
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "preact/jsx-runtime";
|
|
533
446
|
var pageLabel = (page) => `${page.title}${page.access === "locked" ? " \xB7 Locked" : ""}`;
|
|
534
447
|
function MemberContentArea(props) {
|
|
535
448
|
const {
|
|
@@ -537,12 +450,12 @@ function MemberContentArea(props) {
|
|
|
537
450
|
path = "/api/member-content",
|
|
538
451
|
upsellHref,
|
|
539
452
|
onUpsell,
|
|
540
|
-
loadingContent = /* @__PURE__ */
|
|
541
|
-
emptyContent = /* @__PURE__ */
|
|
453
|
+
loadingContent = /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: "Loading member pages\u2026" }),
|
|
454
|
+
emptyContent = /* @__PURE__ */ jsx6("p", { className: "meeting-note", children: "No member pages have been published yet." })
|
|
542
455
|
} = props;
|
|
543
|
-
const [data, setData] =
|
|
544
|
-
const [error, setError] =
|
|
545
|
-
const [selectedId, setSelectedId] =
|
|
456
|
+
const [data, setData] = useState5(props.initialData ?? null);
|
|
457
|
+
const [error, setError] = useState5(null);
|
|
458
|
+
const [selectedId, setSelectedId] = useState5(
|
|
546
459
|
props.initialPageId ?? props.initialData?.pages[0]?.id ?? ""
|
|
547
460
|
);
|
|
548
461
|
useEffect2(() => {
|
|
@@ -567,18 +480,18 @@ function MemberContentArea(props) {
|
|
|
567
480
|
}
|
|
568
481
|
return [...result.entries()];
|
|
569
482
|
}, [data]);
|
|
570
|
-
if (error) return /* @__PURE__ */
|
|
483
|
+
if (error) return /* @__PURE__ */ jsxs6("p", { className: "meeting-note", role: "alert", children: [
|
|
571
484
|
"Member pages could not be loaded: ",
|
|
572
485
|
error
|
|
573
486
|
] });
|
|
574
|
-
if (!data) return /* @__PURE__ */
|
|
575
|
-
if (data.pages.length === 0) return /* @__PURE__ */
|
|
487
|
+
if (!data) return /* @__PURE__ */ jsx6(Fragment2, { children: loadingContent });
|
|
488
|
+
if (data.pages.length === 0) return /* @__PURE__ */ jsx6(Fragment2, { children: emptyContent });
|
|
576
489
|
const selected = data.pages.find((page) => page.id === selectedId) ?? data.pages[0];
|
|
577
490
|
const href = selected.upsell && upsellHref ? upsellHref(selected.upsell.tierId, selected) : void 0;
|
|
578
|
-
return /* @__PURE__ */
|
|
579
|
-
/* @__PURE__ */
|
|
580
|
-
/* @__PURE__ */
|
|
581
|
-
/* @__PURE__ */
|
|
491
|
+
return /* @__PURE__ */ jsxs6("div", { className: "chapter-member-content", "data-member-content": true, children: [
|
|
492
|
+
/* @__PURE__ */ jsx6("nav", { className: "chapter-member-content-nav", "aria-label": "Member pages", children: sections.map(([section, pages]) => /* @__PURE__ */ jsxs6("section", { className: "chapter-member-content-section", children: [
|
|
493
|
+
/* @__PURE__ */ jsx6("h2", { children: section }),
|
|
494
|
+
/* @__PURE__ */ jsx6("ul", { children: pages.map((page) => /* @__PURE__ */ jsx6("li", { "data-parent-page": page.navigation.parentId ?? void 0, children: /* @__PURE__ */ jsx6(
|
|
582
495
|
"button",
|
|
583
496
|
{
|
|
584
497
|
type: "button",
|
|
@@ -588,23 +501,23 @@ function MemberContentArea(props) {
|
|
|
588
501
|
}
|
|
589
502
|
) }, page.id)) })
|
|
590
503
|
] }, section)) }),
|
|
591
|
-
/* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
/* @__PURE__ */
|
|
504
|
+
/* @__PURE__ */ jsxs6("article", { className: "chapter-member-content-page", "data-access": selected.access, children: [
|
|
505
|
+
/* @__PURE__ */ jsxs6("header", { children: [
|
|
506
|
+
/* @__PURE__ */ jsxs6("div", { className: "card-label", children: [
|
|
594
507
|
selected.source.type === "parent" ? "Parent" : "Chapter",
|
|
595
508
|
" \xB7 ",
|
|
596
509
|
selected.access
|
|
597
510
|
] }),
|
|
598
|
-
/* @__PURE__ */
|
|
599
|
-
selected.summary ? /* @__PURE__ */
|
|
511
|
+
/* @__PURE__ */ jsx6("h1", { children: selected.title }),
|
|
512
|
+
selected.summary ? /* @__PURE__ */ jsx6("p", { children: selected.summary }) : null
|
|
600
513
|
] }),
|
|
601
|
-
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */
|
|
602
|
-
selected.teaserMarkdown ? /* @__PURE__ */
|
|
603
|
-
selected.upsell ? /* @__PURE__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
selected.upsell.bodyMarkdown ? /* @__PURE__ */
|
|
607
|
-
href ? /* @__PURE__ */
|
|
514
|
+
selected.access === "allowed" && selected.bodyMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.bodyMarkdown }) : /* @__PURE__ */ jsxs6("div", { className: "chapter-member-content-locked", children: [
|
|
515
|
+
selected.teaserMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.teaserMarkdown }) : /* @__PURE__ */ jsx6("p", { children: "This page is not included in your current membership." }),
|
|
516
|
+
selected.upsell ? /* @__PURE__ */ jsxs6("aside", { className: "chapter-member-content-upsell", "aria-label": selected.upsell.label ?? "Membership option", children: [
|
|
517
|
+
/* @__PURE__ */ jsx6("h2", { children: selected.upsell.label ?? selected.upsell.tierName }),
|
|
518
|
+
/* @__PURE__ */ jsx6("p", { children: fmtMoney(selected.upsell.priceCents) }),
|
|
519
|
+
selected.upsell.bodyMarkdown ? /* @__PURE__ */ jsx6(Markdown, { source: selected.upsell.bodyMarkdown }) : null,
|
|
520
|
+
href ? /* @__PURE__ */ jsx6("a", { className: "btn primary", href, children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : onUpsell ? /* @__PURE__ */ jsx6("button", { className: "btn primary", type: "button", onClick: () => onUpsell(selected.upsell.tierId, selected), children: selected.upsell.ctaLabel ?? `Explore ${selected.upsell.tierName}` }) : null
|
|
608
521
|
] }) : null
|
|
609
522
|
] })
|
|
610
523
|
] })
|
|
@@ -612,12 +525,12 @@ function MemberContentArea(props) {
|
|
|
612
525
|
}
|
|
613
526
|
|
|
614
527
|
// src/ui/members.tsx
|
|
615
|
-
import { Fragment as
|
|
528
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "preact/jsx-runtime";
|
|
616
529
|
function card(copy, kicker, body) {
|
|
617
|
-
return /* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
619
|
-
/* @__PURE__ */
|
|
620
|
-
/* @__PURE__ */
|
|
530
|
+
return /* @__PURE__ */ jsxs7("div", { className: "card", children: [
|
|
531
|
+
/* @__PURE__ */ jsx7("div", { className: "card-label", children: copy.provisional.cardLabel }),
|
|
532
|
+
/* @__PURE__ */ jsxs7("div", { className: "meeting-block", children: [
|
|
533
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-kicker", children: kicker }),
|
|
621
534
|
body
|
|
622
535
|
] })
|
|
623
536
|
] });
|
|
@@ -628,9 +541,9 @@ function ProvisionalCard(props) {
|
|
|
628
541
|
return card(
|
|
629
542
|
copy,
|
|
630
543
|
copy.provisional.applicationNeeded,
|
|
631
|
-
/* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
/* @__PURE__ */
|
|
544
|
+
/* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
545
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
|
|
546
|
+
/* @__PURE__ */ jsx7("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
|
|
634
547
|
] })
|
|
635
548
|
);
|
|
636
549
|
}
|
|
@@ -638,19 +551,19 @@ function ProvisionalCard(props) {
|
|
|
638
551
|
return card(
|
|
639
552
|
copy,
|
|
640
553
|
copy.provisional.refunded,
|
|
641
|
-
/* @__PURE__ */
|
|
554
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.refundedBody })
|
|
642
555
|
);
|
|
643
556
|
}
|
|
644
|
-
const membership = application.paid ? /* @__PURE__ */
|
|
557
|
+
const membership = application.paid ? /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
|
|
645
558
|
if (application.meetingAt) {
|
|
646
559
|
return card(
|
|
647
560
|
copy,
|
|
648
561
|
copy.provisional.introductionCall,
|
|
649
|
-
/* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
651
|
-
/* @__PURE__ */
|
|
652
|
-
application.meetUrl ? /* @__PURE__ */
|
|
653
|
-
/* @__PURE__ */
|
|
562
|
+
/* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
563
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
|
|
564
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
|
|
565
|
+
application.meetUrl ? /* @__PURE__ */ jsx7("div", { className: "meeting-note", children: /* @__PURE__ */ jsx7("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
|
|
566
|
+
/* @__PURE__ */ jsx7(
|
|
654
567
|
Rescheduler,
|
|
655
568
|
{
|
|
656
569
|
api,
|
|
@@ -667,9 +580,9 @@ function ProvisionalCard(props) {
|
|
|
667
580
|
return card(
|
|
668
581
|
copy,
|
|
669
582
|
copy.provisional.bookCall,
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
583
|
+
/* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
584
|
+
/* @__PURE__ */ jsx7("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
|
|
585
|
+
/* @__PURE__ */ jsx7(
|
|
673
586
|
Rescheduler,
|
|
674
587
|
{
|
|
675
588
|
api,
|
|
@@ -696,8 +609,8 @@ function MembersArea(props) {
|
|
|
696
609
|
renderProvisional
|
|
697
610
|
} = props;
|
|
698
611
|
const copy = props.copy ?? inheritedCopy.members;
|
|
699
|
-
const [me, setMe] =
|
|
700
|
-
const [error, setError] =
|
|
612
|
+
const [me, setMe] = useState6(null);
|
|
613
|
+
const [error, setError] = useState6(false);
|
|
701
614
|
const reload = async () => {
|
|
702
615
|
try {
|
|
703
616
|
setMe(await api("/api/me"));
|
|
@@ -708,22 +621,22 @@ function MembersArea(props) {
|
|
|
708
621
|
useEffect3(() => {
|
|
709
622
|
void reload();
|
|
710
623
|
}, []);
|
|
711
|
-
if (error) return /* @__PURE__ */
|
|
712
|
-
if (!me) return /* @__PURE__ */
|
|
624
|
+
if (error) return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: copy.loadFailed });
|
|
625
|
+
if (!me) return /* @__PURE__ */ jsx7("p", { className: "meeting-note", children: inheritedCopy.common.loading });
|
|
713
626
|
const role = me.role || "provisional";
|
|
714
|
-
return /* @__PURE__ */
|
|
715
|
-
/* @__PURE__ */
|
|
716
|
-
/* @__PURE__ */
|
|
717
|
-
/* @__PURE__ */
|
|
718
|
-
/* @__PURE__ */
|
|
627
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
628
|
+
/* @__PURE__ */ jsxs7("div", { className: "card", children: [
|
|
629
|
+
/* @__PURE__ */ jsxs7("div", { className: "member-row", children: [
|
|
630
|
+
/* @__PURE__ */ jsx7("span", { className: "member-email", children: me.email }),
|
|
631
|
+
/* @__PURE__ */ jsx7("span", { className: "role-badge " + role, children: role })
|
|
719
632
|
] }),
|
|
720
|
-
/* @__PURE__ */
|
|
721
|
-
/* @__PURE__ */
|
|
722
|
-
role === "admin" ? /* @__PURE__ */
|
|
633
|
+
/* @__PURE__ */ jsxs7("div", { className: "account-actions", children: [
|
|
634
|
+
/* @__PURE__ */ jsx7("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
|
|
635
|
+
role === "admin" ? /* @__PURE__ */ jsx7("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
|
|
723
636
|
] })
|
|
724
637
|
] }),
|
|
725
638
|
role === "provisional" ? (() => {
|
|
726
|
-
const defaultContent = /* @__PURE__ */
|
|
639
|
+
const defaultContent = /* @__PURE__ */ jsx7(
|
|
727
640
|
ProvisionalCard,
|
|
728
641
|
{
|
|
729
642
|
api,
|
|
@@ -740,14 +653,14 @@ function MembersArea(props) {
|
|
|
740
653
|
reload,
|
|
741
654
|
defaultContent
|
|
742
655
|
}) ?? defaultContent;
|
|
743
|
-
})() : memberContent ?? (memberPages ? /* @__PURE__ */
|
|
656
|
+
})() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx7(
|
|
744
657
|
MemberContentArea,
|
|
745
658
|
{
|
|
746
659
|
api,
|
|
747
660
|
...memberPages === true ? {} : memberPages
|
|
748
661
|
}
|
|
749
|
-
) : /* @__PURE__ */
|
|
750
|
-
/* @__PURE__ */
|
|
662
|
+
) : /* @__PURE__ */ jsx7("div", { className: "card", children: /* @__PURE__ */ jsx7("div", { className: "card-label", children: copy.full.welcome }) })),
|
|
663
|
+
/* @__PURE__ */ jsx7(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment })
|
|
751
664
|
] });
|
|
752
665
|
}
|
|
753
666
|
|
|
@@ -755,14 +668,14 @@ function MembersArea(props) {
|
|
|
755
668
|
import { useEffect as useEffect5, useRef as useRef3, useState as useState11 } from "preact/hooks";
|
|
756
669
|
|
|
757
670
|
// src/ui/join-booking.tsx
|
|
758
|
-
import { useEffect as useEffect4, useState as
|
|
759
|
-
import { jsx as
|
|
671
|
+
import { useEffect as useEffect4, useState as useState7 } from "preact/hooks";
|
|
672
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "preact/jsx-runtime";
|
|
760
673
|
function JoinBooking(props) {
|
|
761
674
|
const { applicationId, copy, onBooked, simulation } = props;
|
|
762
|
-
const [state, setState] =
|
|
763
|
-
const [msg, setMsg] =
|
|
764
|
-
const [busy, setBusy] =
|
|
765
|
-
const [selected, setSelected] =
|
|
675
|
+
const [state, setState] = useState7(null);
|
|
676
|
+
const [msg, setMsg] = useState7(null);
|
|
677
|
+
const [busy, setBusy] = useState7(false);
|
|
678
|
+
const [selected, setSelected] = useState7(null);
|
|
766
679
|
const load = async () => {
|
|
767
680
|
setMsg(null);
|
|
768
681
|
try {
|
|
@@ -819,9 +732,9 @@ function JoinBooking(props) {
|
|
|
819
732
|
setBusy(false);
|
|
820
733
|
}
|
|
821
734
|
};
|
|
822
|
-
if (!state) return /* @__PURE__ */
|
|
823
|
-
return /* @__PURE__ */
|
|
824
|
-
/* @__PURE__ */
|
|
735
|
+
if (!state) return /* @__PURE__ */ jsx8("p", { className: "slots-status", children: msg ?? copy.loading });
|
|
736
|
+
return /* @__PURE__ */ jsxs8("div", { className: "join-book", children: [
|
|
737
|
+
/* @__PURE__ */ jsx8(
|
|
825
738
|
SlotPicker,
|
|
826
739
|
{
|
|
827
740
|
slots: state.slots,
|
|
@@ -831,29 +744,29 @@ function JoinBooking(props) {
|
|
|
831
744
|
onDayChange: () => setSelected(null)
|
|
832
745
|
}
|
|
833
746
|
),
|
|
834
|
-
/* @__PURE__ */
|
|
835
|
-
/* @__PURE__ */
|
|
836
|
-
msg ? /* @__PURE__ */
|
|
747
|
+
/* @__PURE__ */ jsxs8("div", { className: "slot-confirm", hidden: !selected, children: [
|
|
748
|
+
/* @__PURE__ */ jsx8("button", { className: "submit-btn", disabled: busy, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
|
|
749
|
+
msg ? /* @__PURE__ */ jsx8("p", { className: "step2-note", children: msg }) : null
|
|
837
750
|
] })
|
|
838
751
|
] });
|
|
839
752
|
}
|
|
840
753
|
|
|
841
754
|
// src/ui/join-accepted.tsx
|
|
842
|
-
import { jsx as
|
|
755
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "preact/jsx-runtime";
|
|
843
756
|
function JoinAccepted(props) {
|
|
844
|
-
return /* @__PURE__ */
|
|
845
|
-
/* @__PURE__ */
|
|
846
|
-
/* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
757
|
+
return /* @__PURE__ */ jsxs9("div", { className: "join-done card", children: [
|
|
758
|
+
/* @__PURE__ */ jsx9("div", { className: "card-label", children: props.copy.accepted.label }),
|
|
759
|
+
/* @__PURE__ */ jsx9("p", { className: "meeting-note", children: props.copy.accepted.body }),
|
|
760
|
+
/* @__PURE__ */ jsx9("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
|
|
848
761
|
] });
|
|
849
762
|
}
|
|
850
763
|
|
|
851
764
|
// src/ui/gift-claim-card.tsx
|
|
852
|
-
import { useState as
|
|
853
|
-
import { Fragment as
|
|
765
|
+
import { useState as useState8 } from "preact/hooks";
|
|
766
|
+
import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs10 } from "preact/jsx-runtime";
|
|
854
767
|
function GiftClaimCard(props) {
|
|
855
|
-
const [code, setCode] =
|
|
856
|
-
const [error, setError] =
|
|
768
|
+
const [code, setCode] = useState8(props.initialCode ?? "");
|
|
769
|
+
const [error, setError] = useState8(false);
|
|
857
770
|
const rotate = async () => {
|
|
858
771
|
if (!props.claimId) return;
|
|
859
772
|
setError(false);
|
|
@@ -866,21 +779,166 @@ function GiftClaimCard(props) {
|
|
|
866
779
|
if (response.ok && body.code) setCode(body.code);
|
|
867
780
|
else setError(true);
|
|
868
781
|
};
|
|
869
|
-
return /* @__PURE__ */
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
872
|
-
code ? /* @__PURE__ */
|
|
873
|
-
/* @__PURE__ */
|
|
874
|
-
/* @__PURE__ */
|
|
782
|
+
return /* @__PURE__ */ jsxs10("div", { className: "join-done card", children: [
|
|
783
|
+
/* @__PURE__ */ jsx10("div", { className: "card-label", children: props.copy.label }),
|
|
784
|
+
/* @__PURE__ */ jsx10("p", { className: "meeting-note", children: props.copy.body }),
|
|
785
|
+
code ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
786
|
+
/* @__PURE__ */ jsx10("output", { className: "gift-code", children: code }),
|
|
787
|
+
/* @__PURE__ */ jsx10("p", { children: props.copy.save })
|
|
875
788
|
] }) : null,
|
|
876
|
-
!code && props.claimId ? /* @__PURE__ */
|
|
877
|
-
error ? /* @__PURE__ */
|
|
789
|
+
!code && props.claimId ? /* @__PURE__ */ jsx10("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
|
|
790
|
+
error ? /* @__PURE__ */ jsx10("p", { role: "alert", children: props.copy.rotateFailed }) : null
|
|
791
|
+
] });
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/ui/join-application-response.ts
|
|
795
|
+
function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedGiftPurchase) {
|
|
796
|
+
if (!data.id) return null;
|
|
797
|
+
if (data.state === "accepted") return { step: "accepted", applicationId: data.id };
|
|
798
|
+
if (data.state === "paymentPending") return { step: "paymentPending", applicationId: data.id };
|
|
799
|
+
if (data.state === "booking") return { step: "booking", applicationId: data.id };
|
|
800
|
+
if (data.state === "payment") return {
|
|
801
|
+
step: "payment",
|
|
802
|
+
applicationId: data.id,
|
|
803
|
+
...data.giftPurchase || submittedGiftPurchase ? { giftPurchase: true } : {}
|
|
804
|
+
};
|
|
805
|
+
return fallbackNeedsPayment ? { step: "payment", applicationId: data.id, ...submittedGiftPurchase ? { giftPurchase: true } : {} } : { step: "booking", applicationId: data.id };
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/ui/gift-code-redeemer.tsx
|
|
809
|
+
import { InlineActionField } from "@odla-ai/ui/components";
|
|
810
|
+
import { useState as useState9 } from "preact/hooks";
|
|
811
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs11 } from "preact/jsx-runtime";
|
|
812
|
+
var GIFT_CODE_REDEEMER_CSS = `
|
|
813
|
+
.gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
|
|
814
|
+
.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}
|
|
815
|
+
.gift-code-redeemer .inline-action-field-row{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--ui-space-2,.65rem);align-items:stretch}
|
|
816
|
+
.gift-code-redeemer .inline-action-field-input,.gift-code-redeemer .inline-action-field-action{min-height:var(--ui-inline-action-control-height,38px)}
|
|
817
|
+
.gift-code-redeemer .inline-action-field-input.code{font-family:var(--ui-font-mono,ui-monospace,monospace);font-variant-ligatures:none;letter-spacing:var(--ui-tracking-wide,.04em)}
|
|
818
|
+
.gift-code-redeemer .inline-action-field-input:focus-visible{outline:none;border-color:var(--ui-accent,#168c84);box-shadow:var(--ui-focus,0 0 0 3px rgb(22 140 132 / .18))}
|
|
819
|
+
.gift-code-redeemer .inline-action-field-action{white-space:nowrap}
|
|
820
|
+
.gift-code-redeemer .inline-action-field-status{display:block;min-block-size:1.4em;margin:0;color:var(--ui-text-muted,#66777f);font-size:var(--ui-text-sm,.8rem);line-height:1.4}
|
|
821
|
+
.gift-code-redeemer .inline-action-field-status.success{color:var(--ui-good,#1f7a52)}
|
|
822
|
+
.gift-code-redeemer .inline-action-field-status.error{color:var(--ui-danger,#b42318)}
|
|
823
|
+
@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%}}
|
|
824
|
+
`;
|
|
825
|
+
function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
826
|
+
const [code, setCode] = useState9("");
|
|
827
|
+
const [loading, setLoading] = useState9(false);
|
|
828
|
+
const [message, setMessage] = useState9("");
|
|
829
|
+
const [messageTone, setMessageTone] = useState9("neutral");
|
|
830
|
+
const normalizedCode = code.trim();
|
|
831
|
+
const redeem = async () => {
|
|
832
|
+
if (!normalizedCode || loading) return;
|
|
833
|
+
setLoading(true);
|
|
834
|
+
setMessage("");
|
|
835
|
+
setMessageTone("neutral");
|
|
836
|
+
try {
|
|
837
|
+
const result = await api("/api/gifts/redeem", {
|
|
838
|
+
method: "POST",
|
|
839
|
+
headers: { "content-type": "application/json" },
|
|
840
|
+
body: JSON.stringify({ code: normalizedCode, applicationId })
|
|
841
|
+
});
|
|
842
|
+
setCode("");
|
|
843
|
+
setMessage(copy.redeemed);
|
|
844
|
+
setMessageTone("success");
|
|
845
|
+
try {
|
|
846
|
+
await onRedeemed?.(result);
|
|
847
|
+
} catch {
|
|
848
|
+
}
|
|
849
|
+
} catch {
|
|
850
|
+
setMessage(copy.redeemFailed);
|
|
851
|
+
setMessageTone("error");
|
|
852
|
+
} finally {
|
|
853
|
+
setLoading(false);
|
|
854
|
+
}
|
|
855
|
+
};
|
|
856
|
+
return /* @__PURE__ */ jsxs11(Fragment5, { children: [
|
|
857
|
+
/* @__PURE__ */ jsx11("style", { children: GIFT_CODE_REDEEMER_CSS }),
|
|
858
|
+
/* @__PURE__ */ jsx11(
|
|
859
|
+
InlineActionField,
|
|
860
|
+
{
|
|
861
|
+
id,
|
|
862
|
+
className: "gift-code-redeemer",
|
|
863
|
+
label: copy.code,
|
|
864
|
+
value: code,
|
|
865
|
+
code: true,
|
|
866
|
+
actionLabel: copy.redeem,
|
|
867
|
+
loadingLabel: `${copy.redeem}\u2026`,
|
|
868
|
+
loading,
|
|
869
|
+
actionDisabled: !normalizedCode,
|
|
870
|
+
message,
|
|
871
|
+
messageTone,
|
|
872
|
+
inputProps: {
|
|
873
|
+
name: "giftCode",
|
|
874
|
+
maxLength: 64,
|
|
875
|
+
autoComplete: "one-time-code",
|
|
876
|
+
autoCapitalize: "none",
|
|
877
|
+
autocorrect: "off",
|
|
878
|
+
spellcheck: false
|
|
879
|
+
},
|
|
880
|
+
onValueChange: (value) => {
|
|
881
|
+
setCode(value);
|
|
882
|
+
if (message) {
|
|
883
|
+
setMessage("");
|
|
884
|
+
setMessageTone("neutral");
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
onAction: () => void redeem()
|
|
888
|
+
}
|
|
889
|
+
)
|
|
890
|
+
] });
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// src/ui/join-resume.ts
|
|
894
|
+
async function loadJoinResume(applicationId, fetcher = fetch) {
|
|
895
|
+
const res = await fetcher(`/api/join/resume?application=${encodeURIComponent(applicationId)}`);
|
|
896
|
+
const data = await res.json();
|
|
897
|
+
if (!res.ok) throw new Error(data.error ?? "The application could not be resumed.");
|
|
898
|
+
if (data.state === "done" && data.booked) return { step: "done", applicationId: data.applicationId, booked: data.booked };
|
|
899
|
+
if (data.state === "paymentPending") return { step: "paymentPending", applicationId: data.applicationId };
|
|
900
|
+
if (data.state === "booking") return { step: "booking", applicationId: data.applicationId };
|
|
901
|
+
if (data.state === "accepted") return { step: "accepted", applicationId: data.applicationId };
|
|
902
|
+
if (data.state === "gift") return { step: "gift", applicationId: data.applicationId, ...data.claimId ? { claimId: data.claimId } : {} };
|
|
903
|
+
return {
|
|
904
|
+
step: "payment",
|
|
905
|
+
applicationId: data.applicationId,
|
|
906
|
+
...data.giftPurchase ? { giftPurchase: true } : {}
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/ui/join-gift-claim.tsx
|
|
911
|
+
import { jsx as jsx12, jsxs as jsxs12 } from "preact/jsx-runtime";
|
|
912
|
+
function JoinGiftClaim(props) {
|
|
913
|
+
return /* @__PURE__ */ jsxs12("section", { className: "join-gift-claim card", children: [
|
|
914
|
+
/* @__PURE__ */ jsx12("div", { className: "card-label", children: props.copy.claimTitle }),
|
|
915
|
+
/* @__PURE__ */ jsx12("p", { children: props.copy.claimBody }),
|
|
916
|
+
/* @__PURE__ */ jsx12(
|
|
917
|
+
GiftCodeRedeemer,
|
|
918
|
+
{
|
|
919
|
+
api: props.api,
|
|
920
|
+
applicationId: props.applicationId,
|
|
921
|
+
copy: props.copy,
|
|
922
|
+
onRedeemed: async (result) => {
|
|
923
|
+
if (result.state === "booking" || result.state === "accepted") {
|
|
924
|
+
props.onState({ step: result.state, applicationId: result.applicationId });
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
try {
|
|
928
|
+
const resumed = props.loadResume ? await props.loadResume() : await loadJoinResume(result.applicationId);
|
|
929
|
+
if (resumed) props.onState(resumed);
|
|
930
|
+
} catch {
|
|
931
|
+
props.onError();
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
)
|
|
878
936
|
] });
|
|
879
937
|
}
|
|
880
938
|
|
|
881
939
|
// src/ui/join-tiers.tsx
|
|
882
940
|
import { useState as useState10 } from "preact/hooks";
|
|
883
|
-
import { jsx as
|
|
941
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "preact/jsx-runtime";
|
|
884
942
|
function useTierSelection(tiers, initialTierId) {
|
|
885
943
|
const [selectedTierId, setSelectedTierId] = useState10(() => {
|
|
886
944
|
const preset = tiers.find((tier) => tier.id === initialTierId);
|
|
@@ -897,10 +955,10 @@ function useTierSelection(tiers, initialTierId) {
|
|
|
897
955
|
};
|
|
898
956
|
}
|
|
899
957
|
function TierPlaceholder(context) {
|
|
900
|
-
return /* @__PURE__ */
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
context.tiers.map((tier) => /* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
958
|
+
return /* @__PURE__ */ jsxs13("fieldset", { "data-chapter-placeholder": "tiers", children: [
|
|
959
|
+
/* @__PURE__ */ jsx13("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
|
|
960
|
+
context.tiers.map((tier) => /* @__PURE__ */ jsxs13("label", { children: [
|
|
961
|
+
/* @__PURE__ */ jsx13(
|
|
904
962
|
"input",
|
|
905
963
|
{
|
|
906
964
|
type: "radio",
|
|
@@ -918,21 +976,8 @@ function tierNeedsPayment(selected, paymentsReady) {
|
|
|
918
976
|
return selected ? !selected.free && paymentsReady : paymentsReady;
|
|
919
977
|
}
|
|
920
978
|
|
|
921
|
-
// src/ui/join-resume.ts
|
|
922
|
-
async function loadJoinResume(applicationId, fetcher = fetch) {
|
|
923
|
-
const res = await fetcher(`/api/join/resume?application=${encodeURIComponent(applicationId)}`);
|
|
924
|
-
const data = await res.json();
|
|
925
|
-
if (!res.ok) throw new Error(data.error ?? "The application could not be resumed.");
|
|
926
|
-
if (data.state === "done" && data.booked) return { step: "done", applicationId: data.applicationId, booked: data.booked };
|
|
927
|
-
if (data.state === "paymentPending") return { step: "paymentPending", applicationId: data.applicationId };
|
|
928
|
-
if (data.state === "booking") return { step: "booking", applicationId: data.applicationId };
|
|
929
|
-
if (data.state === "accepted") return { step: "accepted", applicationId: data.applicationId };
|
|
930
|
-
if (data.state === "gift") return { step: "gift", applicationId: data.applicationId, ...data.claimId ? { claimId: data.claimId } : {} };
|
|
931
|
-
return { step: "payment", applicationId: data.applicationId };
|
|
932
|
-
}
|
|
933
|
-
|
|
934
979
|
// src/ui/join.tsx
|
|
935
|
-
import { Fragment as Fragment6, jsx as
|
|
980
|
+
import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs14 } from "preact/jsx-runtime";
|
|
936
981
|
function JoinIsland(props) {
|
|
937
982
|
const inheritedCopy = useChapterCopy();
|
|
938
983
|
const {
|
|
@@ -1025,22 +1070,11 @@ function JoinIsland(props) {
|
|
|
1025
1070
|
});
|
|
1026
1071
|
const data = await res.json();
|
|
1027
1072
|
if (!res.ok || !data.id) throw new Error(data.error ?? copy.form.submitFailed);
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
setState({ step: "paymentPending", applicationId: data.id });
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
if (data.state === "payment" || data.state === "booking") {
|
|
1037
|
-
setState({ step: data.state, applicationId: data.id });
|
|
1038
|
-
return;
|
|
1039
|
-
}
|
|
1040
|
-
setState({
|
|
1041
|
-
step: tierNeedsPayment(selectedTier, config.paymentsReady) ? "payment" : "booking",
|
|
1042
|
-
applicationId: data.id
|
|
1043
|
-
});
|
|
1073
|
+
setState(joinStateFromApplicationResponse(
|
|
1074
|
+
data,
|
|
1075
|
+
tierNeedsPayment(selectedTier, config.paymentsReady),
|
|
1076
|
+
Boolean(giftOfferId)
|
|
1077
|
+
));
|
|
1044
1078
|
} catch (err) {
|
|
1045
1079
|
setError(err instanceof Error ? err.message : copy.form.unexpectedFailure);
|
|
1046
1080
|
} finally {
|
|
@@ -1052,35 +1086,35 @@ function JoinIsland(props) {
|
|
|
1052
1086
|
..."applicationId" in state ? { applicationId: state.applicationId } : {}
|
|
1053
1087
|
});
|
|
1054
1088
|
if (state.step === "done") {
|
|
1055
|
-
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1089
|
+
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs14("div", { className: "join-done card", children: [
|
|
1090
|
+
/* @__PURE__ */ jsx14("div", { className: "card-label", children: copy.done.label }),
|
|
1091
|
+
/* @__PURE__ */ jsx14("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
|
|
1092
|
+
/* @__PURE__ */ jsx14("p", { className: "meeting-note", children: copy.done.calendarInvite }),
|
|
1093
|
+
/* @__PURE__ */ jsx14("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
1060
1094
|
] });
|
|
1061
|
-
return /* @__PURE__ */
|
|
1095
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1062
1096
|
header,
|
|
1063
1097
|
body
|
|
1064
1098
|
] });
|
|
1065
1099
|
}
|
|
1066
1100
|
if (state.step === "accepted") {
|
|
1067
|
-
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
1068
|
-
return /* @__PURE__ */
|
|
1101
|
+
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx14(JoinAccepted, { copy, membersHref });
|
|
1102
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1069
1103
|
header,
|
|
1070
1104
|
body
|
|
1071
1105
|
] });
|
|
1072
1106
|
}
|
|
1073
1107
|
if (state.step === "gift") {
|
|
1074
|
-
const body = renderGift?.(state) ?? /* @__PURE__ */
|
|
1075
|
-
return /* @__PURE__ */
|
|
1108
|
+
const body = renderGift?.(state) ?? /* @__PURE__ */ jsx14(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
|
|
1109
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1076
1110
|
header,
|
|
1077
1111
|
body
|
|
1078
1112
|
] });
|
|
1079
1113
|
}
|
|
1080
1114
|
if (state.step === "booking") {
|
|
1081
|
-
return /* @__PURE__ */
|
|
1115
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1082
1116
|
header,
|
|
1083
|
-
/* @__PURE__ */
|
|
1117
|
+
/* @__PURE__ */ jsx14(
|
|
1084
1118
|
JoinBooking,
|
|
1085
1119
|
{
|
|
1086
1120
|
applicationId: state.applicationId,
|
|
@@ -1094,9 +1128,20 @@ function JoinIsland(props) {
|
|
|
1094
1128
|
] });
|
|
1095
1129
|
}
|
|
1096
1130
|
if (state.step === "payment") {
|
|
1097
|
-
return /* @__PURE__ */
|
|
1131
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1098
1132
|
header,
|
|
1099
|
-
/* @__PURE__ */
|
|
1133
|
+
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx14(
|
|
1134
|
+
JoinGiftClaim,
|
|
1135
|
+
{
|
|
1136
|
+
api: props.giftClaimApi,
|
|
1137
|
+
applicationId: state.applicationId,
|
|
1138
|
+
copy: copy.gift,
|
|
1139
|
+
loadResume: props.loadResume,
|
|
1140
|
+
onState: setState,
|
|
1141
|
+
onError: () => setError(copy.form.unexpectedFailure)
|
|
1142
|
+
}
|
|
1143
|
+
) : null,
|
|
1144
|
+
/* @__PURE__ */ jsx14(
|
|
1100
1145
|
PaymentStep,
|
|
1101
1146
|
{
|
|
1102
1147
|
applicationId: state.applicationId,
|
|
@@ -1124,25 +1169,25 @@ function JoinIsland(props) {
|
|
|
1124
1169
|
] });
|
|
1125
1170
|
}
|
|
1126
1171
|
if (state.step === "paymentPending") {
|
|
1127
|
-
return /* @__PURE__ */
|
|
1172
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1128
1173
|
header,
|
|
1129
|
-
/* @__PURE__ */
|
|
1174
|
+
/* @__PURE__ */ jsx14("p", { className: "pay-status", role: "status", children: copy.payment.pending })
|
|
1130
1175
|
] });
|
|
1131
1176
|
}
|
|
1132
1177
|
const submitDisabled = submitting || props.submitDisabled === true;
|
|
1133
1178
|
const tierChooser = tiers.length > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null;
|
|
1134
|
-
return /* @__PURE__ */
|
|
1179
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
1135
1180
|
header,
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
(config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
1138
|
-
/* @__PURE__ */
|
|
1139
|
-
/* @__PURE__ */
|
|
1140
|
-
/* @__PURE__ */
|
|
1181
|
+
/* @__PURE__ */ jsxs14("form", { className: "join-form", onSubmit: (e) => void submit(e), children: [
|
|
1182
|
+
(config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs14("fieldset", { children: [
|
|
1183
|
+
/* @__PURE__ */ jsx14("legend", { children: copy.gift.optionsLabel }),
|
|
1184
|
+
/* @__PURE__ */ jsx14("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => setGiftOfferId(null), children: copy.gift.chooseSelf }),
|
|
1185
|
+
/* @__PURE__ */ jsx14(GiftOfferCards, { offers: config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: setGiftOfferId })
|
|
1141
1186
|
] }) : null,
|
|
1142
1187
|
tierChooser,
|
|
1143
1188
|
children,
|
|
1144
|
-
error ? /* @__PURE__ */
|
|
1145
|
-
renderSubmit?.({ submitting, disabled: submitDisabled }) ?? /* @__PURE__ */
|
|
1189
|
+
error ? /* @__PURE__ */ jsx14("p", { className: "join-error", children: error }) : null,
|
|
1190
|
+
renderSubmit?.({ submitting, disabled: submitDisabled }) ?? /* @__PURE__ */ jsx14("button", { className: "submit-btn", type: "submit", disabled: submitDisabled, children: submitting ? copy.form.submitting : copy.form.submit })
|
|
1146
1191
|
] })
|
|
1147
1192
|
] });
|
|
1148
1193
|
}
|
|
@@ -1319,7 +1364,7 @@ function membershipPageDocument(input, options = {}) {
|
|
|
1319
1364
|
}
|
|
1320
1365
|
|
|
1321
1366
|
// src/ui/membership-cards.tsx
|
|
1322
|
-
import { jsx as
|
|
1367
|
+
import { jsx as jsx15, jsxs as jsxs15 } from "preact/jsx-runtime";
|
|
1323
1368
|
var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
|
|
1324
1369
|
"--ui-membership-grid-gap": "1.4rem",
|
|
1325
1370
|
"--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
|
|
@@ -1388,67 +1433,67 @@ function membershipApplicationHref(applicationPath, tierId) {
|
|
|
1388
1433
|
}
|
|
1389
1434
|
function TierAction(props) {
|
|
1390
1435
|
if (props.mode === "select") {
|
|
1391
|
-
return /* @__PURE__ */
|
|
1436
|
+
return /* @__PURE__ */ jsxs15("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
|
|
1392
1437
|
props.label,
|
|
1393
|
-
/* @__PURE__ */
|
|
1438
|
+
/* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\u2192" })
|
|
1394
1439
|
] });
|
|
1395
1440
|
}
|
|
1396
1441
|
if (props.mode === "preview") {
|
|
1397
|
-
return /* @__PURE__ */
|
|
1442
|
+
return /* @__PURE__ */ jsxs15("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
|
|
1398
1443
|
props.label,
|
|
1399
|
-
/* @__PURE__ */
|
|
1444
|
+
/* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\u2192" })
|
|
1400
1445
|
] });
|
|
1401
1446
|
}
|
|
1402
|
-
return /* @__PURE__ */
|
|
1447
|
+
return /* @__PURE__ */ jsxs15("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
|
|
1403
1448
|
props.label,
|
|
1404
|
-
/* @__PURE__ */
|
|
1449
|
+
/* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\u2192" })
|
|
1405
1450
|
] });
|
|
1406
1451
|
}
|
|
1407
1452
|
function TierCard(props) {
|
|
1408
1453
|
const { tier, presentation } = props;
|
|
1409
1454
|
const summary = presentation.summaryMarkdown ?? tier.blurb;
|
|
1410
1455
|
const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
|
|
1411
|
-
return /* @__PURE__ */
|
|
1412
|
-
presentation.badge ? /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1415
|
-
presentation.capacity ? /* @__PURE__ */
|
|
1416
|
-
/* @__PURE__ */
|
|
1417
|
-
/* @__PURE__ */
|
|
1456
|
+
return /* @__PURE__ */ jsxs15("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
|
|
1457
|
+
presentation.badge ? /* @__PURE__ */ jsx15("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
|
|
1458
|
+
/* @__PURE__ */ jsx15("h3", { className: "chapter-membership-name", children: tier.name }),
|
|
1459
|
+
/* @__PURE__ */ jsxs15("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
|
|
1460
|
+
presentation.capacity ? /* @__PURE__ */ jsxs15("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
|
|
1461
|
+
/* @__PURE__ */ jsx15("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
|
|
1462
|
+
/* @__PURE__ */ jsx15("small", { children: presentation.capacity.label ?? "available" })
|
|
1418
1463
|
] }) : null,
|
|
1419
|
-
/* @__PURE__ */
|
|
1420
|
-
presentation.priceEyebrow ? /* @__PURE__ */
|
|
1421
|
-
/* @__PURE__ */
|
|
1422
|
-
presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1424
|
-
!tier.free && presentation.billingLabel ? /* @__PURE__ */
|
|
1464
|
+
/* @__PURE__ */ jsxs15("div", { className: "chapter-membership-price-stack", children: [
|
|
1465
|
+
presentation.priceEyebrow ? /* @__PURE__ */ jsx15("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : null,
|
|
1466
|
+
/* @__PURE__ */ jsxs15("div", { className: "chapter-membership-price-row", children: [
|
|
1467
|
+
presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx15("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
|
|
1468
|
+
/* @__PURE__ */ jsx15("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.priceCents) }),
|
|
1469
|
+
!tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx15("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
|
|
1425
1470
|
] })
|
|
1426
1471
|
] })
|
|
1427
1472
|
] }),
|
|
1428
|
-
presentation.priceNoteMarkdown ? /* @__PURE__ */
|
|
1429
|
-
summary ? /* @__PURE__ */
|
|
1430
|
-
presentation.benefits?.length ? /* @__PURE__ */
|
|
1431
|
-
/* @__PURE__ */
|
|
1432
|
-
/* @__PURE__ */
|
|
1473
|
+
presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx15(Markdown2, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
|
|
1474
|
+
summary ? /* @__PURE__ */ jsx15(Markdown2, { className: "chapter-membership-summary", source: summary }) : null,
|
|
1475
|
+
presentation.benefits?.length ? /* @__PURE__ */ jsx15("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs15("li", { children: [
|
|
1476
|
+
/* @__PURE__ */ jsx15("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
|
|
1477
|
+
/* @__PURE__ */ jsx15(Markdown2, { className: "chapter-membership-benefit", source: benefit })
|
|
1433
1478
|
] }, `${tier.id}-benefit-${index}`)) }) : null,
|
|
1434
|
-
presentation.callout ? /* @__PURE__ */
|
|
1435
|
-
presentation.callout.label ? /* @__PURE__ */
|
|
1436
|
-
/* @__PURE__ */
|
|
1479
|
+
presentation.callout ? /* @__PURE__ */ jsxs15("aside", { className: "chapter-membership-callout", children: [
|
|
1480
|
+
presentation.callout.label ? /* @__PURE__ */ jsx15("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
|
|
1481
|
+
/* @__PURE__ */ jsx15(Markdown2, { source: presentation.callout.bodyMarkdown })
|
|
1437
1482
|
] }) : null,
|
|
1438
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsx15(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
|
|
1439
1484
|
] });
|
|
1440
1485
|
}
|
|
1441
1486
|
function MembershipCards(props) {
|
|
1442
1487
|
const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
|
|
1443
1488
|
const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
|
|
1444
1489
|
const mode = props.mode ?? "link";
|
|
1445
|
-
return /* @__PURE__ */
|
|
1446
|
-
/* @__PURE__ */
|
|
1447
|
-
/* @__PURE__ */
|
|
1490
|
+
return /* @__PURE__ */ jsxs15("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
|
|
1491
|
+
/* @__PURE__ */ jsx15("style", { children: MEMBERSHIP_CARDS_CSS }),
|
|
1492
|
+
/* @__PURE__ */ jsx15("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
|
|
1448
1493
|
const tier = byId.get(presentation.tierId);
|
|
1449
|
-
return /* @__PURE__ */
|
|
1494
|
+
return /* @__PURE__ */ jsx15(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
|
|
1450
1495
|
}) }),
|
|
1451
|
-
document2.footnoteMarkdown ? /* @__PURE__ */
|
|
1496
|
+
document2.footnoteMarkdown ? /* @__PURE__ */ jsx15(Markdown2, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
|
|
1452
1497
|
] });
|
|
1453
1498
|
}
|
|
1454
1499
|
|
|
@@ -1464,18 +1509,19 @@ export {
|
|
|
1464
1509
|
SlotPicker,
|
|
1465
1510
|
Rescheduler,
|
|
1466
1511
|
GiftOfferCards,
|
|
1467
|
-
GiftCodeRedeemer,
|
|
1468
1512
|
PaymentStep,
|
|
1513
|
+
GiftPurchases,
|
|
1469
1514
|
MemberGifts,
|
|
1470
1515
|
MemberContentArea,
|
|
1471
1516
|
MembersArea,
|
|
1517
|
+
GiftCodeRedeemer,
|
|
1518
|
+
loadJoinResume,
|
|
1472
1519
|
useTierSelection,
|
|
1473
1520
|
TierPlaceholder,
|
|
1474
1521
|
tierNeedsPayment,
|
|
1475
|
-
loadJoinResume,
|
|
1476
1522
|
JoinIsland,
|
|
1477
1523
|
MEMBERSHIP_CARD_TOKEN_DEFAULTS,
|
|
1478
1524
|
membershipApplicationHref,
|
|
1479
1525
|
MembershipCards
|
|
1480
1526
|
};
|
|
1481
|
-
//# sourceMappingURL=chunk-
|
|
1527
|
+
//# sourceMappingURL=chunk-S7CND3R5.js.map
|