@odla-ai/chapter 0.36.0 → 0.38.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 +136 -2
- package/dist/{chunk-I45VYBUV.js → chunk-BIYWPPH6.js} +233 -140
- package/dist/chunk-BIYWPPH6.js.map +1 -0
- package/dist/{chunk-LWM32REV.js → chunk-SI3JHSEX.js} +211 -64
- package/dist/chunk-SI3JHSEX.js.map +1 -0
- package/dist/{copy-context-0k0-yWHL.d.ts → copy-context-Pbs3keLx.d.ts} +174 -28
- package/dist/index.cjs +807 -345
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +295 -36
- package/dist/index.d.ts +295 -36
- package/dist/index.js +807 -345
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +27 -3
- package/dist/ui/admin/index.js +5 -1
- package/dist/ui/index.d.ts +3 -3
- package/dist/ui/index.js +8 -2
- package/dist/ui/member/index.d.ts +63 -4
- package/dist/ui/member/index.js +3 -1
- package/dist/worker/index.cjs +1032 -354
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +151 -28
- package/dist/worker/index.d.ts +151 -28
- package/dist/worker/index.js +1025 -347
- package/dist/worker/index.js.map +1 -1
- package/package.json +1 -1
- package/runbooks/greenfield.md +27 -0
- package/dist/chunk-I45VYBUV.js.map +0 -1
- package/dist/chunk-LWM32REV.js.map +0 -1
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-IAWBE5PX.js";
|
|
8
8
|
|
|
9
9
|
// src/ui/admin.tsx
|
|
10
|
-
import { useEffect as
|
|
10
|
+
import { useEffect as useEffect10, useMemo as useMemo2, useRef, useState as useState16 } from "preact/hooks";
|
|
11
11
|
import { ClerkGate, SignedIn, SignedOut, SignIn, useClerkAuth } from "@odla-ai/auth-clerk";
|
|
12
12
|
import { CrmClient } from "@odla-ai/crm";
|
|
13
13
|
|
|
@@ -453,7 +453,13 @@ async function adminFetch(getToken, path, init) {
|
|
|
453
453
|
if (init?.body) headers.set("content-type", "application/json");
|
|
454
454
|
const res = await fetch(path, { ...init, headers });
|
|
455
455
|
const body = await res.json().catch(() => ({}));
|
|
456
|
-
if (!res.ok)
|
|
456
|
+
if (!res.ok) {
|
|
457
|
+
const error = new Error(typeof body.error === "string" ? body.error : `request failed (${res.status})`);
|
|
458
|
+
if (Array.isArray(body.errors) && body.errors.every((item) => typeof item === "string")) {
|
|
459
|
+
error.errors = body.errors;
|
|
460
|
+
}
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
457
463
|
return body;
|
|
458
464
|
}
|
|
459
465
|
function useAdminResource(getToken, path) {
|
|
@@ -1765,8 +1771,140 @@ function admissionGrantsWorkspace(label = "Admission") {
|
|
|
1765
1771
|
};
|
|
1766
1772
|
}
|
|
1767
1773
|
|
|
1774
|
+
// src/ui/admin-member-content.tsx
|
|
1775
|
+
import { useEffect as useEffect8, useState as useState14 } from "preact/hooks";
|
|
1776
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "preact/jsx-runtime";
|
|
1777
|
+
var emptyDraft = () => ({ pages: [], upsellOverrides: [] });
|
|
1778
|
+
function accessLabel(page) {
|
|
1779
|
+
return page.audience.kind === "all-members" ? "All members" : `Tiers: ${page.audience.tierIds.join(", ")}`;
|
|
1780
|
+
}
|
|
1781
|
+
function MemberContentAdmin({
|
|
1782
|
+
ctx,
|
|
1783
|
+
initialData
|
|
1784
|
+
}) {
|
|
1785
|
+
const resource = useAdminResource(ctx.getToken, "/api/admin/member-content");
|
|
1786
|
+
const [draft, setDraft] = useState14(JSON.stringify(initialData?.chapter?.document ?? emptyDraft(), null, 2));
|
|
1787
|
+
const [saveError, setSaveError] = useState14(null);
|
|
1788
|
+
const [saving, setSaving] = useState14(false);
|
|
1789
|
+
useEffect8(() => {
|
|
1790
|
+
if (!resource.data) return;
|
|
1791
|
+
setDraft(JSON.stringify(resource.data.chapter?.document ?? emptyDraft(), null, 2));
|
|
1792
|
+
}, [resource.data]);
|
|
1793
|
+
const loaded = initialData ?? resource.data;
|
|
1794
|
+
if (!loaded && resource.loading) return /* @__PURE__ */ jsx19(AdminPage, { children: /* @__PURE__ */ jsx19(AdminNote, { children: "Loading member content\u2026" }) });
|
|
1795
|
+
if (resource.error || !loaded) {
|
|
1796
|
+
return /* @__PURE__ */ jsx19(AdminPage, { children: /* @__PURE__ */ jsxs16(AdminNote, { children: [
|
|
1797
|
+
"Member content could not be loaded: ",
|
|
1798
|
+
resource.error ?? "unknown error"
|
|
1799
|
+
] }) });
|
|
1800
|
+
}
|
|
1801
|
+
const data = loaded;
|
|
1802
|
+
const inherited = data.parent?.document.pages ?? [];
|
|
1803
|
+
const local = data.chapter?.document.pages ?? [];
|
|
1804
|
+
const save = async () => {
|
|
1805
|
+
setSaveError(null);
|
|
1806
|
+
let document2;
|
|
1807
|
+
try {
|
|
1808
|
+
document2 = JSON.parse(draft);
|
|
1809
|
+
} catch (error) {
|
|
1810
|
+
setSaveError([`JSON is invalid: ${error instanceof Error ? error.message : String(error)}`]);
|
|
1811
|
+
return;
|
|
1812
|
+
}
|
|
1813
|
+
setSaving(true);
|
|
1814
|
+
try {
|
|
1815
|
+
await adminFetch(ctx.getToken, "/api/admin/member-content", {
|
|
1816
|
+
method: "PUT",
|
|
1817
|
+
body: JSON.stringify({ expectedRevision: data.chapter?.revision ?? 0, document: document2 })
|
|
1818
|
+
});
|
|
1819
|
+
resource.refresh();
|
|
1820
|
+
} catch (error) {
|
|
1821
|
+
const structured = error;
|
|
1822
|
+
setSaveError(structured.errors ?? [error instanceof Error ? error.message : String(error)]);
|
|
1823
|
+
} finally {
|
|
1824
|
+
setSaving(false);
|
|
1825
|
+
}
|
|
1826
|
+
};
|
|
1827
|
+
return /* @__PURE__ */ jsxs16(AdminPage, { children: [
|
|
1828
|
+
/* @__PURE__ */ jsxs16(Panel, { children: [
|
|
1829
|
+
/* @__PURE__ */ jsx19("div", { className: "card-label", children: "Member content" }),
|
|
1830
|
+
/* @__PURE__ */ jsx19("h2", { children: "One catalog, two clear owners" }),
|
|
1831
|
+
/* @__PURE__ */ jsx19("p", { children: "Parent pages are inherited and read-only here. Chapter pages and delegated upsells are edited in the local document. Access uses exact tier IDs; no tier order is assumed." }),
|
|
1832
|
+
/* @__PURE__ */ jsxs16("div", { className: "stat-band", children: [
|
|
1833
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
1834
|
+
/* @__PURE__ */ jsx19("strong", { children: inherited.length }),
|
|
1835
|
+
/* @__PURE__ */ jsx19("span", { children: "Inherited pages" })
|
|
1836
|
+
] }),
|
|
1837
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
1838
|
+
/* @__PURE__ */ jsx19("strong", { children: local.length }),
|
|
1839
|
+
/* @__PURE__ */ jsx19("span", { children: "Chapter pages" })
|
|
1840
|
+
] }),
|
|
1841
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
1842
|
+
/* @__PURE__ */ jsx19("strong", { children: data.tiers.length }),
|
|
1843
|
+
/* @__PURE__ */ jsx19("span", { children: "Declared tiers" })
|
|
1844
|
+
] })
|
|
1845
|
+
] })
|
|
1846
|
+
] }),
|
|
1847
|
+
/* @__PURE__ */ jsxs16(Panel, { children: [
|
|
1848
|
+
/* @__PURE__ */ jsx19("div", { className: "card-label", children: "Inherited \xB7 read only" }),
|
|
1849
|
+
/* @__PURE__ */ jsxs16("h2", { children: [
|
|
1850
|
+
"Parent pages ",
|
|
1851
|
+
data.parent ? `\xB7 revision ${data.parent.revision}` : ""
|
|
1852
|
+
] }),
|
|
1853
|
+
inherited.length === 0 ? /* @__PURE__ */ jsx19(AdminNote, { children: "No Parent pages have been delivered." }) : /* @__PURE__ */ jsx19("div", { className: "data-list", "data-member-content-inherited": true, children: inherited.map((page) => /* @__PURE__ */ jsxs16("article", { className: "card", children: [
|
|
1854
|
+
/* @__PURE__ */ jsx19("strong", { children: page.title }),
|
|
1855
|
+
/* @__PURE__ */ jsxs16("div", { className: "meeting-note", children: [
|
|
1856
|
+
"/",
|
|
1857
|
+
page.slug,
|
|
1858
|
+
" \xB7 ",
|
|
1859
|
+
page.navigation.section,
|
|
1860
|
+
" \xB7 ",
|
|
1861
|
+
accessLabel(page)
|
|
1862
|
+
] }),
|
|
1863
|
+
/* @__PURE__ */ jsxs16("div", { className: "meeting-note", children: [
|
|
1864
|
+
"Upsell: ",
|
|
1865
|
+
page.upsell ? `${page.upsell.owner} controlled` : "none"
|
|
1866
|
+
] })
|
|
1867
|
+
] }, page.id)) })
|
|
1868
|
+
] }),
|
|
1869
|
+
/* @__PURE__ */ jsxs16(Panel, { children: [
|
|
1870
|
+
/* @__PURE__ */ jsx19("div", { className: "card-label", children: "Chapter \xB7 editable" }),
|
|
1871
|
+
/* @__PURE__ */ jsxs16("h2", { children: [
|
|
1872
|
+
"Local document \xB7 revision ",
|
|
1873
|
+
data.chapter?.revision ?? 0
|
|
1874
|
+
] }),
|
|
1875
|
+
/* @__PURE__ */ jsx19("p", { className: "meeting-note", children: "Use the published MemberContentDocument fields. The server supplies schemaVersion, revision, timestamp, and chapter source; unknown fields and undeclared tiers are rejected." }),
|
|
1876
|
+
/* @__PURE__ */ jsxs16("label", { className: "field", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx19("span", { children: "Pages and delegated upsells (JSON)" }),
|
|
1878
|
+
/* @__PURE__ */ jsx19(
|
|
1879
|
+
"textarea",
|
|
1880
|
+
{
|
|
1881
|
+
rows: 24,
|
|
1882
|
+
value: draft,
|
|
1883
|
+
disabled: !data.localAuthoring || saving,
|
|
1884
|
+
onInput: (event) => setDraft(event.currentTarget.value),
|
|
1885
|
+
spellcheck: false
|
|
1886
|
+
}
|
|
1887
|
+
)
|
|
1888
|
+
] }),
|
|
1889
|
+
saveError ? /* @__PURE__ */ jsxs16("div", { className: "notice danger", role: "alert", children: [
|
|
1890
|
+
/* @__PURE__ */ jsx19("strong", { children: "Fix these items before saving:" }),
|
|
1891
|
+
/* @__PURE__ */ jsx19("ul", { children: saveError.map((error) => /* @__PURE__ */ jsx19("li", { children: error }, error)) })
|
|
1892
|
+
] }) : null,
|
|
1893
|
+
/* @__PURE__ */ jsx19("button", { className: "btn primary", type: "button", disabled: !data.localAuthoring || saving, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save chapter content" }),
|
|
1894
|
+
!data.localAuthoring ? /* @__PURE__ */ jsx19(AdminNote, { children: "Local authoring is disabled in the checked-in Chapter config." }) : null
|
|
1895
|
+
] })
|
|
1896
|
+
] });
|
|
1897
|
+
}
|
|
1898
|
+
function memberContentSection() {
|
|
1899
|
+
return {
|
|
1900
|
+
id: "member-content",
|
|
1901
|
+
label: "Member content",
|
|
1902
|
+
render: (ctx) => /* @__PURE__ */ jsx19(MemberContentAdmin, { ctx })
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1768
1906
|
// src/ui/admin-workspaces.tsx
|
|
1769
|
-
import { jsx as
|
|
1907
|
+
import { jsx as jsx20 } from "preact/jsx-runtime";
|
|
1770
1908
|
var adminViewContext = (ctx, viewId, active) => {
|
|
1771
1909
|
const route = {
|
|
1772
1910
|
workspaceId: ctx.route.workspaceId,
|
|
@@ -1792,7 +1930,7 @@ function DashboardWorkspace({ chapter, ctx }) {
|
|
|
1792
1930
|
const active = ctx.route.viewId === "billing" ? "billing" : "overview";
|
|
1793
1931
|
const overview = dashboardSection({ id: "overview", label: copy.workspaces.overview });
|
|
1794
1932
|
const billing = billingSection({ label: copy.workspaces.billing });
|
|
1795
|
-
return /* @__PURE__ */
|
|
1933
|
+
return /* @__PURE__ */ jsx20(
|
|
1796
1934
|
Tabs2,
|
|
1797
1935
|
{
|
|
1798
1936
|
ariaLabel: copy.workspaces.dashboardViewsLabel,
|
|
@@ -1817,10 +1955,11 @@ function DashboardWorkspace({ chapter, ctx }) {
|
|
|
1817
1955
|
}
|
|
1818
1956
|
function SettingsWorkspace({ chapter, ctx }) {
|
|
1819
1957
|
const copy = chapter.copy.admin;
|
|
1820
|
-
const active = ctx.route.viewId === "email" ? "email" : "calendar";
|
|
1958
|
+
const active = ctx.route.viewId === "email" ? "email" : ctx.route.viewId === "member-content" && chapter.memberContent ? "member-content" : "calendar";
|
|
1821
1959
|
const calendar = availabilitySection({ id: "calendar", label: copy.workspaces.calendar });
|
|
1822
1960
|
const email = emailSection({ label: copy.workspaces.email });
|
|
1823
|
-
|
|
1961
|
+
const content = memberContentSection();
|
|
1962
|
+
return /* @__PURE__ */ jsx20(
|
|
1824
1963
|
Tabs2,
|
|
1825
1964
|
{
|
|
1826
1965
|
ariaLabel: copy.workspaces.settingsViewsLabel,
|
|
@@ -1838,7 +1977,13 @@ function SettingsWorkspace({ chapter, ctx }) {
|
|
|
1838
1977
|
label: copy.workspaces.email,
|
|
1839
1978
|
href: ctx.href({ viewId: "email", recordId: null, detailTab: null }),
|
|
1840
1979
|
panel: email.render(adminViewContext(ctx, "email", active === "email"))
|
|
1841
|
-
}
|
|
1980
|
+
},
|
|
1981
|
+
...chapter.memberContent ? [{
|
|
1982
|
+
value: "member-content",
|
|
1983
|
+
label: "Member content",
|
|
1984
|
+
href: ctx.href({ viewId: "member-content", recordId: null, detailTab: null }),
|
|
1985
|
+
panel: content.render(adminViewContext(ctx, "member-content", active === "member-content"))
|
|
1986
|
+
}] : []
|
|
1842
1987
|
]
|
|
1843
1988
|
}
|
|
1844
1989
|
);
|
|
@@ -1848,7 +1993,7 @@ function PeopleWorkspace({ chapter, ctx }) {
|
|
|
1848
1993
|
const fallback = types[0]?.[0] ?? "person";
|
|
1849
1994
|
const active = types.some(([type]) => type === ctx.route.viewId) ? ctx.route.viewId : fallback;
|
|
1850
1995
|
const networkSharing = chapter.network.targets.length > 0;
|
|
1851
|
-
return /* @__PURE__ */
|
|
1996
|
+
return /* @__PURE__ */ jsx20(
|
|
1852
1997
|
Tabs2,
|
|
1853
1998
|
{
|
|
1854
1999
|
ariaLabel: chapter.copy.admin.workspaces.collectionsLabel,
|
|
@@ -1878,8 +2023,8 @@ function PortfolioWorkspace({ chapter, ctx }) {
|
|
|
1878
2023
|
const types = Object.entries(chapter.crm.config.types).filter(([, def]) => def.workspace === "portfolio");
|
|
1879
2024
|
const fallback = types[0]?.[0] ?? "";
|
|
1880
2025
|
const active = types.some(([type]) => type === ctx.route.viewId) ? ctx.route.viewId : fallback;
|
|
1881
|
-
if (!active) return /* @__PURE__ */
|
|
1882
|
-
return /* @__PURE__ */
|
|
2026
|
+
if (!active) return /* @__PURE__ */ jsx20(LeaderNetworkOverview, { ctx });
|
|
2027
|
+
return /* @__PURE__ */ jsx20(
|
|
1883
2028
|
Tabs2,
|
|
1884
2029
|
{
|
|
1885
2030
|
ariaLabel: copy.workspaces.portfolioViewsLabel,
|
|
@@ -1903,7 +2048,7 @@ function PortfolioWorkspace({ chapter, ctx }) {
|
|
|
1903
2048
|
);
|
|
1904
2049
|
}
|
|
1905
2050
|
function LeaderDashboardWorkspace({ chapter, ctx }) {
|
|
1906
|
-
return /* @__PURE__ */
|
|
2051
|
+
return /* @__PURE__ */ jsx20(
|
|
1907
2052
|
Tabs2,
|
|
1908
2053
|
{
|
|
1909
2054
|
ariaLabel: chapter.copy.admin.workspaces.dashboardViewsLabel,
|
|
@@ -1913,14 +2058,14 @@ function LeaderDashboardWorkspace({ chapter, ctx }) {
|
|
|
1913
2058
|
value: "overview",
|
|
1914
2059
|
label: chapter.copy.admin.workspaces.overview,
|
|
1915
2060
|
href: ctx.href({ viewId: "overview", recordId: null, detailTab: null }),
|
|
1916
|
-
panel: /* @__PURE__ */
|
|
2061
|
+
panel: /* @__PURE__ */ jsx20(LeaderNetworkOverview, { ctx: adminViewContext(ctx, "overview", true) })
|
|
1917
2062
|
}]
|
|
1918
2063
|
}
|
|
1919
2064
|
);
|
|
1920
2065
|
}
|
|
1921
2066
|
function LeaderSettingsWorkspace({ chapter, ctx }) {
|
|
1922
2067
|
const email = emailSection({ label: chapter.copy.admin.workspaces.email });
|
|
1923
|
-
return /* @__PURE__ */
|
|
2068
|
+
return /* @__PURE__ */ jsx20(
|
|
1924
2069
|
Tabs2,
|
|
1925
2070
|
{
|
|
1926
2071
|
ariaLabel: chapter.copy.admin.workspaces.settingsViewsLabel,
|
|
@@ -1941,7 +2086,7 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1941
2086
|
id: "people",
|
|
1942
2087
|
label: copy.workspaces.people,
|
|
1943
2088
|
defaultViewId: Object.keys(chapter.crm.config.types)[0] ?? "person",
|
|
1944
|
-
render: (ctx) => /* @__PURE__ */
|
|
2089
|
+
render: (ctx) => /* @__PURE__ */ jsx20(PeopleWorkspace, { chapter, ctx })
|
|
1945
2090
|
};
|
|
1946
2091
|
if (chapter.mode === "hub" && chapter.network.targets.length === 0) return [people];
|
|
1947
2092
|
if (chapter.mode === "hub") {
|
|
@@ -1951,7 +2096,7 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1951
2096
|
id: "dashboard",
|
|
1952
2097
|
label: copy.workspaces.dashboard,
|
|
1953
2098
|
defaultViewId: "overview",
|
|
1954
|
-
render: (ctx) => /* @__PURE__ */
|
|
2099
|
+
render: (ctx) => /* @__PURE__ */ jsx20(LeaderDashboardWorkspace, { chapter, ctx })
|
|
1955
2100
|
},
|
|
1956
2101
|
networkRecordsWorkspace(chapter),
|
|
1957
2102
|
people,
|
|
@@ -1959,13 +2104,13 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1959
2104
|
id: "portfolio",
|
|
1960
2105
|
label: copy.workspaces.portfolio,
|
|
1961
2106
|
defaultViewId: portfolioTypes[0]?.[0],
|
|
1962
|
-
render: (ctx) => /* @__PURE__ */
|
|
2107
|
+
render: (ctx) => /* @__PURE__ */ jsx20(PortfolioWorkspace, { chapter, ctx })
|
|
1963
2108
|
},
|
|
1964
2109
|
{
|
|
1965
2110
|
id: "settings",
|
|
1966
2111
|
label: copy.workspaces.settings,
|
|
1967
2112
|
defaultViewId: "email",
|
|
1968
|
-
render: (ctx) => /* @__PURE__ */
|
|
2113
|
+
render: (ctx) => /* @__PURE__ */ jsx20(LeaderSettingsWorkspace, { chapter, ctx })
|
|
1969
2114
|
}
|
|
1970
2115
|
];
|
|
1971
2116
|
}
|
|
@@ -1974,7 +2119,7 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1974
2119
|
id: "dashboard",
|
|
1975
2120
|
label: copy.workspaces.dashboard,
|
|
1976
2121
|
defaultViewId: "overview",
|
|
1977
|
-
render: (ctx) => /* @__PURE__ */
|
|
2122
|
+
render: (ctx) => /* @__PURE__ */ jsx20(DashboardWorkspace, { chapter, ctx })
|
|
1978
2123
|
},
|
|
1979
2124
|
people,
|
|
1980
2125
|
admissionGrantsWorkspace(copy.workspaces.admission),
|
|
@@ -1982,17 +2127,17 @@ function defaultAdminWorkspaces(chapter) {
|
|
|
1982
2127
|
id: "settings",
|
|
1983
2128
|
label: copy.workspaces.settings,
|
|
1984
2129
|
defaultViewId: "calendar",
|
|
1985
|
-
render: (ctx) => /* @__PURE__ */
|
|
2130
|
+
render: (ctx) => /* @__PURE__ */ jsx20(SettingsWorkspace, { chapter, ctx })
|
|
1986
2131
|
}
|
|
1987
2132
|
];
|
|
1988
2133
|
}
|
|
1989
2134
|
|
|
1990
2135
|
// src/ui/admin-frame.tsx
|
|
1991
2136
|
import { ThemeScope as ThemeScope2 } from "@odla-ai/ui/components";
|
|
1992
|
-
import { jsx as
|
|
2137
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "preact/jsx-runtime";
|
|
1993
2138
|
function AdminTheme(props) {
|
|
1994
2139
|
const brand = props.chapter?.brand;
|
|
1995
|
-
return /* @__PURE__ */
|
|
2140
|
+
return /* @__PURE__ */ jsx21(ChapterCopyProvider, { copy: props.chapter?.copy, children: /* @__PURE__ */ jsxs17(
|
|
1996
2141
|
ThemeScope2,
|
|
1997
2142
|
{
|
|
1998
2143
|
ref: props.scopeRef,
|
|
@@ -2001,7 +2146,7 @@ function AdminTheme(props) {
|
|
|
2001
2146
|
accent: brand?.accent,
|
|
2002
2147
|
colorScheme: brand?.colorScheme ?? "light",
|
|
2003
2148
|
children: [
|
|
2004
|
-
/* @__PURE__ */
|
|
2149
|
+
/* @__PURE__ */ jsx21(BrandStyle, { brand, selector: "[data-chapter-admin]" }),
|
|
2005
2150
|
props.children
|
|
2006
2151
|
]
|
|
2007
2152
|
}
|
|
@@ -2021,11 +2166,11 @@ function signInRedirect(basePath, workspaces) {
|
|
|
2021
2166
|
}
|
|
2022
2167
|
|
|
2023
2168
|
// src/ui/admin-appearance.ts
|
|
2024
|
-
import { useEffect as
|
|
2169
|
+
import { useEffect as useEffect9, useState as useState15 } from "preact/hooks";
|
|
2025
2170
|
import { clerkAppearanceFromTokens } from "@odla-ai/auth-clerk";
|
|
2026
2171
|
function useScopedClerkAppearance(scope) {
|
|
2027
|
-
const [appearance, setAppearance] =
|
|
2028
|
-
|
|
2172
|
+
const [appearance, setAppearance] = useState15();
|
|
2173
|
+
useEffect9(() => {
|
|
2029
2174
|
setAppearance(clerkAppearanceFromTokens(scope.current ?? void 0));
|
|
2030
2175
|
}, [scope]);
|
|
2031
2176
|
return appearance;
|
|
@@ -2056,7 +2201,7 @@ async function loadChapterAdminUser(adapter, apiBase, getToken) {
|
|
|
2056
2201
|
}
|
|
2057
2202
|
|
|
2058
2203
|
// src/ui/admin.tsx
|
|
2059
|
-
import { jsx as
|
|
2204
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "preact/jsx-runtime";
|
|
2060
2205
|
function Authed(props) {
|
|
2061
2206
|
const copy = useChapterCopy().admin;
|
|
2062
2207
|
const {
|
|
@@ -2083,8 +2228,8 @@ function Authed(props) {
|
|
|
2083
2228
|
}),
|
|
2084
2229
|
[getToken, crmBasePath]
|
|
2085
2230
|
);
|
|
2086
|
-
const [state, setState] =
|
|
2087
|
-
|
|
2231
|
+
const [state, setState] = useState16({ status: "checking" });
|
|
2232
|
+
useEffect10(() => {
|
|
2088
2233
|
let live = true;
|
|
2089
2234
|
void (async () => {
|
|
2090
2235
|
try {
|
|
@@ -2103,17 +2248,17 @@ function Authed(props) {
|
|
|
2103
2248
|
live = false;
|
|
2104
2249
|
};
|
|
2105
2250
|
}, [getToken, apiBase, auth]);
|
|
2106
|
-
if (state.status === "checking") return /* @__PURE__ */
|
|
2251
|
+
if (state.status === "checking") return /* @__PURE__ */ jsx22(Gate, { brand, children: /* @__PURE__ */ jsx22("p", { style: S.muted, children: copy.auth.checking }) });
|
|
2107
2252
|
if (state.status === "denied") {
|
|
2108
|
-
return /* @__PURE__ */
|
|
2109
|
-
/* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */
|
|
2253
|
+
return /* @__PURE__ */ jsx22(Gate, { brand, children: /* @__PURE__ */ jsxs18("div", { className: "card", style: S.card, children: [
|
|
2254
|
+
/* @__PURE__ */ jsx22("h2", { style: { marginTop: 0 }, children: copy.auth.notAuthorized }),
|
|
2255
|
+
/* @__PURE__ */ jsx22("p", { style: S.muted, children: formatChapterCopy(copy.auth.accountNotAuthorized, {
|
|
2111
2256
|
account: state.email ?? copy.auth.thisAccount
|
|
2112
2257
|
}) }),
|
|
2113
|
-
/* @__PURE__ */
|
|
2258
|
+
/* @__PURE__ */ jsx22("button", { className: "btn secondary", onClick: () => signOut(), children: copy.auth.signOut })
|
|
2114
2259
|
] }) });
|
|
2115
2260
|
}
|
|
2116
|
-
return /* @__PURE__ */
|
|
2261
|
+
return /* @__PURE__ */ jsx22(
|
|
2117
2262
|
AdminShell,
|
|
2118
2263
|
{
|
|
2119
2264
|
workspaces,
|
|
@@ -2154,10 +2299,10 @@ function ChapterAdmin(props) {
|
|
|
2154
2299
|
const chrome = props.chrome ?? "embedded";
|
|
2155
2300
|
const auth = props.auth ?? DEFAULT_ADMIN_AUTH;
|
|
2156
2301
|
const redirect = signInRedirect(basePath, workspaces);
|
|
2157
|
-
const [publishableKey, setPublishableKey] =
|
|
2302
|
+
const [publishableKey, setPublishableKey] = useState16(void 0);
|
|
2158
2303
|
const scopeRef = useRef(null);
|
|
2159
2304
|
const appearance = useScopedClerkAppearance(scopeRef);
|
|
2160
|
-
|
|
2305
|
+
useEffect10(() => {
|
|
2161
2306
|
let live = true;
|
|
2162
2307
|
void loadChapterAdminConfig(auth, apiBase).then((config) => live && setPublishableKey(config.publishableKey ?? null)).catch(() => live && setPublishableKey(null));
|
|
2163
2308
|
return () => {
|
|
@@ -2166,23 +2311,23 @@ function ChapterAdmin(props) {
|
|
|
2166
2311
|
}, [apiBase, auth]);
|
|
2167
2312
|
let content;
|
|
2168
2313
|
if (publishableKey === void 0 || publishableKey && !appearance) {
|
|
2169
|
-
content = /* @__PURE__ */
|
|
2314
|
+
content = /* @__PURE__ */ jsx22(Gate, { brand, children: /* @__PURE__ */ jsx22("p", { style: S.muted, children: copy.admin.auth.loading }) });
|
|
2170
2315
|
} else if (!publishableKey) {
|
|
2171
|
-
content = /* @__PURE__ */
|
|
2172
|
-
/* @__PURE__ */
|
|
2173
|
-
/* @__PURE__ */
|
|
2316
|
+
content = /* @__PURE__ */ jsx22(Gate, { brand, children: /* @__PURE__ */ jsxs18("div", { className: "card", style: S.card, children: [
|
|
2317
|
+
/* @__PURE__ */ jsx22("h2", { style: { marginTop: 0 }, children: copy.admin.auth.signInNotConfigured }),
|
|
2318
|
+
/* @__PURE__ */ jsx22("p", { style: S.muted, children: copy.admin.auth.missingPublishableKey })
|
|
2174
2319
|
] }) });
|
|
2175
2320
|
} else if (workspaces.length === 0) {
|
|
2176
|
-
content = /* @__PURE__ */
|
|
2321
|
+
content = /* @__PURE__ */ jsx22(Gate, { brand, children: /* @__PURE__ */ jsx22("p", { style: S.muted, children: copy.admin.auth.noWorkspaces }) });
|
|
2177
2322
|
} else {
|
|
2178
|
-
content = /* @__PURE__ */
|
|
2323
|
+
content = /* @__PURE__ */ jsxs18(
|
|
2179
2324
|
ClerkGate,
|
|
2180
2325
|
{
|
|
2181
2326
|
publishableKey,
|
|
2182
2327
|
appearance,
|
|
2183
2328
|
afterSignOutUrl: "/",
|
|
2184
2329
|
children: [
|
|
2185
|
-
/* @__PURE__ */
|
|
2330
|
+
/* @__PURE__ */ jsx22(SignedOut, { children: /* @__PURE__ */ jsx22(Gate, { brand, tagline: copy.admin.auth.signInTagline, children: /* @__PURE__ */ jsx22(
|
|
2186
2331
|
SignIn,
|
|
2187
2332
|
{
|
|
2188
2333
|
routing: "hash",
|
|
@@ -2190,7 +2335,7 @@ function ChapterAdmin(props) {
|
|
|
2190
2335
|
signUpForceRedirectUrl: redirect
|
|
2191
2336
|
}
|
|
2192
2337
|
) }) }),
|
|
2193
|
-
/* @__PURE__ */
|
|
2338
|
+
/* @__PURE__ */ jsx22(SignedIn, { children: /* @__PURE__ */ jsx22(
|
|
2194
2339
|
Authed,
|
|
2195
2340
|
{
|
|
2196
2341
|
workspaces,
|
|
@@ -2210,7 +2355,7 @@ function ChapterAdmin(props) {
|
|
|
2210
2355
|
}
|
|
2211
2356
|
);
|
|
2212
2357
|
}
|
|
2213
|
-
return /* @__PURE__ */
|
|
2358
|
+
return /* @__PURE__ */ jsx22(AdminTheme, { chapter: props.chapter, scopeRef, children: content });
|
|
2214
2359
|
}
|
|
2215
2360
|
|
|
2216
2361
|
// src/ui/admin-defaults.ts
|
|
@@ -2219,17 +2364,17 @@ function defaultAdminSections(chapter) {
|
|
|
2219
2364
|
}
|
|
2220
2365
|
|
|
2221
2366
|
// src/ui/admin-meetings.tsx
|
|
2222
|
-
import { useState as
|
|
2367
|
+
import { useState as useState17 } from "preact/hooks";
|
|
2223
2368
|
import { Button as Button7 } from "@odla-ai/ui/components";
|
|
2224
|
-
import { Fragment as Fragment4, jsx as
|
|
2369
|
+
import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs19 } from "preact/jsx-runtime";
|
|
2225
2370
|
var when2 = (t) => new Date(t).toLocaleString([], { dateStyle: "medium", timeStyle: "short" });
|
|
2226
2371
|
function MeetingsBody({ ctx }) {
|
|
2227
2372
|
const copy = useChapterCopy().admin.meetings;
|
|
2228
2373
|
const { data, loading, error, refresh } = useAdminResource(ctx.getToken, "/api/admin/meetings?all=1");
|
|
2229
|
-
const [busy, setBusy] =
|
|
2230
|
-
const [note, setNote] =
|
|
2231
|
-
if (loading) return /* @__PURE__ */
|
|
2232
|
-
if (error || !data) return /* @__PURE__ */
|
|
2374
|
+
const [busy, setBusy] = useState17(null);
|
|
2375
|
+
const [note, setNote] = useState17(null);
|
|
2376
|
+
if (loading) return /* @__PURE__ */ jsx23(AdminNote, { children: copy.loading });
|
|
2377
|
+
if (error || !data) return /* @__PURE__ */ jsxs19(AdminNote, { children: [
|
|
2233
2378
|
copy.loadFailed,
|
|
2234
2379
|
error ? `: ${error}` : "",
|
|
2235
2380
|
"."
|
|
@@ -2260,32 +2405,32 @@ function MeetingsBody({ ctx }) {
|
|
|
2260
2405
|
}
|
|
2261
2406
|
void run(id, () => adminFetch(ctx.getToken, `/api/admin/meetings/${id}/reschedule`, { method: "POST", body: JSON.stringify({ startAt }) }));
|
|
2262
2407
|
};
|
|
2263
|
-
return /* @__PURE__ */
|
|
2408
|
+
return /* @__PURE__ */ jsx23(AdminPage, { children: /* @__PURE__ */ jsx23(Panel, { title: /* @__PURE__ */ jsxs19(Fragment4, { children: [
|
|
2264
2409
|
copy.agenda,
|
|
2265
2410
|
" ",
|
|
2266
|
-
/* @__PURE__ */
|
|
2411
|
+
/* @__PURE__ */ jsxs19("span", { className: "muted", style: { fontWeight: 400 }, children: [
|
|
2267
2412
|
"\xB7 ",
|
|
2268
2413
|
data.timezone
|
|
2269
2414
|
] })
|
|
2270
|
-
] }), actions: note ? /* @__PURE__ */
|
|
2271
|
-
/* @__PURE__ */
|
|
2272
|
-
/* @__PURE__ */
|
|
2273
|
-
/* @__PURE__ */
|
|
2274
|
-
m.drift && m.drift !== "none" ? /* @__PURE__ */
|
|
2415
|
+
] }), actions: note ? /* @__PURE__ */ jsx23("span", { className: "muted", children: note }) : void 0, children: data.meetings.length === 0 ? /* @__PURE__ */ jsx23("p", { className: "muted", style: { margin: 0 }, children: copy.empty }) : /* @__PURE__ */ jsx23("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 12 }, children: data.meetings.map((m) => /* @__PURE__ */ jsxs19("li", { style: { display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap", opacity: m.status === "cancelled" ? 0.55 : 1 }, children: [
|
|
2416
|
+
/* @__PURE__ */ jsx23("strong", { style: { minWidth: 170 }, children: when2(m.startAt) }),
|
|
2417
|
+
/* @__PURE__ */ jsx23("span", { style: { flex: 1 }, children: m.applicant ? `${m.applicant.name} \xB7 ${m.applicant.email}` : copy.unknown }),
|
|
2418
|
+
/* @__PURE__ */ jsx23("span", { className: "badge", children: m.status }),
|
|
2419
|
+
m.drift && m.drift !== "none" ? /* @__PURE__ */ jsxs19("span", { className: "badge", children: [
|
|
2275
2420
|
copy.drift,
|
|
2276
2421
|
": ",
|
|
2277
2422
|
m.drift
|
|
2278
2423
|
] }) : null,
|
|
2279
|
-
m.meetUrl ? /* @__PURE__ */
|
|
2280
|
-
m.status === "scheduled" ? /* @__PURE__ */
|
|
2281
|
-
/* @__PURE__ */
|
|
2282
|
-
/* @__PURE__ */
|
|
2424
|
+
m.meetUrl ? /* @__PURE__ */ jsx23("a", { href: m.meetUrl, target: "_blank", rel: "noreferrer", children: copy.meet }) : null,
|
|
2425
|
+
m.status === "scheduled" ? /* @__PURE__ */ jsxs19(Fragment4, { children: [
|
|
2426
|
+
/* @__PURE__ */ jsx23(Button7, { variant: "secondary", mini: true, disabled: busy === m.id, onClick: () => reschedule(m.id), children: copy.reschedule }),
|
|
2427
|
+
/* @__PURE__ */ jsx23(Button7, { variant: "danger", mini: true, disabled: busy === m.id, onClick: () => cancel(m.id), children: copy.cancel })
|
|
2283
2428
|
] }) : null
|
|
2284
2429
|
] }, m.id)) }) }) });
|
|
2285
2430
|
}
|
|
2286
2431
|
function meetingsSection(options = {}) {
|
|
2287
2432
|
const { id = "meetings", label = "Meetings" } = options;
|
|
2288
|
-
return { id, label, render: (ctx) => /* @__PURE__ */
|
|
2433
|
+
return { id, label, render: (ctx) => /* @__PURE__ */ jsx23(MeetingsBody, { ctx }) };
|
|
2289
2434
|
}
|
|
2290
2435
|
|
|
2291
2436
|
export {
|
|
@@ -2313,6 +2458,8 @@ export {
|
|
|
2313
2458
|
LeaderNetworkOverview,
|
|
2314
2459
|
AdmissionGrantsWorkspace,
|
|
2315
2460
|
admissionGrantsWorkspace,
|
|
2461
|
+
MemberContentAdmin,
|
|
2462
|
+
memberContentSection,
|
|
2316
2463
|
defaultAdminWorkspaces,
|
|
2317
2464
|
loadChapterAdminConfig,
|
|
2318
2465
|
loadChapterAdminUser,
|
|
@@ -2320,4 +2467,4 @@ export {
|
|
|
2320
2467
|
defaultAdminSections,
|
|
2321
2468
|
meetingsSection
|
|
2322
2469
|
};
|
|
2323
|
-
//# sourceMappingURL=chunk-
|
|
2470
|
+
//# sourceMappingURL=chunk-SI3JHSEX.js.map
|