@odla-ai/chapter 0.62.0 → 0.63.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 +61 -0
- package/dist/{chunk-7CVP6VSO.js → chunk-OXYMVK2O.js} +145 -1
- package/dist/chunk-OXYMVK2O.js.map +1 -0
- package/dist/{chunk-ZIYK3OV2.js → chunk-QPFJBHHK.js} +691 -332
- package/dist/chunk-QPFJBHHK.js.map +1 -0
- package/dist/{chunk-MUUBATZJ.js → chunk-S6VPJFHL.js} +474 -200
- package/dist/chunk-S6VPJFHL.js.map +1 -0
- package/dist/{copy-context-BJUkVUjE.d.ts → copy-context-BNKK7ZDm.d.ts} +6 -0
- package/dist/index.cjs +419 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -6
- package/dist/index.d.ts +196 -6
- package/dist/index.js +419 -73
- 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 +53 -11
- package/dist/ui/member/index.d.ts +175 -3
- package/dist/ui/member/index.js +52 -10
- package/dist/worker/index.cjs +3722 -2903
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +6 -0
- package/dist/worker/index.d.ts +6 -0
- package/dist/worker/index.js +3729 -2910
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7CVP6VSO.js.map +0 -1
- package/dist/chunk-MUUBATZJ.js.map +0 -1
- package/dist/chunk-ZIYK3OV2.js.map +0 -1
|
@@ -1,69 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_JOIN_COPY,
|
|
3
|
+
dayLabel,
|
|
4
|
+
fmtDate,
|
|
5
|
+
fmtMoney,
|
|
3
6
|
formatChapterCopy,
|
|
7
|
+
fullLabel,
|
|
8
|
+
groupSlotsByDay,
|
|
9
|
+
timeLabel,
|
|
4
10
|
useChapterCopy
|
|
5
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-OXYMVK2O.js";
|
|
6
12
|
import {
|
|
7
13
|
collectFormFields
|
|
8
14
|
} from "./chunk-IVXVECKR.js";
|
|
9
15
|
|
|
10
16
|
// src/ui/slot-picker.tsx
|
|
11
17
|
import { useMemo, useState } from "preact/hooks";
|
|
12
|
-
|
|
13
|
-
// src/ui/datetime.ts
|
|
14
|
-
function tzShort(tz) {
|
|
15
|
-
try {
|
|
16
|
-
const parts = new Intl.DateTimeFormat(void 0, { timeZone: tz, timeZoneName: "short" }).formatToParts(
|
|
17
|
-
/* @__PURE__ */ new Date()
|
|
18
|
-
);
|
|
19
|
-
return parts.find((p) => p.type === "timeZoneName")?.value ?? tz;
|
|
20
|
-
} catch {
|
|
21
|
-
return tz;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function dayKey(ms, tz) {
|
|
25
|
-
return new Date(ms).toLocaleDateString("en-CA", { timeZone: tz });
|
|
26
|
-
}
|
|
27
|
-
function dayLabel(ms, tz) {
|
|
28
|
-
return new Date(ms).toLocaleDateString(void 0, { timeZone: tz, weekday: "short", month: "short", day: "numeric" });
|
|
29
|
-
}
|
|
30
|
-
function timeLabel(ms, tz) {
|
|
31
|
-
return new Date(ms).toLocaleTimeString(void 0, {
|
|
32
|
-
timeZone: tz,
|
|
33
|
-
hour: "numeric",
|
|
34
|
-
minute: "2-digit",
|
|
35
|
-
timeZoneName: "short"
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
function fullLabel(ms, tz) {
|
|
39
|
-
return new Date(ms).toLocaleString(void 0, {
|
|
40
|
-
timeZone: tz,
|
|
41
|
-
weekday: "long",
|
|
42
|
-
month: "long",
|
|
43
|
-
day: "numeric",
|
|
44
|
-
hour: "numeric",
|
|
45
|
-
minute: "2-digit",
|
|
46
|
-
timeZoneName: "short"
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function fmtMoney(cents) {
|
|
50
|
-
return "$" + Math.round(cents / 100).toLocaleString();
|
|
51
|
-
}
|
|
52
|
-
function fmtDate(ms) {
|
|
53
|
-
return new Date(ms).toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
|
|
54
|
-
}
|
|
55
|
-
function groupSlotsByDay(slots, tz) {
|
|
56
|
-
const byDay = /* @__PURE__ */ new Map();
|
|
57
|
-
for (const s of slots) {
|
|
58
|
-
const k = dayKey(s.startAt, tz);
|
|
59
|
-
const bucket = byDay.get(k);
|
|
60
|
-
if (bucket) bucket.push(s);
|
|
61
|
-
else byDay.set(k, [s]);
|
|
62
|
-
}
|
|
63
|
-
return byDay;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/ui/slot-picker.tsx
|
|
67
18
|
import { Fragment, jsx, jsxs } from "preact/jsx-runtime";
|
|
68
19
|
var DEFAULT_CLASSES = {
|
|
69
20
|
days: "slot-days",
|
|
@@ -867,7 +818,7 @@ function MemberRestart(props) {
|
|
|
867
818
|
}
|
|
868
819
|
|
|
869
820
|
// src/ui/members.tsx
|
|
870
|
-
import { useEffect as
|
|
821
|
+
import { useEffect as useEffect11, useState as useState18 } from "preact/hooks";
|
|
871
822
|
|
|
872
823
|
// src/ui/reschedule.tsx
|
|
873
824
|
import { useState as useState8 } from "preact/hooks";
|
|
@@ -1365,14 +1316,14 @@ function MemberContentArea(props) {
|
|
|
1365
1316
|
var placeholderBadge = (page) => page.placeholder?.badge ?? (page.placeholder?.availableYear ? `Coming in ${page.placeholder.availableYear}` : "Coming soon");
|
|
1366
1317
|
function MemberPlaceholderBody({ page }) {
|
|
1367
1318
|
return /* @__PURE__ */ jsxs15("div", { className: "chapter-member-placeholder", "data-placeholder": true, children: [
|
|
1368
|
-
/* @__PURE__ */ jsx16("
|
|
1319
|
+
/* @__PURE__ */ jsx16("div", { className: "card-label", children: placeholderBadge(page) }),
|
|
1369
1320
|
page.bodyMarkdown ? /* @__PURE__ */ jsx16(Markdown, { source: page.bodyMarkdown }) : null,
|
|
1370
|
-
page.placeholder?.actionLabel ? /* @__PURE__ */ jsx16("button", { className: "btn", type: "button", disabled: true, children: page.placeholder.actionLabel }) : null
|
|
1321
|
+
page.placeholder?.actionLabel ? /* @__PURE__ */ jsx16("button", { className: "btn secondary", type: "button", disabled: true, children: page.placeholder.actionLabel }) : null
|
|
1371
1322
|
] });
|
|
1372
1323
|
}
|
|
1373
1324
|
|
|
1374
1325
|
// src/ui/member-portal.tsx
|
|
1375
|
-
import { useEffect as
|
|
1326
|
+
import { useEffect as useEffect10, useMemo as useMemo3, useState as useState17 } from "preact/hooks";
|
|
1376
1327
|
|
|
1377
1328
|
// src/ui/member-portal-nav.tsx
|
|
1378
1329
|
import { ThemeScope } from "@odla-ai/ui/components";
|
|
@@ -1421,12 +1372,12 @@ function PortalIcon({ name, size = 18, label }) {
|
|
|
1421
1372
|
// src/ui/member-portal-routing.ts
|
|
1422
1373
|
var PROFILE_SEGMENT = "profile";
|
|
1423
1374
|
var trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
|
|
1424
|
-
function routeFromLocation(
|
|
1375
|
+
function routeFromLocation(location2, routing) {
|
|
1425
1376
|
let segment = "";
|
|
1426
|
-
if (routing.mode === "hash") segment = trimSlashes(decodeURIComponent(
|
|
1377
|
+
if (routing.mode === "hash") segment = trimSlashes(decodeURIComponent(location2.hash.replace(/^#/, "")));
|
|
1427
1378
|
else {
|
|
1428
1379
|
const base = `/${trimSlashes(routing.basePath)}`;
|
|
1429
|
-
const path =
|
|
1380
|
+
const path = location2.pathname;
|
|
1430
1381
|
if (path === base || path.startsWith(`${base}/`)) segment = trimSlashes(decodeURIComponent(path.slice(base.length)));
|
|
1431
1382
|
}
|
|
1432
1383
|
if (!segment) return { kind: "home" };
|
|
@@ -1525,7 +1476,8 @@ import { Markdown as Markdown2 } from "@odla-ai/ui/components";
|
|
|
1525
1476
|
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
1526
1477
|
var upsellOf = (page, ctx) => {
|
|
1527
1478
|
const tierName = page.upsell?.tierName;
|
|
1528
|
-
const
|
|
1479
|
+
const tierId = page.upsell?.tierId ?? (page.audience.kind === "tiers" ? page.audience.tierIds[0] : void 0);
|
|
1480
|
+
const href = tierId && ctx.upsellHref ? ctx.upsellHref(tierId, page) : void 0;
|
|
1529
1481
|
return { tierName, href, cta: page.upsell?.ctaLabel ?? ctx.copy.pages.upgrade };
|
|
1530
1482
|
};
|
|
1531
1483
|
function LockedPill({ page, ctx }) {
|
|
@@ -1807,6 +1759,8 @@ var MEMBER_PORTAL_CSS = `
|
|
|
1807
1759
|
.chapter-portal-account button.chapter-portal-link,.chapter-portal-account a{display:inline;padding:0;border:0;background:none;color:var(--ui-text,#fff);font:inherit;text-decoration:underline;cursor:pointer}
|
|
1808
1760
|
.chapter-portal-avatar{display:inline-grid;place-items:center;flex:none;width:28px;height:28px;border-radius:50%;overflow:hidden;background:var(--ui-accent-soft,rgba(124,184,63,.2));color:var(--ui-text,inherit);font-size:.72rem;font-weight:700;letter-spacing:.04em}
|
|
1809
1761
|
.chapter-portal-avatar img{width:100%;height:100%;object-fit:cover}
|
|
1762
|
+
.chapter-portal-avatar.chapter-portal-profile-photo{width:96px;height:96px;font-size:1.6rem}
|
|
1763
|
+
.chapter-portal-locked-wrap{position:relative}
|
|
1810
1764
|
.chapter-portal-main{min-width:0;padding:clamp(1rem,3vw,2.5rem);display:flex;flex-direction:column;gap:1.5rem}
|
|
1811
1765
|
.chapter-portal-top{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
|
|
1812
1766
|
.chapter-portal-top h1{margin:0;font-family:var(--ui-font-display,inherit);font-weight:400;font-size:clamp(1.8rem,4vw,2.4rem);line-height:1.1}
|
|
@@ -1830,6 +1784,25 @@ var MEMBER_PORTAL_CSS = `
|
|
|
1830
1784
|
.chapter-portal-btn:disabled{opacity:.5;cursor:not-allowed}
|
|
1831
1785
|
.chapter-portal-btns{display:flex;flex-wrap:wrap;gap:.6rem}
|
|
1832
1786
|
.chapter-portal :where(button,a,input,textarea,select):focus-visible{outline:3px solid var(--ui-focus,var(--ui-accent,#7cb83f));outline-offset:2px}
|
|
1787
|
+
.chapter-portal-modal-back{position:fixed;inset:0;z-index:50;display:grid;place-items:center;padding:1rem;background:color-mix(in srgb,var(--ui-text,#2f3e34) 45%,transparent)}
|
|
1788
|
+
.chapter-portal-modal{position:relative;width:min(100%,46rem);max-height:90vh;overflow:auto}
|
|
1789
|
+
.chapter-portal-modal-x{position:absolute;top:.75rem;right:.75rem;width:40px;height:40px;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}
|
|
1790
|
+
.chapter-portal-link-box{display:flex;align-items:center;justify-content:space-between;gap:.75rem;flex-wrap:wrap;margin:.75rem 0;padding:.5rem .5rem .5rem 1rem;border:1px solid var(--ui-border,#e2dccf);border-radius:999px;background:var(--ui-bg,#f4efe6)}
|
|
1791
|
+
.chapter-portal-link-box code{overflow-wrap:anywhere;font-size:.9rem}
|
|
1792
|
+
.chapter-portal-tally{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.75rem}
|
|
1793
|
+
.chapter-portal-tally[data-tiles="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
1794
|
+
.chapter-portal-tally>div{display:flex;flex-direction:column;padding:.9rem;border:1px solid var(--ui-border,#e2dccf);border-radius:var(--ui-radius-sm,10px)}
|
|
1795
|
+
.chapter-portal-tally b{font-family:var(--ui-font-numeral,var(--ui-font-display,inherit));font-size:1.8rem;font-weight:400}
|
|
1796
|
+
.chapter-portal-tally span{font-size:.8rem;color:var(--ui-text-muted,#7e8e84)}
|
|
1797
|
+
.chapter-portal-fallback{margin-top:1rem;padding:1rem;border:1px dashed var(--ui-border-strong,#aeb9b5);border-radius:var(--ui-radius-sm,10px)}
|
|
1798
|
+
.chapter-portal-material{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;padding:.35rem 0;list-style:none}
|
|
1799
|
+
.chapter-portal-material small{color:var(--ui-text-muted,#7e8e84)}
|
|
1800
|
+
.chapter-portal-material a{margin-left:auto}
|
|
1801
|
+
.chapter-portal details{border-top:1px solid var(--ui-border,#e2dccf);padding:.75rem 0}
|
|
1802
|
+
.chapter-portal summary{cursor:pointer}
|
|
1803
|
+
.chapter-portal dl{display:grid;grid-template-columns:auto 1fr;gap:.3rem 1rem;margin:.75rem 0}
|
|
1804
|
+
.chapter-portal dt{color:var(--ui-text-muted,#7e8e84)}
|
|
1805
|
+
.chapter-portal dd{margin:0}
|
|
1833
1806
|
.chapter-portal-mobile{display:none}
|
|
1834
1807
|
@media (max-width:860px){
|
|
1835
1808
|
.chapter-portal{grid-template-columns:minmax(0,1fr)}
|
|
@@ -1839,23 +1812,388 @@ var MEMBER_PORTAL_CSS = `
|
|
|
1839
1812
|
.chapter-portal-burger{display:inline-grid;place-items:center;width:44px;height:44px;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer}
|
|
1840
1813
|
.chapter-portal-mobile-menu{display:flex;flex-direction:column;gap:1rem;padding:0 1rem 1.25rem}
|
|
1841
1814
|
.chapter-portal-mobile .chapter-portal-brand{font-size:1.15rem;padding:0}
|
|
1815
|
+
.chapter-portal-modal-back{place-items:end stretch;padding:0}
|
|
1816
|
+
.chapter-portal-modal{width:100%;border-radius:var(--ui-radius-lg,14px) var(--ui-radius-lg,14px) 0 0}
|
|
1842
1817
|
}
|
|
1843
1818
|
`;
|
|
1844
1819
|
|
|
1820
|
+
// src/ui/member-course-page.tsx
|
|
1821
|
+
import { useEffect as useEffect7, useState as useState14 } from "preact/hooks";
|
|
1822
|
+
import { Markdown as Markdown3 } from "@odla-ai/ui/components";
|
|
1823
|
+
import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs19 } from "preact/jsx-runtime";
|
|
1824
|
+
function useCourse(ctx, courseId) {
|
|
1825
|
+
const [view, setView] = useState14(null);
|
|
1826
|
+
const [error, setError] = useState14(null);
|
|
1827
|
+
const [busy, setBusy] = useState14(false);
|
|
1828
|
+
useEffect7(() => {
|
|
1829
|
+
if (!courseId) return;
|
|
1830
|
+
let live = true;
|
|
1831
|
+
void ctx.api(`/api/member/courses/${encodeURIComponent(courseId)}`).then((v) => live && setView(v)).catch(() => live && setError(ctx.copy.course.failed));
|
|
1832
|
+
return () => {
|
|
1833
|
+
live = false;
|
|
1834
|
+
};
|
|
1835
|
+
}, [courseId]);
|
|
1836
|
+
const act = async (action) => {
|
|
1837
|
+
setBusy(true);
|
|
1838
|
+
setError(null);
|
|
1839
|
+
try {
|
|
1840
|
+
setView(await ctx.api(`/api/member/courses/${encodeURIComponent(courseId)}/${action}`, { method: "POST" }));
|
|
1841
|
+
} catch {
|
|
1842
|
+
setError(ctx.copy.course.failed);
|
|
1843
|
+
} finally {
|
|
1844
|
+
setBusy(false);
|
|
1845
|
+
}
|
|
1846
|
+
};
|
|
1847
|
+
return { view, error, busy, act };
|
|
1848
|
+
}
|
|
1849
|
+
function seatLine(view, copy) {
|
|
1850
|
+
if (view.enrollment?.status === "enrolled") return copy.invitesOnWay;
|
|
1851
|
+
if (view.enrollment?.status === "waitlisted") return formatChapterCopy(copy.onWaitlist, { position: String(view.enrollment.waitlistPosition ?? "") });
|
|
1852
|
+
if (view.course.status === "closed") return copy.closed;
|
|
1853
|
+
return formatChapterCopy(copy.seatsOpen, { left: String(view.course.seatsLeft), capacity: String(view.course.capacity) });
|
|
1854
|
+
}
|
|
1855
|
+
function SeatActions({ ctx, course, details }) {
|
|
1856
|
+
const copy = ctx.copy.course;
|
|
1857
|
+
const view = course.view;
|
|
1858
|
+
const status = view.enrollment?.status;
|
|
1859
|
+
const confirmThen = (action) => {
|
|
1860
|
+
if (window.confirm(copy.confirmGiveUp)) void course.act(action);
|
|
1861
|
+
};
|
|
1862
|
+
return /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-btns", children: [
|
|
1863
|
+
status === "enrolled" ? /* @__PURE__ */ jsx21("span", { className: "chapter-portal-pill", children: copy.youreIn }) : null,
|
|
1864
|
+
status === "enrolled" && view.meetUrl ? /* @__PURE__ */ jsx21("a", { className: "chapter-portal-btn", href: view.meetUrl, target: "_blank", rel: "noopener", children: copy.openMeet }) : null,
|
|
1865
|
+
status === "enrolled" ? /* @__PURE__ */ jsx21("button", { type: "button", className: "chapter-portal-btn", "data-variant": "ghost", disabled: course.busy, onClick: () => confirmThen("withdraw"), children: copy.giveUp }) : null,
|
|
1866
|
+
status === "waitlisted" ? /* @__PURE__ */ jsx21("button", { type: "button", className: "chapter-portal-btn", "data-variant": "ghost", disabled: course.busy, onClick: () => void course.act("withdraw"), children: copy.leaveWaitlist }) : null,
|
|
1867
|
+
!status && view.course.status !== "closed" ? /* @__PURE__ */ jsx21("button", { type: "button", className: "chapter-portal-btn", disabled: course.busy, onClick: () => void course.act("enroll"), children: view.course.status === "full" ? copy.joinWaitlist : copy.reserve }) : null,
|
|
1868
|
+
details ? /* @__PURE__ */ jsx21("button", { type: "button", className: "chapter-portal-btn", "data-variant": "ghost", onClick: details, children: status === "enrolled" ? copy.courseDetails : copy.seeDetails }) : null
|
|
1869
|
+
] });
|
|
1870
|
+
}
|
|
1871
|
+
var MaterialItem = ({ item, kind, ctx, enrolled }) => /* @__PURE__ */ jsxs19("li", { className: "chapter-portal-material", children: [
|
|
1872
|
+
kind ? /* @__PURE__ */ jsx21("span", { className: "chapter-portal-pill", children: ctx.copy.course[kind] }) : null,
|
|
1873
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
1874
|
+
item.label,
|
|
1875
|
+
item.meta ? /* @__PURE__ */ jsxs19("small", { children: [
|
|
1876
|
+
" \xB7 ",
|
|
1877
|
+
item.meta
|
|
1878
|
+
] }) : null
|
|
1879
|
+
] }),
|
|
1880
|
+
enrolled && item.url ? /* @__PURE__ */ jsx21("a", { href: item.url, target: "_blank", rel: "noopener", children: ctx.copy.course.open }) : null
|
|
1881
|
+
] });
|
|
1882
|
+
function CoursePage({ page, ctx }) {
|
|
1883
|
+
const course = useCourse(ctx, page.feature?.ref);
|
|
1884
|
+
const copy = ctx.copy.course;
|
|
1885
|
+
if (!course.view) return /* @__PURE__ */ jsx21("p", { children: course.error ?? ctx.copy.shell.loading });
|
|
1886
|
+
const { course: c } = course.view;
|
|
1887
|
+
const enrolled = course.view.enrollment?.status === "enrolled";
|
|
1888
|
+
return /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-stack", "data-course-page": true, children: [
|
|
1889
|
+
/* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card ui-invert", style: { display: "grid", gap: "1.25rem", gridTemplateColumns: "repeat(auto-fit,minmax(min(100%,18rem),1fr))" }, children: [
|
|
1890
|
+
/* @__PURE__ */ jsxs19("div", { children: [
|
|
1891
|
+
/* @__PURE__ */ jsx21("h1", { style: { fontFamily: "var(--ui-font-display,inherit)", fontWeight: 400, margin: 0 }, children: c.title }),
|
|
1892
|
+
c.content.basedOn ? /* @__PURE__ */ jsx21("p", { style: { fontStyle: "italic" }, children: c.content.basedOn }) : null,
|
|
1893
|
+
c.content.short ? /* @__PURE__ */ jsx21("p", { children: c.content.short }) : null
|
|
1894
|
+
] }),
|
|
1895
|
+
/* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", "data-seat-box": true, children: [
|
|
1896
|
+
!course.view.enrollment ? /* @__PURE__ */ jsx21("div", { className: "chapter-portal-group-label", style: { padding: 0 }, children: copy.reserveYourSeat }) : null,
|
|
1897
|
+
/* @__PURE__ */ jsxs19("dl", { children: [
|
|
1898
|
+
c.content.when ? /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
1899
|
+
/* @__PURE__ */ jsx21("dt", { children: copy.when }),
|
|
1900
|
+
/* @__PURE__ */ jsx21("dd", { children: c.content.when })
|
|
1901
|
+
] }) : null,
|
|
1902
|
+
c.content.dates ?? c.content.start ? /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
1903
|
+
/* @__PURE__ */ jsx21("dt", { children: copy.dates }),
|
|
1904
|
+
/* @__PURE__ */ jsx21("dd", { children: c.content.dates ?? c.content.start })
|
|
1905
|
+
] }) : null,
|
|
1906
|
+
/* @__PURE__ */ jsx21("dt", { children: copy.where }),
|
|
1907
|
+
/* @__PURE__ */ jsx21("dd", { children: copy.googleMeet }),
|
|
1908
|
+
/* @__PURE__ */ jsx21("dt", { children: copy.seats }),
|
|
1909
|
+
/* @__PURE__ */ jsx21("dd", { children: seatLine(course.view, copy) })
|
|
1910
|
+
] }),
|
|
1911
|
+
/* @__PURE__ */ jsx21(SeatActions, { ctx, course }),
|
|
1912
|
+
!course.view.enrollment ? /* @__PURE__ */ jsx21("p", { style: { color: "var(--ui-text-muted)" }, children: copy.inviteEvery }) : null,
|
|
1913
|
+
course.error ? /* @__PURE__ */ jsx21("p", { role: "alert", children: course.error }) : null
|
|
1914
|
+
] })
|
|
1915
|
+
] }),
|
|
1916
|
+
c.guides.length ? /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", children: [
|
|
1917
|
+
/* @__PURE__ */ jsx21("h2", { children: copy.guidesTitle }),
|
|
1918
|
+
/* @__PURE__ */ jsx21("div", { className: "chapter-portal-tiles", children: c.guides.map((guide) => /* @__PURE__ */ jsxs19("div", { children: [
|
|
1919
|
+
guide.photoUrl ? /* @__PURE__ */ jsx21("img", { src: guide.photoUrl, alt: guide.name, style: { width: 72, height: 72, borderRadius: "50%", objectFit: "cover" } }) : null,
|
|
1920
|
+
/* @__PURE__ */ jsx21("h3", { children: guide.name }),
|
|
1921
|
+
guide.role ? /* @__PURE__ */ jsx21("div", { style: { color: "var(--ui-text-muted)" }, children: guide.role }) : null,
|
|
1922
|
+
guide.bio ? /* @__PURE__ */ jsx21("p", { children: guide.bio }) : null
|
|
1923
|
+
] }, guide.name)) })
|
|
1924
|
+
] }) : null,
|
|
1925
|
+
/* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", "data-sessions": true, children: [
|
|
1926
|
+
/* @__PURE__ */ jsx21("h2", { children: copy.sessionsTitle }),
|
|
1927
|
+
/* @__PURE__ */ jsx21("p", { style: { color: "var(--ui-text-muted)" }, children: enrolled ? copy.materialsOpen : copy.materialsLocked }),
|
|
1928
|
+
c.sessions.map((session, index) => /* @__PURE__ */ jsxs19("details", { open: enrolled && index === 0, children: [
|
|
1929
|
+
/* @__PURE__ */ jsxs19("summary", { children: [
|
|
1930
|
+
/* @__PURE__ */ jsx21("strong", { children: session.date }),
|
|
1931
|
+
" \xB7 ",
|
|
1932
|
+
session.topic,
|
|
1933
|
+
session.materials.length ? /* @__PURE__ */ jsxs19("small", { children: [
|
|
1934
|
+
" \xB7 ",
|
|
1935
|
+
formatChapterCopy(copy.items, { count: String(session.materials.length) })
|
|
1936
|
+
] }) : null
|
|
1937
|
+
] }),
|
|
1938
|
+
session.description ? /* @__PURE__ */ jsx21("p", { children: session.description }) : null,
|
|
1939
|
+
/* @__PURE__ */ jsx21("ul", { children: session.materials.map((item) => /* @__PURE__ */ jsx21(MaterialItem, { item, kind: item.kind, ctx, enrolled }, item.label)) })
|
|
1940
|
+
] }, session.startsAt))
|
|
1941
|
+
] }),
|
|
1942
|
+
/* @__PURE__ */ jsxs19("div", { className: "chapter-portal-tiles", children: [
|
|
1943
|
+
c.content.outcomes?.length ? /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", children: [
|
|
1944
|
+
/* @__PURE__ */ jsx21("h2", { children: copy.outcomesTitle }),
|
|
1945
|
+
/* @__PURE__ */ jsx21("ul", { children: c.content.outcomes.map((o) => /* @__PURE__ */ jsx21("li", { children: o }, o)) })
|
|
1946
|
+
] }) : null,
|
|
1947
|
+
c.toolkit.length || c.content.time ? /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", children: [
|
|
1948
|
+
/* @__PURE__ */ jsx21("h2", { children: copy.toolkitTitle }),
|
|
1949
|
+
/* @__PURE__ */ jsx21("ul", { children: c.toolkit.map((item) => /* @__PURE__ */ jsx21(MaterialItem, { item, ctx, enrolled }, item.label)) }),
|
|
1950
|
+
c.content.time ? /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
1951
|
+
/* @__PURE__ */ jsx21("h2", { children: copy.timeTitle }),
|
|
1952
|
+
/* @__PURE__ */ jsx21("p", { children: c.content.time })
|
|
1953
|
+
] }) : null
|
|
1954
|
+
] }) : null
|
|
1955
|
+
] }),
|
|
1956
|
+
c.content.partnerMarkdown ? /* @__PURE__ */ jsx21("div", { className: "chapter-portal-card", children: /* @__PURE__ */ jsx21(Markdown3, { source: c.content.partnerMarkdown }) }) : null
|
|
1957
|
+
] });
|
|
1958
|
+
}
|
|
1959
|
+
function CourseHomePanel({ page, ctx }) {
|
|
1960
|
+
const locked = page.access === "locked";
|
|
1961
|
+
const course = useCourse(ctx, locked ? void 0 : page.feature?.ref);
|
|
1962
|
+
const view = course.view;
|
|
1963
|
+
return /* @__PURE__ */ jsxs19("div", { className: "chapter-portal-card", "data-course-panel": true, children: [
|
|
1964
|
+
/* @__PURE__ */ jsx21("div", { className: "chapter-portal-group-label", style: { padding: 0 }, children: ctx.copy.course.eyebrow }),
|
|
1965
|
+
/* @__PURE__ */ jsx21("h2", { children: view?.course.title ?? page.title }),
|
|
1966
|
+
view?.course.content.basedOn ? /* @__PURE__ */ jsx21("p", { style: { fontStyle: "italic" }, children: view.course.content.basedOn }) : null,
|
|
1967
|
+
/* @__PURE__ */ jsx21("p", { children: view?.course.content.short ?? page.summary }),
|
|
1968
|
+
view ? /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
1969
|
+
/* @__PURE__ */ jsx21("p", { children: [view.course.content.when, view.course.content.start].filter(Boolean).join(" \xB7 ") }),
|
|
1970
|
+
/* @__PURE__ */ jsx21("p", { children: /* @__PURE__ */ jsx21("strong", { children: seatLine(view, ctx.copy.course) }) }),
|
|
1971
|
+
/* @__PURE__ */ jsx21(SeatActions, { ctx, course, details: () => ctx.navigate({ kind: "page", slug: page.slug }) })
|
|
1972
|
+
] }) : null
|
|
1973
|
+
] });
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
// src/ui/member-share-page.tsx
|
|
1977
|
+
import { useEffect as useEffect9, useState as useState16 } from "preact/hooks";
|
|
1978
|
+
|
|
1979
|
+
// src/ui/member-share.ts
|
|
1980
|
+
import { useEffect as useEffect8, useState as useState15 } from "preact/hooks";
|
|
1981
|
+
var articleFor = (word) => /^[aeiou]/i.test(word.trim()) ? "an" : "a";
|
|
1982
|
+
function shareVars(me, referrals) {
|
|
1983
|
+
const tierName = me.tier?.name ?? "";
|
|
1984
|
+
return {
|
|
1985
|
+
tierName,
|
|
1986
|
+
article: articleFor(tierName),
|
|
1987
|
+
inviteUrl: referrals?.link ?? "",
|
|
1988
|
+
firstName: me.firstName ?? me.displayName.split(/\s+/)[0] ?? "",
|
|
1989
|
+
location: me.location ?? "",
|
|
1990
|
+
credit: referrals?.credit ? fmtMoney(referrals.credit.perFriendCents).replace(/\.00$/, "") : ""
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
var fill = (template, vars) => formatChapterCopy(template, vars);
|
|
1994
|
+
var linkedinShareUrl = (post, link) => `https://www.linkedin.com/feed/?shareActive=true&text=${encodeURIComponent(`${post}
|
|
1995
|
+
|
|
1996
|
+
|
|
1997
|
+
${link}`).replace(/'/g, "%27")}`;
|
|
1998
|
+
var mailtoHref = (subject, body) => `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
|
|
1999
|
+
var smsHref = (body, ios) => `${ios ? "sms:&body=" : "sms:?body="}${encodeURIComponent(body)}`;
|
|
2000
|
+
var isIOS = (nav) => /iPad|iPhone|iPod/.test(nav.userAgent) || nav.platform === "MacIntel" && (nav.maxTouchPoints ?? 0) > 1;
|
|
2001
|
+
function useMemberReferrals(api) {
|
|
2002
|
+
const [state, setState] = useState15({ data: null, failed: false });
|
|
2003
|
+
useEffect8(() => {
|
|
2004
|
+
let live = true;
|
|
2005
|
+
void api("/api/member/referrals").then((data) => live && setState({ data, failed: false })).catch(() => live && setState({ data: null, failed: true }));
|
|
2006
|
+
return () => {
|
|
2007
|
+
live = false;
|
|
2008
|
+
};
|
|
2009
|
+
}, [api]);
|
|
2010
|
+
return state;
|
|
2011
|
+
}
|
|
2012
|
+
async function copyText(text, copy) {
|
|
2013
|
+
try {
|
|
2014
|
+
await navigator.clipboard.writeText(text);
|
|
2015
|
+
return copy.copied;
|
|
2016
|
+
} catch {
|
|
2017
|
+
return copy.copyBlocked;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
// src/ui/member-share-page.tsx
|
|
2022
|
+
import { Fragment as Fragment9, jsx as jsx22, jsxs as jsxs20 } from "preact/jsx-runtime";
|
|
2023
|
+
function CopyButton({ text, label, ctx, variant }) {
|
|
2024
|
+
const [shown, setShown] = useState16(label);
|
|
2025
|
+
return /* @__PURE__ */ jsx22("button", { type: "button", className: "chapter-portal-btn", "data-variant": variant, onClick: () => void copyText(text, ctx.copy.share).then((result) => {
|
|
2026
|
+
setShown(result);
|
|
2027
|
+
setTimeout(() => setShown(label), 2e3);
|
|
2028
|
+
}), children: shown });
|
|
2029
|
+
}
|
|
2030
|
+
function HowDialog({ ctx, vars, onClose, example }) {
|
|
2031
|
+
const copy = ctx.copy.share;
|
|
2032
|
+
useEffect9(() => {
|
|
2033
|
+
const onKey = (event) => {
|
|
2034
|
+
if (event.key === "Escape") onClose();
|
|
2035
|
+
};
|
|
2036
|
+
document.addEventListener("keydown", onKey);
|
|
2037
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2038
|
+
}, []);
|
|
2039
|
+
return /* @__PURE__ */ jsx22("div", { className: "chapter-portal-modal-back", "data-portal-dialog": true, onClick: (event) => {
|
|
2040
|
+
if (event.target === event.currentTarget) onClose();
|
|
2041
|
+
}, children: /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-modal chapter-portal-card", role: "dialog", "aria-modal": "true", "aria-labelledby": "chapter-portal-how-title", children: [
|
|
2042
|
+
/* @__PURE__ */ jsx22("button", { type: "button", className: "chapter-portal-modal-x", "aria-label": copy.close, onClick: onClose, children: /* @__PURE__ */ jsx22(PortalIcon, { name: "close", size: 20 }) }),
|
|
2043
|
+
/* @__PURE__ */ jsx22("div", { className: "chapter-portal-group-label", style: { padding: 0 }, children: copy.stepsEyebrow }),
|
|
2044
|
+
/* @__PURE__ */ jsx22("h2", { id: "chapter-portal-how-title", children: copy.officialTitle }),
|
|
2045
|
+
/* @__PURE__ */ jsx22("ol", { children: copy.steps.map((step) => /* @__PURE__ */ jsx22("li", { children: fill(step, vars) }, step)) }),
|
|
2046
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-btns", children: [
|
|
2047
|
+
/* @__PURE__ */ jsx22("a", { className: "chapter-portal-btn", href: "https://www.linkedin.com/in/me/", target: "_blank", rel: "noopener", children: copy.openLinkedIn }),
|
|
2048
|
+
/* @__PURE__ */ jsx22(CopyButton, { text: fill(copy.linkedinDescription, vars), label: copy.copyDescription, ctx, variant: "ghost" })
|
|
2049
|
+
] }),
|
|
2050
|
+
example
|
|
2051
|
+
] }) });
|
|
2052
|
+
}
|
|
2053
|
+
function OfficialCard({ ctx, referrals, example }) {
|
|
2054
|
+
const [open, setOpen] = useState16(false);
|
|
2055
|
+
const copy = ctx.copy.share;
|
|
2056
|
+
return /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-card", "data-official": true, children: [
|
|
2057
|
+
/* @__PURE__ */ jsx22("h2", { children: copy.officialTitle }),
|
|
2058
|
+
/* @__PURE__ */ jsx22("p", { children: copy.officialBody }),
|
|
2059
|
+
/* @__PURE__ */ jsx22("button", { type: "button", className: "chapter-portal-btn", onClick: () => setOpen(true), children: copy.showMeHow }),
|
|
2060
|
+
open ? /* @__PURE__ */ jsx22(HowDialog, { ctx, vars: shareVars(ctx.me, referrals), onClose: () => setOpen(false), example }) : null
|
|
2061
|
+
] });
|
|
2062
|
+
}
|
|
2063
|
+
function PostCard({ ctx, referrals }) {
|
|
2064
|
+
const copy = ctx.copy.share;
|
|
2065
|
+
const vars = shareVars(ctx.me, referrals);
|
|
2066
|
+
const post = fill(copy.linkedinPost, vars);
|
|
2067
|
+
return /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-card", "data-post": true, children: [
|
|
2068
|
+
/* @__PURE__ */ jsx22("h2", { children: copy.postTitle }),
|
|
2069
|
+
/* @__PURE__ */ jsx22("p", { children: copy.postBody }),
|
|
2070
|
+
/* @__PURE__ */ jsx22("a", { className: "chapter-portal-btn", href: linkedinShareUrl(post, vars.inviteUrl), target: "_blank", rel: "noopener", children: copy.shareOnLinkedIn }),
|
|
2071
|
+
/* @__PURE__ */ jsxs20("details", { children: [
|
|
2072
|
+
/* @__PURE__ */ jsx22("summary", { children: copy.previewPost }),
|
|
2073
|
+
/* @__PURE__ */ jsx22("p", { children: post }),
|
|
2074
|
+
/* @__PURE__ */ jsx22("p", { children: vars.inviteUrl })
|
|
2075
|
+
] })
|
|
2076
|
+
] });
|
|
2077
|
+
}
|
|
2078
|
+
function InviteLinkCard({ ctx, referrals }) {
|
|
2079
|
+
const copy = ctx.copy.share;
|
|
2080
|
+
const vars = shareVars(ctx.me, referrals);
|
|
2081
|
+
const [fallback, setFallback] = useState16(null);
|
|
2082
|
+
const ios = typeof navigator !== "undefined" && isIOS(navigator);
|
|
2083
|
+
const email = fill(copy.emailBody, vars), text = fill(copy.textBody, vars);
|
|
2084
|
+
const tryOpen = (kind) => setTimeout(() => {
|
|
2085
|
+
if (!document.hidden) setFallback(kind);
|
|
2086
|
+
}, 900);
|
|
2087
|
+
return /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-card", "data-invite-link": true, children: [
|
|
2088
|
+
/* @__PURE__ */ jsx22("h2", { children: copy.linkTitle }),
|
|
2089
|
+
/* @__PURE__ */ jsxs20("p", { children: [
|
|
2090
|
+
copy.linkBody,
|
|
2091
|
+
referrals?.credit ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
2092
|
+
" ",
|
|
2093
|
+
/* @__PURE__ */ jsx22("strong", { children: fill(copy.linkCredit, vars) })
|
|
2094
|
+
] }) : null
|
|
2095
|
+
] }),
|
|
2096
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-link-box", children: [
|
|
2097
|
+
/* @__PURE__ */ jsx22("code", { children: referrals ? referrals.link.replace(/^https?:\/\//, "") : "\u2026" }),
|
|
2098
|
+
referrals ? /* @__PURE__ */ jsx22(CopyButton, { text: referrals.link, label: copy.copyLink, ctx }) : null
|
|
2099
|
+
] }),
|
|
2100
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-btns", children: [
|
|
2101
|
+
/* @__PURE__ */ jsx22("a", { className: "chapter-portal-btn", "data-variant": "ghost", href: mailtoHref(copy.emailSubject, email), onClick: () => tryOpen("email"), children: copy.emailInvite }),
|
|
2102
|
+
/* @__PURE__ */ jsx22("a", { className: "chapter-portal-btn", "data-variant": "ghost", href: smsHref(text, ios), onClick: () => tryOpen("text"), children: copy.textInvite })
|
|
2103
|
+
] }),
|
|
2104
|
+
fallback ? /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-fallback", "data-fallback": fallback, children: [
|
|
2105
|
+
/* @__PURE__ */ jsx22("p", { children: fallback === "email" ? copy.fallbackEmail : copy.fallbackText }),
|
|
2106
|
+
/* @__PURE__ */ jsx22("pre", { style: { whiteSpace: "pre-wrap" }, children: fallback === "email" ? `${copy.emailSubject}
|
|
2107
|
+
|
|
2108
|
+
${email}` : text }),
|
|
2109
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-btns", children: [
|
|
2110
|
+
/* @__PURE__ */ jsx22(CopyButton, { text: fallback === "email" ? email : text, label: copy.copyMessage, ctx }),
|
|
2111
|
+
/* @__PURE__ */ jsx22("button", { type: "button", className: "chapter-portal-btn", "data-variant": "ghost", onClick: () => setFallback(null), children: copy.close })
|
|
2112
|
+
] })
|
|
2113
|
+
] }) : null,
|
|
2114
|
+
/* @__PURE__ */ jsx22("p", { style: { color: "var(--ui-text-muted)" }, children: copy.inviteNote })
|
|
2115
|
+
] });
|
|
2116
|
+
}
|
|
2117
|
+
function ReferralsCard({ ctx, referrals }) {
|
|
2118
|
+
const copy = ctx.copy.share;
|
|
2119
|
+
if (!referrals) return null;
|
|
2120
|
+
const vars = shareVars(ctx.me, referrals);
|
|
2121
|
+
const tile = (value, label) => /* @__PURE__ */ jsxs20("div", { children: [
|
|
2122
|
+
/* @__PURE__ */ jsx22("b", { children: value }),
|
|
2123
|
+
/* @__PURE__ */ jsx22("span", { children: label })
|
|
2124
|
+
] });
|
|
2125
|
+
return /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-card", "data-referrals": true, children: [
|
|
2126
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-top", children: [
|
|
2127
|
+
/* @__PURE__ */ jsx22("h2", { children: copy.referralsTitle }),
|
|
2128
|
+
/* @__PURE__ */ jsx22("button", { type: "button", className: "chapter-portal-btn", "data-variant": "ghost", onClick: () => {
|
|
2129
|
+
const share = ctx.content.pages.find((page) => page.kind === "feature" && page.feature?.name === "share");
|
|
2130
|
+
if (share) ctx.navigate({ kind: "page", slug: share.slug });
|
|
2131
|
+
}, children: copy.inviteFriend })
|
|
2132
|
+
] }),
|
|
2133
|
+
/* @__PURE__ */ jsxs20("p", { children: [
|
|
2134
|
+
copy.referralsBody,
|
|
2135
|
+
referrals.credit ? /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
2136
|
+
" ",
|
|
2137
|
+
fill(copy.referralsCredit, vars)
|
|
2138
|
+
] }) : null
|
|
2139
|
+
] }),
|
|
2140
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-tally", "data-tiles": referrals.credit ? 3 : 2, children: [
|
|
2141
|
+
tile(String(referrals.joined.count), copy.joined),
|
|
2142
|
+
tile(String(referrals.inProcess), copy.inProcess),
|
|
2143
|
+
referrals.credit ? tile(fmtMoney(referrals.credit.offNextYearCents).replace(/\.00$/, ""), copy.offNextYear) : null
|
|
2144
|
+
] }),
|
|
2145
|
+
referrals.joined.names.length ? /* @__PURE__ */ jsx22("p", { children: fill(copy.joinedWith, { names: referrals.joined.names.join(", ") }) }) : null
|
|
2146
|
+
] });
|
|
2147
|
+
}
|
|
2148
|
+
function SharePage({ page, ctx, example }) {
|
|
2149
|
+
const { data } = useMemberReferrals(ctx.api);
|
|
2150
|
+
return /* @__PURE__ */ jsxs20("div", { className: "chapter-portal-stack", "data-share-page": true, children: [
|
|
2151
|
+
/* @__PURE__ */ jsxs20("div", { children: [
|
|
2152
|
+
/* @__PURE__ */ jsx22("div", { className: "chapter-portal-group-label", style: { padding: 0 }, children: ctx.copy.share.eyebrow }),
|
|
2153
|
+
/* @__PURE__ */ jsx22("h1", { style: { margin: ".3rem 0", fontFamily: "var(--ui-font-display,inherit)", fontWeight: 400 }, children: page.title }),
|
|
2154
|
+
/* @__PURE__ */ jsx22("p", { style: { maxWidth: "40rem", color: "var(--ui-text-muted)" }, children: page.summary ?? ctx.copy.share.intro })
|
|
2155
|
+
] }),
|
|
2156
|
+
/* @__PURE__ */ jsx22(OfficialCard, { ctx, referrals: data, example }),
|
|
2157
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-tiles", children: [
|
|
2158
|
+
/* @__PURE__ */ jsx22(PostCard, { ctx, referrals: data }),
|
|
2159
|
+
/* @__PURE__ */ jsx22(InviteLinkCard, { ctx, referrals: data })
|
|
2160
|
+
] })
|
|
2161
|
+
] });
|
|
2162
|
+
}
|
|
2163
|
+
function ShareHome({ ctx }) {
|
|
2164
|
+
const { data } = useMemberReferrals(ctx.api);
|
|
2165
|
+
return /* @__PURE__ */ jsxs20("section", { className: "chapter-portal-stack", "data-share-home": true, children: [
|
|
2166
|
+
/* @__PURE__ */ jsx22("h2", { style: { fontFamily: "var(--ui-font-display,inherit)", fontWeight: 400, margin: 0 }, children: ctx.copy.share.eyebrow }),
|
|
2167
|
+
/* @__PURE__ */ jsx22(OfficialCard, { ctx, referrals: data }),
|
|
2168
|
+
/* @__PURE__ */ jsxs20("div", { className: "chapter-portal-tiles", children: [
|
|
2169
|
+
/* @__PURE__ */ jsx22(PostCard, { ctx, referrals: data }),
|
|
2170
|
+
/* @__PURE__ */ jsx22(InviteLinkCard, { ctx, referrals: data })
|
|
2171
|
+
] })
|
|
2172
|
+
] });
|
|
2173
|
+
}
|
|
2174
|
+
function ProfileReferrals({ ctx }) {
|
|
2175
|
+
const { data } = useMemberReferrals(ctx.api);
|
|
2176
|
+
return /* @__PURE__ */ jsx22(ReferralsCard, { ctx, referrals: data });
|
|
2177
|
+
}
|
|
2178
|
+
|
|
1845
2179
|
// src/ui/member-portal-features.tsx
|
|
1846
|
-
|
|
2180
|
+
import { jsx as jsx23 } from "preact/jsx-runtime";
|
|
2181
|
+
var PACKAGED_PORTAL_FEATURES = {
|
|
2182
|
+
course: { page: (page, ctx) => /* @__PURE__ */ jsx23(CoursePage, { page, ctx }), home: (page, ctx) => /* @__PURE__ */ jsx23(CourseHomePanel, { page, ctx }) },
|
|
2183
|
+
share: { page: (page, ctx) => /* @__PURE__ */ jsx23(SharePage, { page, ctx }), home: (_page, ctx) => /* @__PURE__ */ jsx23(ShareHome, { ctx }) }
|
|
2184
|
+
};
|
|
1847
2185
|
|
|
1848
2186
|
// src/ui/member-portal.tsx
|
|
1849
|
-
import { jsx as
|
|
2187
|
+
import { jsx as jsx24, jsxs as jsxs21 } from "preact/jsx-runtime";
|
|
1850
2188
|
var EMPTY = { pages: [], sections: [], viewer: { tierId: null, admin: false }, revisions: { parent: null, chapter: null } };
|
|
1851
2189
|
function MemberPortal(props) {
|
|
1852
2190
|
const inherited = useChapterCopy();
|
|
1853
2191
|
const copy = props.copy ?? inherited.portal;
|
|
1854
2192
|
const routing = { mode: props.routing?.mode ?? "hash", basePath: props.routing?.basePath ?? "/members" };
|
|
1855
|
-
const [content, setContent] =
|
|
1856
|
-
const [route, setRoute] =
|
|
1857
|
-
const [menuOpen, setMenuOpen] =
|
|
1858
|
-
|
|
2193
|
+
const [content, setContent] = useState17(props.initialContent ?? null);
|
|
2194
|
+
const [route, setRoute] = useState17(props.initialRoute ?? { kind: "home" });
|
|
2195
|
+
const [menuOpen, setMenuOpen] = useState17(false);
|
|
2196
|
+
useEffect10(() => {
|
|
1859
2197
|
if (props.initialContent) return;
|
|
1860
2198
|
let live = true;
|
|
1861
2199
|
void props.api("/api/member-content").then((value) => live && setContent(value)).catch(() => live && setContent(EMPTY));
|
|
@@ -1863,7 +2201,7 @@ function MemberPortal(props) {
|
|
|
1863
2201
|
live = false;
|
|
1864
2202
|
};
|
|
1865
2203
|
}, [props.api, props.initialContent]);
|
|
1866
|
-
|
|
2204
|
+
useEffect10(() => {
|
|
1867
2205
|
if (typeof window === "undefined" || props.initialRoute) return;
|
|
1868
2206
|
const sync = () => setRoute(routeFromLocation(window.location, routing));
|
|
1869
2207
|
sync();
|
|
@@ -1883,9 +2221,9 @@ function MemberPortal(props) {
|
|
|
1883
2221
|
}
|
|
1884
2222
|
};
|
|
1885
2223
|
const features = useMemo3(() => ({ ...PACKAGED_PORTAL_FEATURES, ...props.features }), [props.features]);
|
|
1886
|
-
if (!content) return /* @__PURE__ */
|
|
1887
|
-
/* @__PURE__ */
|
|
1888
|
-
/* @__PURE__ */
|
|
2224
|
+
if (!content) return /* @__PURE__ */ jsxs21("div", { className: "chapter-portal", children: [
|
|
2225
|
+
/* @__PURE__ */ jsx24("style", { children: MEMBER_PORTAL_CSS }),
|
|
2226
|
+
/* @__PURE__ */ jsx24("p", { children: copy.shell.loading })
|
|
1889
2227
|
] });
|
|
1890
2228
|
const ctx = {
|
|
1891
2229
|
api: props.api,
|
|
@@ -1901,12 +2239,13 @@ function MemberPortal(props) {
|
|
|
1901
2239
|
};
|
|
1902
2240
|
const page = route.kind === "page" ? content.pages.find((candidate) => candidate.slug === route.slug) : void 0;
|
|
1903
2241
|
const slots = typeof props.home === "function" ? {} : props.home ?? {};
|
|
1904
|
-
const
|
|
1905
|
-
const
|
|
2242
|
+
const shareAllowed = content.pages.some((candidate) => candidate.kind === "feature" && candidate.feature?.name === "share" && candidate.access === "allowed");
|
|
2243
|
+
const home = /* @__PURE__ */ jsx24(DefaultHome, { ctx, features, slots });
|
|
2244
|
+
const body = route.kind === "home" ? typeof props.home === "function" ? props.home(ctx, home) : home : route.kind === "profile" ? /* @__PURE__ */ jsx24(MemberProfilePage, { ctx, middle: props.profile?.middle ? props.profile.middle(ctx) : shareAllowed ? /* @__PURE__ */ jsx24(ProfileReferrals, { ctx }) : null, extras: props.profile?.extras }) : page ? /* @__PURE__ */ jsx24(PortalPage, { page, ctx, features }) : /* @__PURE__ */ jsx24("div", { className: "chapter-portal-card", children: copy.shell.notFound });
|
|
1906
2245
|
const admin = props.me.authorized || props.me.superAdmin ? props.adminHref ?? "/admin/" : void 0;
|
|
1907
|
-
return /* @__PURE__ */
|
|
1908
|
-
/* @__PURE__ */
|
|
1909
|
-
/* @__PURE__ */
|
|
2246
|
+
return /* @__PURE__ */ jsxs21("div", { className: "chapter-portal", "data-member-portal": true, "data-route": route.kind, children: [
|
|
2247
|
+
/* @__PURE__ */ jsx24("style", { children: MEMBER_PORTAL_CSS }),
|
|
2248
|
+
/* @__PURE__ */ jsx24(
|
|
1910
2249
|
PortalNav,
|
|
1911
2250
|
{
|
|
1912
2251
|
content,
|
|
@@ -1923,12 +2262,12 @@ function MemberPortal(props) {
|
|
|
1923
2262
|
onToggleMenu: () => setMenuOpen(!menuOpen)
|
|
1924
2263
|
}
|
|
1925
2264
|
),
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
1928
|
-
route.kind === "home" ? /* @__PURE__ */
|
|
1929
|
-
/* @__PURE__ */
|
|
1930
|
-
ctx.me.tier ? /* @__PURE__ */
|
|
1931
|
-
/* @__PURE__ */
|
|
2265
|
+
/* @__PURE__ */ jsxs21("main", { className: "chapter-portal-main", children: [
|
|
2266
|
+
/* @__PURE__ */ jsxs21("div", { className: "chapter-portal-top", children: [
|
|
2267
|
+
route.kind === "home" ? /* @__PURE__ */ jsx24("h1", { children: copy.shell.welcomeBack }) : /* @__PURE__ */ jsx24("button", { type: "button", className: "chapter-portal-back", onClick: () => navigate({ kind: "home" }), children: copy.shell.backHome }),
|
|
2268
|
+
/* @__PURE__ */ jsxs21("div", { className: "chapter-portal-top-right", children: [
|
|
2269
|
+
ctx.me.tier ? /* @__PURE__ */ jsx24("span", { className: "chapter-portal-pill", children: ctx.me.tier.name }) : null,
|
|
2270
|
+
/* @__PURE__ */ jsx24(
|
|
1932
2271
|
"button",
|
|
1933
2272
|
{
|
|
1934
2273
|
type: "button",
|
|
@@ -1937,7 +2276,7 @@ function MemberPortal(props) {
|
|
|
1937
2276
|
title: copy.shell.yourProfile,
|
|
1938
2277
|
"aria-current": route.kind === "profile" ? "page" : void 0,
|
|
1939
2278
|
onClick: () => navigate({ kind: "profile" }),
|
|
1940
|
-
children: /* @__PURE__ */
|
|
2279
|
+
children: /* @__PURE__ */ jsx24(PortalAvatar, { me: ctx.me })
|
|
1941
2280
|
}
|
|
1942
2281
|
)
|
|
1943
2282
|
] })
|
|
@@ -1948,12 +2287,12 @@ function MemberPortal(props) {
|
|
|
1948
2287
|
}
|
|
1949
2288
|
|
|
1950
2289
|
// src/ui/members.tsx
|
|
1951
|
-
import { Fragment as
|
|
2290
|
+
import { Fragment as Fragment10, jsx as jsx25, jsxs as jsxs22 } from "preact/jsx-runtime";
|
|
1952
2291
|
function card(copy, kicker, body) {
|
|
1953
|
-
return /* @__PURE__ */
|
|
1954
|
-
/* @__PURE__ */
|
|
1955
|
-
/* @__PURE__ */
|
|
1956
|
-
/* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsxs22("div", { className: "card", children: [
|
|
2293
|
+
/* @__PURE__ */ jsx25("div", { className: "card-label", children: copy.provisional.cardLabel }),
|
|
2294
|
+
/* @__PURE__ */ jsxs22("div", { className: "meeting-block", children: [
|
|
2295
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-kicker", children: kicker }),
|
|
1957
2296
|
body
|
|
1958
2297
|
] })
|
|
1959
2298
|
] });
|
|
@@ -1964,32 +2303,32 @@ function ProvisionalCard(props) {
|
|
|
1964
2303
|
return card(
|
|
1965
2304
|
copy,
|
|
1966
2305
|
copy.provisional.applicationNeeded,
|
|
1967
|
-
/* @__PURE__ */
|
|
1968
|
-
/* @__PURE__ */
|
|
1969
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
2307
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-note", children: copy.provisional.applicationNeededBody }),
|
|
2308
|
+
/* @__PURE__ */ jsx25("a", { className: "apply-link", href: applyHref, children: copy.provisional.apply })
|
|
1970
2309
|
] })
|
|
1971
2310
|
);
|
|
1972
2311
|
}
|
|
1973
2312
|
if (application.status === "declined") {
|
|
1974
|
-
return card(copy, copy.provisional.declined, /* @__PURE__ */
|
|
2313
|
+
return card(copy, copy.provisional.declined, /* @__PURE__ */ jsx25("div", { className: "meeting-note", children: copy.provisional.declinedBody }));
|
|
1975
2314
|
}
|
|
1976
2315
|
if (application.status === "refunded") {
|
|
1977
2316
|
return card(
|
|
1978
2317
|
copy,
|
|
1979
2318
|
copy.provisional.refunded,
|
|
1980
|
-
/* @__PURE__ */
|
|
2319
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-note", children: copy.provisional.refundedBody })
|
|
1981
2320
|
);
|
|
1982
2321
|
}
|
|
1983
|
-
const membership = application.paid ? /* @__PURE__ */
|
|
2322
|
+
const membership = application.paid ? /* @__PURE__ */ jsx25("div", { className: "meeting-note", children: application.renewalAt ? formatChapterCopy(copy.provisional.renews, { date: fmtDate(application.renewalAt) }) : copy.provisional.active }) : null;
|
|
1984
2323
|
if (application.meetingAt) {
|
|
1985
2324
|
return card(
|
|
1986
2325
|
copy,
|
|
1987
2326
|
copy.provisional.introductionCall,
|
|
1988
|
-
/* @__PURE__ */
|
|
1989
|
-
/* @__PURE__ */
|
|
1990
|
-
/* @__PURE__ */
|
|
1991
|
-
application.meetUrl ? /* @__PURE__ */
|
|
1992
|
-
/* @__PURE__ */
|
|
2327
|
+
/* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
2328
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-date", children: fullLabel(application.meetingAt, application.timezone) }),
|
|
2329
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-note", children: copy.provisional.calendarInvite }),
|
|
2330
|
+
application.meetUrl ? /* @__PURE__ */ jsx25("div", { className: "meeting-note", children: /* @__PURE__ */ jsx25("a", { href: application.meetUrl, target: "_blank", rel: "noopener", children: copy.provisional.joinCall }) }) : null,
|
|
2331
|
+
/* @__PURE__ */ jsx25(
|
|
1993
2332
|
Rescheduler,
|
|
1994
2333
|
{
|
|
1995
2334
|
api,
|
|
@@ -2006,9 +2345,9 @@ function ProvisionalCard(props) {
|
|
|
2006
2345
|
return card(
|
|
2007
2346
|
copy,
|
|
2008
2347
|
copy.provisional.bookCall,
|
|
2009
|
-
/* @__PURE__ */
|
|
2010
|
-
/* @__PURE__ */
|
|
2011
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
2349
|
+
/* @__PURE__ */ jsx25("div", { className: "meeting-note", children: copy.provisional.bookCallBody }),
|
|
2350
|
+
/* @__PURE__ */ jsx25(
|
|
2012
2351
|
Rescheduler,
|
|
2013
2352
|
{
|
|
2014
2353
|
api,
|
|
@@ -2035,8 +2374,8 @@ function MembersArea(props) {
|
|
|
2035
2374
|
renderProvisional
|
|
2036
2375
|
} = props;
|
|
2037
2376
|
const copy = props.copy ?? inheritedCopy.members;
|
|
2038
|
-
const [me, setMe] =
|
|
2039
|
-
const [error, setError] =
|
|
2377
|
+
const [me, setMe] = useState18(null);
|
|
2378
|
+
const [error, setError] = useState18(false);
|
|
2040
2379
|
const reload = async () => {
|
|
2041
2380
|
try {
|
|
2042
2381
|
setMe(await api("/api/me"));
|
|
@@ -2044,14 +2383,14 @@ function MembersArea(props) {
|
|
|
2044
2383
|
setError(true);
|
|
2045
2384
|
}
|
|
2046
2385
|
};
|
|
2047
|
-
|
|
2386
|
+
useEffect11(() => {
|
|
2048
2387
|
void reload();
|
|
2049
2388
|
}, []);
|
|
2050
|
-
if (error) return /* @__PURE__ */
|
|
2051
|
-
if (!me) return /* @__PURE__ */
|
|
2389
|
+
if (error) return /* @__PURE__ */ jsx25("p", { className: "meeting-note", children: copy.loadFailed });
|
|
2390
|
+
if (!me) return /* @__PURE__ */ jsx25("p", { className: "meeting-note", children: inheritedCopy.common.loading });
|
|
2052
2391
|
if (props.portal && me.memberAccess === true && me.portal) {
|
|
2053
|
-
const gifts = /* @__PURE__ */
|
|
2054
|
-
return /* @__PURE__ */
|
|
2392
|
+
const gifts = /* @__PURE__ */ jsx25(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment });
|
|
2393
|
+
return /* @__PURE__ */ jsx25(
|
|
2055
2394
|
MemberPortal,
|
|
2056
2395
|
{
|
|
2057
2396
|
...props.portal,
|
|
@@ -2060,28 +2399,28 @@ function MembersArea(props) {
|
|
|
2060
2399
|
signOut,
|
|
2061
2400
|
reloadMe: reload,
|
|
2062
2401
|
adminHref: props.portal.adminHref ?? adminHref,
|
|
2063
|
-
profile: { ...props.portal.profile, extras: /* @__PURE__ */
|
|
2402
|
+
profile: { ...props.portal.profile, extras: /* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
2064
2403
|
props.portal.profile?.extras,
|
|
2065
2404
|
gifts,
|
|
2066
|
-
me.namedSeatsEnabled ? /* @__PURE__ */
|
|
2405
|
+
me.namedSeatsEnabled ? /* @__PURE__ */ jsx25(NamedSeatPurchase, { api }) : null
|
|
2067
2406
|
] }) }
|
|
2068
2407
|
}
|
|
2069
2408
|
);
|
|
2070
2409
|
}
|
|
2071
2410
|
const role = me.role || "provisional";
|
|
2072
|
-
return /* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2074
|
-
/* @__PURE__ */
|
|
2075
|
-
/* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2411
|
+
return /* @__PURE__ */ jsxs22(Fragment10, { children: [
|
|
2412
|
+
/* @__PURE__ */ jsxs22("div", { className: "card", children: [
|
|
2413
|
+
/* @__PURE__ */ jsxs22("div", { className: "member-row", children: [
|
|
2414
|
+
/* @__PURE__ */ jsx25("span", { className: "member-email", children: me.email }),
|
|
2415
|
+
/* @__PURE__ */ jsx25("span", { className: "role-badge " + role, children: role })
|
|
2077
2416
|
] }),
|
|
2078
|
-
/* @__PURE__ */
|
|
2079
|
-
/* @__PURE__ */
|
|
2080
|
-
me.authorized || me.superAdmin ? /* @__PURE__ */
|
|
2417
|
+
/* @__PURE__ */ jsxs22("div", { className: "account-actions", children: [
|
|
2418
|
+
/* @__PURE__ */ jsx25("button", { className: "btn secondary mini", onClick: signOut, children: copy.account.signOut }),
|
|
2419
|
+
me.authorized || me.superAdmin ? /* @__PURE__ */ jsx25("a", { className: "admin-console-link", href: adminHref, children: copy.account.adminConsole }) : null
|
|
2081
2420
|
] })
|
|
2082
2421
|
] }),
|
|
2083
|
-
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */
|
|
2084
|
-
const defaultContent = /* @__PURE__ */
|
|
2422
|
+
me.memberAccess !== true && me.membershipRestart?.eligible && me.application ? /* @__PURE__ */ jsx25(MemberRestart, { api, application: me.application, applicationId: me.membershipRestart.applicationId, onComplete: reload }) : me.memberAccess !== true ? (() => {
|
|
2423
|
+
const defaultContent = /* @__PURE__ */ jsx25(
|
|
2085
2424
|
ProvisionalCard,
|
|
2086
2425
|
{
|
|
2087
2426
|
api,
|
|
@@ -2098,27 +2437,34 @@ function MembersArea(props) {
|
|
|
2098
2437
|
reload,
|
|
2099
2438
|
defaultContent
|
|
2100
2439
|
}) ?? defaultContent;
|
|
2101
|
-
})() : memberContent ?? (memberPages ? /* @__PURE__ */
|
|
2440
|
+
})() : memberContent ?? (memberPages ? /* @__PURE__ */ jsx25(
|
|
2102
2441
|
MemberContentArea,
|
|
2103
2442
|
{
|
|
2104
2443
|
api,
|
|
2105
2444
|
...memberPages === true ? {} : memberPages
|
|
2106
2445
|
}
|
|
2107
|
-
) : /* @__PURE__ */
|
|
2108
|
-
/* @__PURE__ */
|
|
2109
|
-
me.namedSeatsEnabled ? /* @__PURE__ */
|
|
2446
|
+
) : /* @__PURE__ */ jsx25("div", { className: "card", children: /* @__PURE__ */ jsx25("div", { className: "card-label", children: copy.full.welcome }) })),
|
|
2447
|
+
/* @__PURE__ */ jsx25(GiftPurchases, { api, copy: copy.gifts, paymentCopy: inheritedCopy.join.payment }),
|
|
2448
|
+
me.namedSeatsEnabled ? /* @__PURE__ */ jsx25(NamedSeatPurchase, { api }) : null
|
|
2110
2449
|
] });
|
|
2111
2450
|
}
|
|
2112
2451
|
|
|
2452
|
+
// src/ui/join-referral.ts
|
|
2453
|
+
var CODE = /^[23456789abcdefghjkmnpqrstuvwxyz]{5,8}$/;
|
|
2454
|
+
function referralFromLocation(search = typeof location === "undefined" ? "" : location.search) {
|
|
2455
|
+
const code = new URLSearchParams(search).get("ref")?.trim().toLowerCase() ?? "";
|
|
2456
|
+
return CODE.test(code) ? { referralCode: code } : {};
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2113
2459
|
// src/ui/join.tsx
|
|
2114
|
-
import { useEffect as
|
|
2460
|
+
import { useEffect as useEffect16, useRef as useRef8, useState as useState26 } from "preact/hooks";
|
|
2115
2461
|
|
|
2116
2462
|
// src/ui/join-booking.tsx
|
|
2117
|
-
import { useEffect as
|
|
2118
|
-
import { jsx as
|
|
2463
|
+
import { useEffect as useEffect12, useRef as useRef6, useState as useState19 } from "preact/hooks";
|
|
2464
|
+
import { jsx as jsx26, jsxs as jsxs23 } from "preact/jsx-runtime";
|
|
2119
2465
|
function useJoinSlotsPreload(active) {
|
|
2120
2466
|
const preload = useRef6(null);
|
|
2121
|
-
|
|
2467
|
+
useEffect12(() => {
|
|
2122
2468
|
if (!active || preload.current) return;
|
|
2123
2469
|
preload.current = Promise.resolve().then(() => fetch("/api/schedule/slots"));
|
|
2124
2470
|
preload.current.catch(() => {
|
|
@@ -2129,11 +2475,11 @@ function useJoinSlotsPreload(active) {
|
|
|
2129
2475
|
}
|
|
2130
2476
|
function JoinBooking(props) {
|
|
2131
2477
|
const { applicationId, copy, onBooked, simulation } = props;
|
|
2132
|
-
const [state, setState] =
|
|
2133
|
-
const [msg, setMsg] =
|
|
2134
|
-
const [busy, setBusy] =
|
|
2135
|
-
const [day2, setDay] =
|
|
2136
|
-
const [selected, setSelected] =
|
|
2478
|
+
const [state, setState] = useState19(null);
|
|
2479
|
+
const [msg, setMsg] = useState19(null);
|
|
2480
|
+
const [busy, setBusy] = useState19(false);
|
|
2481
|
+
const [day2, setDay] = useState19(null);
|
|
2482
|
+
const [selected, setSelected] = useState19(null);
|
|
2137
2483
|
const load = async (preloaded) => {
|
|
2138
2484
|
setMsg(null);
|
|
2139
2485
|
try {
|
|
@@ -2158,7 +2504,7 @@ function JoinBooking(props) {
|
|
|
2158
2504
|
setMsg(copy.loadFailed);
|
|
2159
2505
|
}
|
|
2160
2506
|
};
|
|
2161
|
-
|
|
2507
|
+
useEffect12(() => {
|
|
2162
2508
|
void load(props.preload);
|
|
2163
2509
|
}, [simulation]);
|
|
2164
2510
|
const book = async () => {
|
|
@@ -2190,17 +2536,17 @@ function JoinBooking(props) {
|
|
|
2190
2536
|
setBusy(false);
|
|
2191
2537
|
}
|
|
2192
2538
|
};
|
|
2193
|
-
if (!state) return /* @__PURE__ */
|
|
2539
|
+
if (!state) return /* @__PURE__ */ jsx26("p", { className: "slots-status", children: msg ?? copy.loading });
|
|
2194
2540
|
const hint = !day2 ? copy.pickDate ?? DEFAULT_JOIN_COPY.booking.pickDate : !selected ? copy.pickTime ?? DEFAULT_JOIN_COPY.booking.pickTime : null;
|
|
2195
|
-
return /* @__PURE__ */
|
|
2196
|
-
/* @__PURE__ */
|
|
2197
|
-
/* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
hint ? /* @__PURE__ */
|
|
2201
|
-
msg ? /* @__PURE__ */
|
|
2541
|
+
return /* @__PURE__ */ jsxs23("div", { className: "join-book", children: [
|
|
2542
|
+
/* @__PURE__ */ jsx26("h2", { children: copy.title ?? DEFAULT_JOIN_COPY.booking.title }),
|
|
2543
|
+
/* @__PURE__ */ jsx26("p", { children: copy.intro ?? DEFAULT_JOIN_COPY.booking.intro }),
|
|
2544
|
+
/* @__PURE__ */ jsxs23("div", { className: "slot-confirm", children: [
|
|
2545
|
+
/* @__PURE__ */ jsx26("button", { className: "submit-btn", type: "button", disabled: busy || !selected, onClick: () => void book(), children: busy ? copy.booking : copy.book }),
|
|
2546
|
+
hint ? /* @__PURE__ */ jsx26("p", { className: "slot-hint", role: "status", children: hint }) : null,
|
|
2547
|
+
msg ? /* @__PURE__ */ jsx26("p", { className: "step2-note", role: "alert", children: msg }) : null
|
|
2202
2548
|
] }),
|
|
2203
|
-
/* @__PURE__ */
|
|
2549
|
+
/* @__PURE__ */ jsx26(
|
|
2204
2550
|
SlotPicker,
|
|
2205
2551
|
{
|
|
2206
2552
|
slots: state.slots,
|
|
@@ -2218,21 +2564,21 @@ function JoinBooking(props) {
|
|
|
2218
2564
|
}
|
|
2219
2565
|
|
|
2220
2566
|
// src/ui/join-accepted.tsx
|
|
2221
|
-
import { jsx as
|
|
2567
|
+
import { jsx as jsx27, jsxs as jsxs24 } from "preact/jsx-runtime";
|
|
2222
2568
|
function JoinAccepted(props) {
|
|
2223
|
-
return /* @__PURE__ */
|
|
2224
|
-
/* @__PURE__ */
|
|
2225
|
-
/* @__PURE__ */
|
|
2226
|
-
/* @__PURE__ */
|
|
2569
|
+
return /* @__PURE__ */ jsxs24("div", { className: "join-done card", children: [
|
|
2570
|
+
/* @__PURE__ */ jsx27("div", { className: "card-label", children: props.copy.accepted.label }),
|
|
2571
|
+
/* @__PURE__ */ jsx27("p", { className: "meeting-note", children: props.copy.accepted.body }),
|
|
2572
|
+
/* @__PURE__ */ jsx27("a", { className: "apply-link", href: props.membersHref, children: props.copy.done.memberArea })
|
|
2227
2573
|
] });
|
|
2228
2574
|
}
|
|
2229
2575
|
|
|
2230
2576
|
// src/ui/gift-claim-card.tsx
|
|
2231
|
-
import { useState as
|
|
2232
|
-
import { Fragment as
|
|
2577
|
+
import { useState as useState20 } from "preact/hooks";
|
|
2578
|
+
import { Fragment as Fragment11, jsx as jsx28, jsxs as jsxs25 } from "preact/jsx-runtime";
|
|
2233
2579
|
function GiftClaimCard(props) {
|
|
2234
|
-
const [code, setCode] =
|
|
2235
|
-
const [error, setError] =
|
|
2580
|
+
const [code, setCode] = useState20(props.initialCode ?? "");
|
|
2581
|
+
const [error, setError] = useState20(false);
|
|
2236
2582
|
const rotate = async () => {
|
|
2237
2583
|
if (!props.claimId) return;
|
|
2238
2584
|
setError(false);
|
|
@@ -2245,15 +2591,15 @@ function GiftClaimCard(props) {
|
|
|
2245
2591
|
if (response.ok && body.code) setCode(body.code);
|
|
2246
2592
|
else setError(true);
|
|
2247
2593
|
};
|
|
2248
|
-
return /* @__PURE__ */
|
|
2249
|
-
/* @__PURE__ */
|
|
2250
|
-
/* @__PURE__ */
|
|
2251
|
-
code ? /* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
2253
|
-
/* @__PURE__ */
|
|
2594
|
+
return /* @__PURE__ */ jsxs25("div", { className: "join-done card", children: [
|
|
2595
|
+
/* @__PURE__ */ jsx28("div", { className: "card-label", children: props.copy.label }),
|
|
2596
|
+
/* @__PURE__ */ jsx28("p", { className: "meeting-note", children: props.copy.body }),
|
|
2597
|
+
code ? /* @__PURE__ */ jsxs25(Fragment11, { children: [
|
|
2598
|
+
/* @__PURE__ */ jsx28("output", { className: "gift-code", children: code }),
|
|
2599
|
+
/* @__PURE__ */ jsx28("p", { children: props.copy.save })
|
|
2254
2600
|
] }) : null,
|
|
2255
|
-
!code && props.claimId ? /* @__PURE__ */
|
|
2256
|
-
error ? /* @__PURE__ */
|
|
2601
|
+
!code && props.claimId ? /* @__PURE__ */ jsx28("button", { type: "button", className: "btn secondary", onClick: () => void rotate(), children: props.copy.rotate }) : null,
|
|
2602
|
+
error ? /* @__PURE__ */ jsx28("p", { role: "alert", children: props.copy.rotateFailed }) : null
|
|
2257
2603
|
] });
|
|
2258
2604
|
}
|
|
2259
2605
|
|
|
@@ -2261,11 +2607,11 @@ function GiftClaimCard(props) {
|
|
|
2261
2607
|
import { useRef as useRef7 } from "preact/hooks";
|
|
2262
2608
|
|
|
2263
2609
|
// src/ui/join-tiers.tsx
|
|
2264
|
-
import { useState as
|
|
2265
|
-
import { Fragment as
|
|
2610
|
+
import { useState as useState21 } from "preact/hooks";
|
|
2611
|
+
import { Fragment as Fragment12, jsx as jsx29, jsxs as jsxs26 } from "preact/jsx-runtime";
|
|
2266
2612
|
var joinTierMoney = (cents, currency = "usd") => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
2267
2613
|
function useTierSelection(tiers, initialTierId) {
|
|
2268
|
-
const [selectedTierId, setSelectedTierId] =
|
|
2614
|
+
const [selectedTierId, setSelectedTierId] = useState21(() => {
|
|
2269
2615
|
const preset = tiers.find((tier) => tier.id === initialTierId);
|
|
2270
2616
|
if (preset) return preset.id;
|
|
2271
2617
|
return tiers.length === 1 ? tiers[0].id : null;
|
|
@@ -2280,10 +2626,10 @@ function useTierSelection(tiers, initialTierId) {
|
|
|
2280
2626
|
};
|
|
2281
2627
|
}
|
|
2282
2628
|
function TierPlaceholder(context) {
|
|
2283
|
-
return /* @__PURE__ */
|
|
2284
|
-
/* @__PURE__ */
|
|
2285
|
-
context.tiers.map((tier) => /* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2629
|
+
return /* @__PURE__ */ jsxs26("fieldset", { "data-chapter-placeholder": "tiers", children: [
|
|
2630
|
+
/* @__PURE__ */ jsx29("legend", { children: "Membership (placeholder \u2014 pass renderTiers to style this)" }),
|
|
2631
|
+
context.tiers.map((tier) => /* @__PURE__ */ jsxs26("label", { children: [
|
|
2632
|
+
/* @__PURE__ */ jsx29(
|
|
2287
2633
|
"input",
|
|
2288
2634
|
{
|
|
2289
2635
|
type: "radio",
|
|
@@ -2294,13 +2640,13 @@ function TierPlaceholder(context) {
|
|
|
2294
2640
|
}
|
|
2295
2641
|
),
|
|
2296
2642
|
tier.name,
|
|
2297
|
-
tier.founding ? /* @__PURE__ */
|
|
2643
|
+
tier.founding ? /* @__PURE__ */ jsxs26(Fragment12, { children: [
|
|
2298
2644
|
" \u2014 ",
|
|
2299
2645
|
joinTierMoney(tier.founding.dueTodayCents),
|
|
2300
2646
|
" founding member rate (list ",
|
|
2301
2647
|
joinTierMoney(tier.priceCents),
|
|
2302
2648
|
")"
|
|
2303
|
-
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */
|
|
2649
|
+
] }) : tier.free ? " \u2014 free" : /* @__PURE__ */ jsxs26(Fragment12, { children: [
|
|
2304
2650
|
" \u2014 ",
|
|
2305
2651
|
joinTierMoney(tier.priceCents)
|
|
2306
2652
|
] })
|
|
@@ -2312,12 +2658,12 @@ function tierNeedsPayment(selected, paymentsReady) {
|
|
|
2312
2658
|
}
|
|
2313
2659
|
|
|
2314
2660
|
// src/ui/join-application-form.tsx
|
|
2315
|
-
import { jsx as
|
|
2661
|
+
import { jsx as jsx30, jsxs as jsxs27 } from "preact/jsx-runtime";
|
|
2316
2662
|
function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelection, giftOfferId, selectGift, submitting, error, submit }) {
|
|
2317
2663
|
const form = useRef7(null);
|
|
2318
2664
|
const ready = useFormReadiness(form);
|
|
2319
2665
|
const disabled = submitting || props.submitDisabled === true || !ready || !validJoinRecipient(props.payment?.initialNamedSeat);
|
|
2320
|
-
return /* @__PURE__ */
|
|
2666
|
+
return /* @__PURE__ */ jsxs27("form", { ref: form, className: "join-form", onSubmit: (event) => {
|
|
2321
2667
|
if (!isFormReady(event.currentTarget)) {
|
|
2322
2668
|
event.preventDefault();
|
|
2323
2669
|
event.currentTarget.reportValidity();
|
|
@@ -2325,15 +2671,15 @@ function JoinApplicationForm({ props, copy, invitation, requestedSeat, tierSelec
|
|
|
2325
2671
|
}
|
|
2326
2672
|
void submit(event);
|
|
2327
2673
|
}, children: [
|
|
2328
|
-
!requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */
|
|
2329
|
-
/* @__PURE__ */
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
2674
|
+
!requestedSeat && (props.config.giftOffers?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs27("fieldset", { children: [
|
|
2675
|
+
/* @__PURE__ */ jsx30("legend", { children: copy.gift.optionsLabel }),
|
|
2676
|
+
/* @__PURE__ */ jsx30("button", { type: "button", className: "btn secondary", "aria-pressed": !giftOfferId, onClick: () => selectGift(null), children: copy.gift.chooseSelf }),
|
|
2677
|
+
/* @__PURE__ */ jsx30(GiftOfferCards, { offers: props.config.giftOffers ?? [], mode: "select", selectedOfferId: giftOfferId, onSelect: selectGift })
|
|
2332
2678
|
] }) : null,
|
|
2333
2679
|
!requestedSeat && (props.config.tiers?.length ?? 0) > 1 ? props.renderTiers?.(tierSelection) ?? TierPlaceholder(tierSelection) : null,
|
|
2334
2680
|
typeof props.children === "function" ? props.children({ invitation }) : props.children,
|
|
2335
|
-
error ? /* @__PURE__ */
|
|
2336
|
-
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */
|
|
2681
|
+
error ? /* @__PURE__ */ jsx30("p", { className: "join-error", role: "alert", children: error }) : null,
|
|
2682
|
+
props.renderSubmit?.({ submitting, disabled }) ?? /* @__PURE__ */ jsx30(JoinSubmitButton, { disabled, children: submitting ? copy.form.submitting : copy.form.submit })
|
|
2337
2683
|
] });
|
|
2338
2684
|
}
|
|
2339
2685
|
|
|
@@ -2358,8 +2704,8 @@ function joinStateFromApplicationResponse(data, fallbackNeedsPayment, submittedG
|
|
|
2358
2704
|
|
|
2359
2705
|
// src/ui/gift-code-redeemer.tsx
|
|
2360
2706
|
import { InlineActionField } from "@odla-ai/ui/components";
|
|
2361
|
-
import { useState as
|
|
2362
|
-
import { Fragment as
|
|
2707
|
+
import { useState as useState22 } from "preact/hooks";
|
|
2708
|
+
import { Fragment as Fragment13, jsx as jsx31, jsxs as jsxs28 } from "preact/jsx-runtime";
|
|
2363
2709
|
var GIFT_CODE_REDEEMER_CSS = `
|
|
2364
2710
|
.gift-code-redeemer{container-type:inline-size;display:grid;gap:var(--ui-space-1,.35rem);margin:0}
|
|
2365
2711
|
.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}
|
|
@@ -2374,10 +2720,10 @@ var GIFT_CODE_REDEEMER_CSS = `
|
|
|
2374
2720
|
@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%}}
|
|
2375
2721
|
`;
|
|
2376
2722
|
function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
2377
|
-
const [code, setCode] =
|
|
2378
|
-
const [loading, setLoading] =
|
|
2379
|
-
const [message, setMessage] =
|
|
2380
|
-
const [messageTone, setMessageTone] =
|
|
2723
|
+
const [code, setCode] = useState22("");
|
|
2724
|
+
const [loading, setLoading] = useState22(false);
|
|
2725
|
+
const [message, setMessage] = useState22("");
|
|
2726
|
+
const [messageTone, setMessageTone] = useState22("neutral");
|
|
2381
2727
|
const normalizedCode = code.trim();
|
|
2382
2728
|
const redeem = async () => {
|
|
2383
2729
|
if (!normalizedCode || loading) return;
|
|
@@ -2404,9 +2750,9 @@ function GiftCodeRedeemer({ api, applicationId, copy, id, onRedeemed }) {
|
|
|
2404
2750
|
setLoading(false);
|
|
2405
2751
|
}
|
|
2406
2752
|
};
|
|
2407
|
-
return /* @__PURE__ */
|
|
2408
|
-
/* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */
|
|
2753
|
+
return /* @__PURE__ */ jsxs28(Fragment13, { children: [
|
|
2754
|
+
/* @__PURE__ */ jsx31("style", { children: GIFT_CODE_REDEEMER_CSS }),
|
|
2755
|
+
/* @__PURE__ */ jsx31(
|
|
2410
2756
|
InlineActionField,
|
|
2411
2757
|
{
|
|
2412
2758
|
id,
|
|
@@ -2462,12 +2808,12 @@ async function loadJoinResume(applicationId, fetcher = fetch) {
|
|
|
2462
2808
|
}
|
|
2463
2809
|
|
|
2464
2810
|
// src/ui/join-gift-claim.tsx
|
|
2465
|
-
import { jsx as
|
|
2811
|
+
import { jsx as jsx32, jsxs as jsxs29 } from "preact/jsx-runtime";
|
|
2466
2812
|
function JoinGiftClaim(props) {
|
|
2467
|
-
return /* @__PURE__ */
|
|
2468
|
-
/* @__PURE__ */
|
|
2469
|
-
/* @__PURE__ */
|
|
2470
|
-
/* @__PURE__ */
|
|
2813
|
+
return /* @__PURE__ */ jsxs29("section", { className: "join-gift-claim card", children: [
|
|
2814
|
+
/* @__PURE__ */ jsx32("div", { className: "card-label", children: props.copy.claimTitle }),
|
|
2815
|
+
/* @__PURE__ */ jsx32("p", { children: props.copy.claimBody }),
|
|
2816
|
+
/* @__PURE__ */ jsx32(
|
|
2471
2817
|
GiftCodeRedeemer,
|
|
2472
2818
|
{
|
|
2473
2819
|
api: props.api,
|
|
@@ -2491,21 +2837,21 @@ function JoinGiftClaim(props) {
|
|
|
2491
2837
|
}
|
|
2492
2838
|
|
|
2493
2839
|
// src/ui/join-named-seat.tsx
|
|
2494
|
-
import { useState as
|
|
2495
|
-
import { jsx as
|
|
2840
|
+
import { useState as useState23 } from "preact/hooks";
|
|
2841
|
+
import { jsx as jsx33, jsxs as jsxs30 } from "preact/jsx-runtime";
|
|
2496
2842
|
function JoinNamedSeat(props) {
|
|
2497
2843
|
const seatId = props.seatId ?? "";
|
|
2498
2844
|
const inherited = useChapterCopy(), copy = props.copy ?? inherited.join.namedSeat;
|
|
2499
|
-
const [accepted, setAccepted] =
|
|
2500
|
-
return /* @__PURE__ */
|
|
2501
|
-
/* @__PURE__ */
|
|
2502
|
-
/* @__PURE__ */
|
|
2503
|
-
/* @__PURE__ */
|
|
2504
|
-
/* @__PURE__ */
|
|
2505
|
-
/* @__PURE__ */
|
|
2845
|
+
const [accepted, setAccepted] = useState23(false), [busy, setBusy] = useState23(false), [error, setError] = useState23("");
|
|
2846
|
+
return /* @__PURE__ */ jsxs30("section", { className: "join-named-seat card", children: [
|
|
2847
|
+
/* @__PURE__ */ jsx33("h2", { children: copy.title }),
|
|
2848
|
+
/* @__PURE__ */ jsx33("p", { children: copy.body }),
|
|
2849
|
+
/* @__PURE__ */ jsxs30("label", { className: "journey-consent", children: [
|
|
2850
|
+
/* @__PURE__ */ jsx33("input", { type: "checkbox", checked: accepted, disabled: busy, onChange: (event) => setAccepted(event.currentTarget.checked) }),
|
|
2851
|
+
/* @__PURE__ */ jsx33("span", { children: copy.consent })
|
|
2506
2852
|
] }),
|
|
2507
|
-
error ? /* @__PURE__ */
|
|
2508
|
-
/* @__PURE__ */
|
|
2853
|
+
error ? /* @__PURE__ */ jsx33("p", { role: "alert", children: error }) : null,
|
|
2854
|
+
/* @__PURE__ */ jsx33("button", { type: "button", className: "btn btn-primary", disabled: busy || !accepted || !seatId.trim(), onClick: async () => {
|
|
2509
2855
|
setBusy(true);
|
|
2510
2856
|
setError("");
|
|
2511
2857
|
try {
|
|
@@ -2525,13 +2871,13 @@ function JoinNamedSeat(props) {
|
|
|
2525
2871
|
}
|
|
2526
2872
|
|
|
2527
2873
|
// src/ui/join-invitation.tsx
|
|
2528
|
-
import { useEffect as
|
|
2529
|
-
import { jsx as
|
|
2874
|
+
import { useEffect as useEffect13, useState as useState24 } from "preact/hooks";
|
|
2875
|
+
import { jsx as jsx34, jsxs as jsxs31 } from "preact/jsx-runtime";
|
|
2530
2876
|
function useJoinInvitation(seatId, api, fallback) {
|
|
2531
|
-
const [invitation, setInvitation] =
|
|
2532
|
-
const [error, setError] =
|
|
2533
|
-
const [revision, setRevision] =
|
|
2534
|
-
|
|
2877
|
+
const [invitation, setInvitation] = useState24(null);
|
|
2878
|
+
const [error, setError] = useState24("");
|
|
2879
|
+
const [revision, setRevision] = useState24(0);
|
|
2880
|
+
useEffect13(() => {
|
|
2535
2881
|
let live = true;
|
|
2536
2882
|
setInvitation(null);
|
|
2537
2883
|
setError("");
|
|
@@ -2553,9 +2899,9 @@ function useJoinInvitation(seatId, api, fallback) {
|
|
|
2553
2899
|
return { invitation: invitation?.seatId === seatId ? invitation : null, error, retry: () => setRevision((value) => value + 1) };
|
|
2554
2900
|
}
|
|
2555
2901
|
function JoinInvitationNotice(props) {
|
|
2556
|
-
return /* @__PURE__ */
|
|
2557
|
-
/* @__PURE__ */
|
|
2558
|
-
/* @__PURE__ */
|
|
2902
|
+
return /* @__PURE__ */ jsxs31("aside", { className: "journey-invitation", "aria-label": props.copy.title, children: [
|
|
2903
|
+
/* @__PURE__ */ jsx34("p", { children: /* @__PURE__ */ jsx34("strong", { children: formatChapterCopy(props.copy.from, { purchaserName: props.invitation.purchaserName }) }) }),
|
|
2904
|
+
/* @__PURE__ */ jsx34("p", { children: formatChapterCopy(props.copy.prepaid, { tierName: props.tierName }) })
|
|
2559
2905
|
] });
|
|
2560
2906
|
}
|
|
2561
2907
|
|
|
@@ -2570,9 +2916,9 @@ function joinSimulationPayment(simulation, priceCents) {
|
|
|
2570
2916
|
}
|
|
2571
2917
|
|
|
2572
2918
|
// src/ui/join-pending.ts
|
|
2573
|
-
import { useEffect as
|
|
2919
|
+
import { useEffect as useEffect14 } from "preact/hooks";
|
|
2574
2920
|
function useJoinPending(state, loadResume, setState) {
|
|
2575
|
-
|
|
2921
|
+
useEffect14(() => {
|
|
2576
2922
|
if (state.step !== "paymentPending") return;
|
|
2577
2923
|
let live = true;
|
|
2578
2924
|
let timer;
|
|
@@ -2595,16 +2941,16 @@ function useJoinPending(state, loadResume, setState) {
|
|
|
2595
2941
|
}
|
|
2596
2942
|
|
|
2597
2943
|
// src/ui/payment-receipt.tsx
|
|
2598
|
-
import { useEffect as
|
|
2599
|
-
import { Fragment as
|
|
2944
|
+
import { useEffect as useEffect15, useState as useState25 } from "preact/hooks";
|
|
2945
|
+
import { Fragment as Fragment14, jsx as jsx35, jsxs as jsxs32 } from "preact/jsx-runtime";
|
|
2600
2946
|
function PaymentReceiptCard({ applicationId }) {
|
|
2601
|
-
const [receipt, setReceipt] =
|
|
2602
|
-
const [error, setError] =
|
|
2603
|
-
const [revision, setRevision] =
|
|
2604
|
-
const [emailState, setEmailState] =
|
|
2605
|
-
const [previewEmail, setPreviewEmail] =
|
|
2947
|
+
const [receipt, setReceipt] = useState25(null);
|
|
2948
|
+
const [error, setError] = useState25("");
|
|
2949
|
+
const [revision, setRevision] = useState25(0);
|
|
2950
|
+
const [emailState, setEmailState] = useState25("idle");
|
|
2951
|
+
const [previewEmail, setPreviewEmail] = useState25(false);
|
|
2606
2952
|
const endpoint = `/api/payments/receipt?application=${encodeURIComponent(applicationId)}`;
|
|
2607
|
-
|
|
2953
|
+
useEffect15(() => {
|
|
2608
2954
|
let live = true, timer;
|
|
2609
2955
|
setReceipt(null);
|
|
2610
2956
|
setError("");
|
|
@@ -2630,9 +2976,9 @@ function PaymentReceiptCard({ applicationId }) {
|
|
|
2630
2976
|
if (timer) clearTimeout(timer);
|
|
2631
2977
|
};
|
|
2632
2978
|
}, [endpoint, revision]);
|
|
2633
|
-
if (!receipt) return error ? /* @__PURE__ */
|
|
2634
|
-
/* @__PURE__ */
|
|
2635
|
-
/* @__PURE__ */
|
|
2979
|
+
if (!receipt) return error ? /* @__PURE__ */ jsxs32("section", { "aria-label": "Payment receipt", children: [
|
|
2980
|
+
/* @__PURE__ */ jsx35("p", { role: "status", children: error }),
|
|
2981
|
+
/* @__PURE__ */ jsx35("button", { type: "button", onClick: () => setRevision((value) => value + 1), children: "Reload receipt" })
|
|
2636
2982
|
] }) : null;
|
|
2637
2983
|
const money = (cents) => new Intl.NumberFormat("en-US", { style: "currency", currency: receipt.currency }).format(cents / 100);
|
|
2638
2984
|
const email = async () => {
|
|
@@ -2649,38 +2995,38 @@ function PaymentReceiptCard({ applicationId }) {
|
|
|
2649
2995
|
setError("We could not confirm email delivery. You can print or save your receipt.");
|
|
2650
2996
|
}
|
|
2651
2997
|
};
|
|
2652
|
-
return /* @__PURE__ */
|
|
2653
|
-
/* @__PURE__ */
|
|
2654
|
-
/* @__PURE__ */
|
|
2655
|
-
/* @__PURE__ */
|
|
2656
|
-
/* @__PURE__ */
|
|
2657
|
-
/* @__PURE__ */
|
|
2658
|
-
receipt.namedSeat ? /* @__PURE__ */
|
|
2659
|
-
/* @__PURE__ */
|
|
2998
|
+
return /* @__PURE__ */ jsxs32("section", { className: "payment-receipt card", "aria-label": "Payment receipt", children: [
|
|
2999
|
+
/* @__PURE__ */ jsx35("h2", { children: "Payment received" }),
|
|
3000
|
+
/* @__PURE__ */ jsx35("p", { children: receipt.tierName }),
|
|
3001
|
+
/* @__PURE__ */ jsxs32("dl", { className: "journey-summary", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx35("dt", { children: "Membership" }),
|
|
3003
|
+
/* @__PURE__ */ jsx35("dd", { children: money(receipt.membershipCents) }),
|
|
3004
|
+
receipt.namedSeat ? /* @__PURE__ */ jsxs32(Fragment14, { children: [
|
|
3005
|
+
/* @__PURE__ */ jsxs32("dt", { children: [
|
|
2660
3006
|
"Additional member \u2014 ",
|
|
2661
3007
|
receipt.namedSeat.recipientName
|
|
2662
3008
|
] }),
|
|
2663
|
-
/* @__PURE__ */
|
|
3009
|
+
/* @__PURE__ */ jsxs32("dd", { children: [
|
|
2664
3010
|
receipt.namedSeat.amountCents === 0 ? "Included \u2014 " : "",
|
|
2665
3011
|
money(receipt.namedSeat.amountCents)
|
|
2666
3012
|
] })
|
|
2667
3013
|
] }) : null,
|
|
2668
|
-
/* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
3014
|
+
/* @__PURE__ */ jsx35("dt", { children: "Total paid" }),
|
|
3015
|
+
/* @__PURE__ */ jsx35("dd", { children: money(receipt.totalCents) })
|
|
2670
3016
|
] }),
|
|
2671
|
-
/* @__PURE__ */
|
|
2672
|
-
/* @__PURE__ */
|
|
2673
|
-
/* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsxs32("div", { className: "journey-actions", children: [
|
|
3018
|
+
/* @__PURE__ */ jsx35("a", { className: "apply-link journey-secondary", href: `${endpoint}&format=html`, target: "_blank", rel: "noopener noreferrer", children: "Print / save receipt" }),
|
|
3019
|
+
/* @__PURE__ */ jsx35("button", { type: "button", disabled: emailState !== "idle", onClick: () => void email(), children: emailState === "sending" ? "Sending\u2026" : emailState === "sent" ? "Receipt emailed" : "Email me my receipt" })
|
|
2674
3020
|
] }),
|
|
2675
|
-
emailState === "sent" ? /* @__PURE__ */
|
|
2676
|
-
error ? /* @__PURE__ */
|
|
3021
|
+
emailState === "sent" ? /* @__PURE__ */ jsx35("p", { role: "status", children: previewEmail ? "Test receipt sent to the configured test inbox." : "Sent to the email used for your payment." }) : null,
|
|
3022
|
+
error ? /* @__PURE__ */ jsx35("p", { role: "alert", children: error }) : null
|
|
2677
3023
|
] });
|
|
2678
3024
|
}
|
|
2679
3025
|
|
|
2680
3026
|
// src/ui/join.tsx
|
|
2681
|
-
import { Fragment as
|
|
3027
|
+
import { Fragment as Fragment15, jsx as jsx36, jsxs as jsxs33 } from "preact/jsx-runtime";
|
|
2682
3028
|
function JoinIsland(props) {
|
|
2683
|
-
return /* @__PURE__ */
|
|
3029
|
+
return /* @__PURE__ */ jsx36(JourneyFrame, { children: /* @__PURE__ */ jsx36(JoinFlow, { ...props }) });
|
|
2684
3030
|
}
|
|
2685
3031
|
function JoinFlow(props) {
|
|
2686
3032
|
const inheritedCopy = useChapterCopy();
|
|
@@ -2701,16 +3047,16 @@ function JoinFlow(props) {
|
|
|
2701
3047
|
const invitation = invitationState.invitation;
|
|
2702
3048
|
const selectedTierId = invitation?.skuId ?? tierSelection.selectedTierId;
|
|
2703
3049
|
const selectedTier = tiers.find((tier) => tier.id === selectedTierId) ?? tierSelection.selected;
|
|
2704
|
-
const [state, setState] =
|
|
2705
|
-
const [error, setError] =
|
|
2706
|
-
const [submitting, setSubmitting] =
|
|
2707
|
-
const [editingNamedSeat, setEditingNamedSeat] =
|
|
2708
|
-
const [giftOfferId, setGiftOfferId] =
|
|
3050
|
+
const [state, setState] = useState26(requestedSeat ? { step: "form" } : props.initialState ?? { step: "form" });
|
|
3051
|
+
const [error, setError] = useState26(null);
|
|
3052
|
+
const [submitting, setSubmitting] = useState26(false);
|
|
3053
|
+
const [editingNamedSeat, setEditingNamedSeat] = useState26(false);
|
|
3054
|
+
const [giftOfferId, setGiftOfferId] = useState26(props.initialGiftOfferId ?? null);
|
|
2709
3055
|
const simulatedPayment = joinSimulationPayment(props.simulation, selectedTier?.priceCents ?? 0);
|
|
2710
3056
|
const simulatedBooking = props.simulation ? props.simulation.booking ?? { slots: [], timezone: "UTC" } : void 0;
|
|
2711
3057
|
const submissionId = useRef8(null);
|
|
2712
3058
|
const slotsPreload = useJoinSlotsPreload(!props.simulation && ["payment", "paymentPending"].includes(state.step));
|
|
2713
|
-
|
|
3059
|
+
useEffect16(() => {
|
|
2714
3060
|
if (props.simulation) return;
|
|
2715
3061
|
const resolver = requestedSeat ? () => invitation?.applicationId ? loadJoinResume(invitation.applicationId) : Promise.resolve(null) : props.loadResume ?? (() => {
|
|
2716
3062
|
if (typeof window === "undefined") return Promise.resolve(null);
|
|
@@ -2739,7 +3085,7 @@ function JoinFlow(props) {
|
|
|
2739
3085
|
setError(null);
|
|
2740
3086
|
try {
|
|
2741
3087
|
const fields = collectFormFields(new FormData(e.currentTarget));
|
|
2742
|
-
fields
|
|
3088
|
+
Object.assign(fields, { submissionId: submissionId.current ??= crypto.randomUUID() }, invitation ? {} : referralFromLocation());
|
|
2743
3089
|
if (invitation) {
|
|
2744
3090
|
fields.namedSeatId = invitation.seatId;
|
|
2745
3091
|
fields.tierId = invitation.skuId;
|
|
@@ -2783,13 +3129,13 @@ function JoinFlow(props) {
|
|
|
2783
3129
|
setSubmitting(false);
|
|
2784
3130
|
}
|
|
2785
3131
|
};
|
|
2786
|
-
if (requestedSeat && !invitation) return /* @__PURE__ */
|
|
2787
|
-
/* @__PURE__ */
|
|
2788
|
-
/* @__PURE__ */
|
|
2789
|
-
invitationState.error ? /* @__PURE__ */
|
|
3132
|
+
if (requestedSeat && !invitation) return /* @__PURE__ */ jsxs33("section", { className: "card", "aria-live": "polite", children: [
|
|
3133
|
+
/* @__PURE__ */ jsx36("h2", { children: seatCopy.title }),
|
|
3134
|
+
/* @__PURE__ */ jsx36("p", { role: invitationState.error ? "alert" : "status", children: invitationState.error || seatCopy.loading }),
|
|
3135
|
+
invitationState.error ? /* @__PURE__ */ jsx36("button", { type: "button", onClick: invitationState.retry, children: seatCopy.retry }) : null
|
|
2790
3136
|
] });
|
|
2791
|
-
const header = /* @__PURE__ */
|
|
2792
|
-
invitation ? /* @__PURE__ */
|
|
3137
|
+
const header = /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
3138
|
+
invitation ? /* @__PURE__ */ jsx36(
|
|
2793
3139
|
JoinInvitationNotice,
|
|
2794
3140
|
{
|
|
2795
3141
|
invitation,
|
|
@@ -2804,49 +3150,49 @@ function JoinFlow(props) {
|
|
|
2804
3150
|
..."applicationId" in state ? { applicationId: state.applicationId } : {}
|
|
2805
3151
|
})
|
|
2806
3152
|
] });
|
|
2807
|
-
const receipt = !props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */
|
|
3153
|
+
const receipt = !props.simulation && !requestedSeat && ["paymentPending", "booking", "accepted", "done"].includes(state.step) && "applicationId" in state ? /* @__PURE__ */ jsx36(PaymentReceiptCard, { applicationId: state.applicationId }) : null;
|
|
2808
3154
|
if (state.step === "closed") {
|
|
2809
|
-
return /* @__PURE__ */
|
|
3155
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2810
3156
|
header,
|
|
2811
|
-
/* @__PURE__ */
|
|
2812
|
-
/* @__PURE__ */
|
|
2813
|
-
/* @__PURE__ */
|
|
2814
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsxs33("section", { className: "card", "aria-label": "Application closed", children: [
|
|
3158
|
+
/* @__PURE__ */ jsx36("h2", { children: "This application is closed" }),
|
|
3159
|
+
/* @__PURE__ */ jsx36("p", { children: "This link cannot resume payment or booking. Sign in to view your application status, or contact the chapter if you need help." }),
|
|
3160
|
+
/* @__PURE__ */ jsx36("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
2815
3161
|
] })
|
|
2816
3162
|
] });
|
|
2817
3163
|
}
|
|
2818
3164
|
if (state.step === "done") {
|
|
2819
|
-
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
2820
|
-
/* @__PURE__ */
|
|
2821
|
-
/* @__PURE__ */
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
3165
|
+
const body = renderDone?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsxs33("div", { className: "join-done card", children: [
|
|
3166
|
+
/* @__PURE__ */ jsx36("div", { className: "card-label", children: copy.done.label }),
|
|
3167
|
+
/* @__PURE__ */ jsx36("p", { className: "meeting-date", children: fullLabel(state.booked.startAt, state.booked.timezone) }),
|
|
3168
|
+
/* @__PURE__ */ jsx36("p", { className: "meeting-note", children: copy.done.calendarInvite }),
|
|
3169
|
+
/* @__PURE__ */ jsx36("a", { className: "apply-link", href: membersHref, children: copy.done.memberArea })
|
|
2824
3170
|
] });
|
|
2825
|
-
return /* @__PURE__ */
|
|
3171
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2826
3172
|
header,
|
|
2827
3173
|
body,
|
|
2828
3174
|
receipt
|
|
2829
3175
|
] });
|
|
2830
3176
|
}
|
|
2831
3177
|
if (state.step === "accepted") {
|
|
2832
|
-
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */
|
|
2833
|
-
return /* @__PURE__ */
|
|
3178
|
+
const body = renderAccepted?.({ ...state, membersHref }) ?? /* @__PURE__ */ jsx36(JoinAccepted, { copy, membersHref });
|
|
3179
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2834
3180
|
header,
|
|
2835
3181
|
body,
|
|
2836
3182
|
receipt
|
|
2837
3183
|
] });
|
|
2838
3184
|
}
|
|
2839
3185
|
if (state.step === "gift") {
|
|
2840
|
-
const body = renderGift?.(state) ?? /* @__PURE__ */
|
|
2841
|
-
return /* @__PURE__ */
|
|
3186
|
+
const body = renderGift?.(state) ?? /* @__PURE__ */ jsx36(GiftClaimCard, { applicationId: state.applicationId, claimId: state.claimId, initialCode: state.code, copy: copy.gift });
|
|
3187
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2842
3188
|
header,
|
|
2843
3189
|
body
|
|
2844
3190
|
] });
|
|
2845
3191
|
}
|
|
2846
3192
|
if (state.step === "booking") {
|
|
2847
|
-
return /* @__PURE__ */
|
|
3193
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2848
3194
|
header,
|
|
2849
|
-
/* @__PURE__ */
|
|
3195
|
+
/* @__PURE__ */ jsx36(
|
|
2850
3196
|
JoinBooking,
|
|
2851
3197
|
{
|
|
2852
3198
|
applicationId: state.applicationId,
|
|
@@ -2863,9 +3209,9 @@ function JoinFlow(props) {
|
|
|
2863
3209
|
}
|
|
2864
3210
|
if (state.step === "payment") {
|
|
2865
3211
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation && !state.giftPurchase) {
|
|
2866
|
-
return /* @__PURE__ */
|
|
3212
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2867
3213
|
header,
|
|
2868
|
-
/* @__PURE__ */
|
|
3214
|
+
/* @__PURE__ */ jsx36(
|
|
2869
3215
|
JoinNamedSeat,
|
|
2870
3216
|
{
|
|
2871
3217
|
api: props.namedSeatClaimApi,
|
|
@@ -2878,9 +3224,9 @@ function JoinFlow(props) {
|
|
|
2878
3224
|
] });
|
|
2879
3225
|
}
|
|
2880
3226
|
const Payment = state.giftPurchase || props.simulation ? PaymentStep : MembershipPaymentStep;
|
|
2881
|
-
return /* @__PURE__ */
|
|
3227
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2882
3228
|
header,
|
|
2883
|
-
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */
|
|
3229
|
+
props.giftClaimApi && !state.giftPurchase ? /* @__PURE__ */ jsx36(
|
|
2884
3230
|
JoinGiftClaim,
|
|
2885
3231
|
{
|
|
2886
3232
|
api: props.giftClaimApi,
|
|
@@ -2891,7 +3237,7 @@ function JoinFlow(props) {
|
|
|
2891
3237
|
onError: () => setError(copy.form.unexpectedFailure)
|
|
2892
3238
|
}
|
|
2893
3239
|
) : null,
|
|
2894
|
-
/* @__PURE__ */
|
|
3240
|
+
/* @__PURE__ */ jsx36(
|
|
2895
3241
|
Payment,
|
|
2896
3242
|
{
|
|
2897
3243
|
applicationId: state.applicationId,
|
|
@@ -2919,9 +3265,9 @@ function JoinFlow(props) {
|
|
|
2919
3265
|
}
|
|
2920
3266
|
if (state.step === "paymentPending") {
|
|
2921
3267
|
if (props.namedSeatClaimApi && props.initialNamedSeatId && !props.simulation) {
|
|
2922
|
-
return /* @__PURE__ */
|
|
3268
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2923
3269
|
header,
|
|
2924
|
-
/* @__PURE__ */
|
|
3270
|
+
/* @__PURE__ */ jsx36(
|
|
2925
3271
|
JoinNamedSeat,
|
|
2926
3272
|
{
|
|
2927
3273
|
api: props.namedSeatClaimApi,
|
|
@@ -2933,15 +3279,15 @@ function JoinFlow(props) {
|
|
|
2933
3279
|
)
|
|
2934
3280
|
] });
|
|
2935
3281
|
}
|
|
2936
|
-
return /* @__PURE__ */
|
|
3282
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2937
3283
|
header,
|
|
2938
|
-
/* @__PURE__ */
|
|
3284
|
+
/* @__PURE__ */ jsx36("p", { className: "pay-status", role: "status", children: copy.payment.pending }),
|
|
2939
3285
|
receipt
|
|
2940
3286
|
] });
|
|
2941
3287
|
}
|
|
2942
|
-
return /* @__PURE__ */
|
|
3288
|
+
return /* @__PURE__ */ jsxs33(Fragment15, { children: [
|
|
2943
3289
|
header,
|
|
2944
|
-
/* @__PURE__ */
|
|
3290
|
+
/* @__PURE__ */ jsx36(
|
|
2945
3291
|
JoinApplicationForm,
|
|
2946
3292
|
{
|
|
2947
3293
|
props,
|
|
@@ -2960,7 +3306,7 @@ function JoinFlow(props) {
|
|
|
2960
3306
|
}
|
|
2961
3307
|
|
|
2962
3308
|
// src/ui/membership-cards.tsx
|
|
2963
|
-
import { Markdown as
|
|
3309
|
+
import { Markdown as Markdown4 } from "@odla-ai/ui/components";
|
|
2964
3310
|
|
|
2965
3311
|
// src/membership-page.ts
|
|
2966
3312
|
var MEMBERSHIP_PAGE_RENDERER = "membership-cards-v1";
|
|
@@ -3131,7 +3477,7 @@ function membershipPageDocument(input, options = {}) {
|
|
|
3131
3477
|
}
|
|
3132
3478
|
|
|
3133
3479
|
// src/ui/membership-cards.tsx
|
|
3134
|
-
import { jsx as
|
|
3480
|
+
import { jsx as jsx37, jsxs as jsxs34 } from "preact/jsx-runtime";
|
|
3135
3481
|
var MEMBERSHIP_CARD_TOKEN_DEFAULTS = Object.freeze({
|
|
3136
3482
|
"--ui-membership-grid-gap": "1.4rem",
|
|
3137
3483
|
"--ui-membership-card-padding": "2rem 1.7rem 1.8rem",
|
|
@@ -3200,79 +3546,71 @@ function membershipApplicationHref(applicationPath, tierId) {
|
|
|
3200
3546
|
}
|
|
3201
3547
|
function TierAction(props) {
|
|
3202
3548
|
if (props.mode === "select") {
|
|
3203
|
-
return /* @__PURE__ */
|
|
3549
|
+
return /* @__PURE__ */ jsxs34("button", { type: "button", className: "chapter-membership-action", "aria-current": props.selected ? "true" : void 0, onClick: () => props.onSelectTier?.(props.tierId), children: [
|
|
3204
3550
|
props.label,
|
|
3205
|
-
/* @__PURE__ */
|
|
3551
|
+
/* @__PURE__ */ jsx37("span", { "aria-hidden": "true", children: "\u2192" })
|
|
3206
3552
|
] });
|
|
3207
3553
|
}
|
|
3208
3554
|
if (props.mode === "preview") {
|
|
3209
|
-
return /* @__PURE__ */
|
|
3555
|
+
return /* @__PURE__ */ jsxs34("span", { className: "chapter-membership-action", "aria-disabled": "true", children: [
|
|
3210
3556
|
props.label,
|
|
3211
|
-
/* @__PURE__ */
|
|
3557
|
+
/* @__PURE__ */ jsx37("span", { "aria-hidden": "true", children: "\u2192" })
|
|
3212
3558
|
] });
|
|
3213
3559
|
}
|
|
3214
|
-
return /* @__PURE__ */
|
|
3560
|
+
return /* @__PURE__ */ jsxs34("a", { className: "chapter-membership-action", href: membershipApplicationHref(props.applicationPath, props.tierId), children: [
|
|
3215
3561
|
props.label,
|
|
3216
|
-
/* @__PURE__ */
|
|
3562
|
+
/* @__PURE__ */ jsx37("span", { "aria-hidden": "true", children: "\u2192" })
|
|
3217
3563
|
] });
|
|
3218
3564
|
}
|
|
3219
3565
|
function TierCard(props) {
|
|
3220
3566
|
const { tier, presentation } = props;
|
|
3221
3567
|
const summary = presentation.summaryMarkdown ?? tier.blurb;
|
|
3222
3568
|
const action = presentation.ctaLabel ?? (tier.free ? "Join for free" : `Choose ${tier.name}`);
|
|
3223
|
-
return /* @__PURE__ */
|
|
3224
|
-
presentation.badge ? /* @__PURE__ */
|
|
3225
|
-
/* @__PURE__ */
|
|
3226
|
-
/* @__PURE__ */
|
|
3227
|
-
presentation.capacity ? /* @__PURE__ */
|
|
3228
|
-
/* @__PURE__ */
|
|
3229
|
-
/* @__PURE__ */
|
|
3569
|
+
return /* @__PURE__ */ jsxs34("article", { className: "chapter-membership-card", "data-tier-id": tier.id, "data-variant": presentation.variant ?? "standard", children: [
|
|
3570
|
+
presentation.badge ? /* @__PURE__ */ jsx37("div", { className: "chapter-membership-badge", children: presentation.badge }) : null,
|
|
3571
|
+
/* @__PURE__ */ jsx37("h3", { className: "chapter-membership-name", children: tier.name }),
|
|
3572
|
+
/* @__PURE__ */ jsxs34("div", { className: "chapter-membership-offer", "data-with-capacity": presentation.capacity ? "true" : void 0, children: [
|
|
3573
|
+
presentation.capacity ? /* @__PURE__ */ jsxs34("div", { className: "chapter-membership-capacity", "aria-label": `${presentation.capacity.total} ${presentation.capacity.label ?? "available"}`, children: [
|
|
3574
|
+
/* @__PURE__ */ jsx37("strong", { children: presentation.capacity.total.toLocaleString("en-US") }),
|
|
3575
|
+
/* @__PURE__ */ jsx37("small", { children: presentation.capacity.label ?? "available" })
|
|
3230
3576
|
] }) : null,
|
|
3231
|
-
/* @__PURE__ */
|
|
3232
|
-
presentation.priceEyebrow ? /* @__PURE__ */
|
|
3233
|
-
/* @__PURE__ */
|
|
3234
|
-
tier.founding ? /* @__PURE__ */
|
|
3235
|
-
/* @__PURE__ */
|
|
3236
|
-
!tier.free && presentation.billingLabel ? /* @__PURE__ */
|
|
3577
|
+
/* @__PURE__ */ jsxs34("div", { className: "chapter-membership-price-stack", children: [
|
|
3578
|
+
presentation.priceEyebrow ? /* @__PURE__ */ jsx37("p", { className: "chapter-membership-price-eyebrow", children: presentation.priceEyebrow }) : tier.founding ? /* @__PURE__ */ jsx37("p", { className: "chapter-membership-price-eyebrow", children: "Founding member rate" }) : null,
|
|
3579
|
+
/* @__PURE__ */ jsxs34("div", { className: "chapter-membership-price-row", children: [
|
|
3580
|
+
tier.founding ? /* @__PURE__ */ jsx37("span", { className: "chapter-membership-compare", children: fmtMoney(tier.priceCents) }) : presentation.compareAtPriceCents !== void 0 ? /* @__PURE__ */ jsx37("span", { className: "chapter-membership-compare", children: fmtMoney(presentation.compareAtPriceCents) }) : null,
|
|
3581
|
+
/* @__PURE__ */ jsx37("span", { className: "chapter-membership-price", children: tier.free ? "Free" : fmtMoney(tier.founding ? tier.founding.dueTodayCents : tier.priceCents) }),
|
|
3582
|
+
!tier.free && presentation.billingLabel ? /* @__PURE__ */ jsx37("span", { className: "chapter-membership-billing", children: presentation.billingLabel }) : null
|
|
3237
3583
|
] })
|
|
3238
3584
|
] })
|
|
3239
3585
|
] }),
|
|
3240
|
-
presentation.priceNoteMarkdown ? /* @__PURE__ */
|
|
3241
|
-
summary ? /* @__PURE__ */
|
|
3242
|
-
presentation.benefits?.length ? /* @__PURE__ */
|
|
3243
|
-
/* @__PURE__ */
|
|
3244
|
-
/* @__PURE__ */
|
|
3586
|
+
presentation.priceNoteMarkdown ? /* @__PURE__ */ jsx37(Markdown4, { className: "chapter-membership-price-note", source: presentation.priceNoteMarkdown }) : null,
|
|
3587
|
+
summary ? /* @__PURE__ */ jsx37(Markdown4, { className: "chapter-membership-summary", source: summary }) : null,
|
|
3588
|
+
presentation.benefits?.length ? /* @__PURE__ */ jsx37("ul", { className: "chapter-membership-benefits", children: presentation.benefits.map((benefit, index) => /* @__PURE__ */ jsxs34("li", { children: [
|
|
3589
|
+
/* @__PURE__ */ jsx37("span", { className: "chapter-membership-check", "aria-hidden": "true", children: "\u2713" }),
|
|
3590
|
+
/* @__PURE__ */ jsx37(Markdown4, { className: "chapter-membership-benefit", source: benefit })
|
|
3245
3591
|
] }, `${tier.id}-benefit-${index}`)) }) : null,
|
|
3246
|
-
presentation.callout ? /* @__PURE__ */
|
|
3247
|
-
presentation.callout.label ? /* @__PURE__ */
|
|
3248
|
-
/* @__PURE__ */
|
|
3592
|
+
presentation.callout ? /* @__PURE__ */ jsxs34("aside", { className: "chapter-membership-callout", children: [
|
|
3593
|
+
presentation.callout.label ? /* @__PURE__ */ jsx37("p", { className: "chapter-membership-callout-label", children: presentation.callout.label }) : null,
|
|
3594
|
+
/* @__PURE__ */ jsx37(Markdown4, { source: presentation.callout.bodyMarkdown })
|
|
3249
3595
|
] }) : null,
|
|
3250
|
-
/* @__PURE__ */
|
|
3596
|
+
/* @__PURE__ */ jsx37(TierAction, { tierId: tier.id, label: action, mode: props.mode, selected: props.selected, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier })
|
|
3251
3597
|
] });
|
|
3252
3598
|
}
|
|
3253
3599
|
function MembershipCards(props) {
|
|
3254
3600
|
const document2 = membershipPageDocument(props.document, { tiers: props.tiers });
|
|
3255
3601
|
const byId = new Map(props.tiers.map((tier) => [tier.id, tier]));
|
|
3256
3602
|
const mode = props.mode ?? "link";
|
|
3257
|
-
return /* @__PURE__ */
|
|
3258
|
-
/* @__PURE__ */
|
|
3259
|
-
/* @__PURE__ */
|
|
3603
|
+
return /* @__PURE__ */ jsxs34("section", { className: ["chapter-membership", props.className].filter(Boolean).join(" "), "data-chapter-membership": MEMBERSHIP_PAGE_RENDERER, "aria-label": props.ariaLabel ?? "Membership options", children: [
|
|
3604
|
+
/* @__PURE__ */ jsx37("style", { children: MEMBERSHIP_CARDS_CSS }),
|
|
3605
|
+
/* @__PURE__ */ jsx37("div", { className: "chapter-membership-grid", style: { "--chapter-membership-columns": String(Math.min(document2.tiers.length, 3)) }, children: document2.tiers.map((presentation) => {
|
|
3260
3606
|
const tier = byId.get(presentation.tierId);
|
|
3261
|
-
return /* @__PURE__ */
|
|
3607
|
+
return /* @__PURE__ */ jsx37(TierCard, { tier, presentation, mode, selected: props.selectedTierId === tier.id, applicationPath: props.applicationPath, onSelectTier: props.onSelectTier }, tier.id);
|
|
3262
3608
|
}) }),
|
|
3263
|
-
document2.footnoteMarkdown ? /* @__PURE__ */
|
|
3609
|
+
document2.footnoteMarkdown ? /* @__PURE__ */ jsx37(Markdown4, { className: "chapter-membership-footnote", source: document2.footnoteMarkdown }) : null
|
|
3264
3610
|
] });
|
|
3265
3611
|
}
|
|
3266
3612
|
|
|
3267
3613
|
export {
|
|
3268
|
-
tzShort,
|
|
3269
|
-
dayKey,
|
|
3270
|
-
dayLabel,
|
|
3271
|
-
timeLabel,
|
|
3272
|
-
fullLabel,
|
|
3273
|
-
fmtMoney,
|
|
3274
|
-
fmtDate,
|
|
3275
|
-
groupSlotsByDay,
|
|
3276
3614
|
SlotPicker,
|
|
3277
3615
|
ADDITIONAL_MEMBER_COPY,
|
|
3278
3616
|
additionalMemberSelection,
|
|
@@ -3315,9 +3653,30 @@ export {
|
|
|
3315
3653
|
startingPrompts,
|
|
3316
3654
|
choosePrompt,
|
|
3317
3655
|
MemberProfilePage,
|
|
3656
|
+
useCourse,
|
|
3657
|
+
seatLine,
|
|
3658
|
+
SeatActions,
|
|
3659
|
+
CoursePage,
|
|
3660
|
+
CourseHomePanel,
|
|
3661
|
+
articleFor,
|
|
3662
|
+
shareVars,
|
|
3663
|
+
linkedinShareUrl,
|
|
3664
|
+
mailtoHref,
|
|
3665
|
+
smsHref,
|
|
3666
|
+
isIOS,
|
|
3667
|
+
useMemberReferrals,
|
|
3668
|
+
CopyButton,
|
|
3669
|
+
OfficialCard,
|
|
3670
|
+
PostCard,
|
|
3671
|
+
InviteLinkCard,
|
|
3672
|
+
ReferralsCard,
|
|
3673
|
+
SharePage,
|
|
3674
|
+
ShareHome,
|
|
3675
|
+
ProfileReferrals,
|
|
3318
3676
|
PACKAGED_PORTAL_FEATURES,
|
|
3319
3677
|
MemberPortal,
|
|
3320
3678
|
MembersArea,
|
|
3679
|
+
referralFromLocation,
|
|
3321
3680
|
useTierSelection,
|
|
3322
3681
|
TierPlaceholder,
|
|
3323
3682
|
tierNeedsPayment,
|
|
@@ -3328,4 +3687,4 @@ export {
|
|
|
3328
3687
|
membershipApplicationHref,
|
|
3329
3688
|
MembershipCards
|
|
3330
3689
|
};
|
|
3331
|
-
//# sourceMappingURL=chunk-
|
|
3690
|
+
//# sourceMappingURL=chunk-QPFJBHHK.js.map
|