@odla-ai/chapter 0.50.0 → 0.52.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 +109 -8
- package/dist/{chunk-4EA5V4JE.js → chunk-7N4VDWM5.js} +239 -136
- package/dist/chunk-7N4VDWM5.js.map +1 -0
- package/dist/{chunk-OS46ZE46.js → chunk-7RIT2UN5.js} +3 -7
- package/dist/chunk-7RIT2UN5.js.map +1 -0
- package/dist/{chunk-JXX4BFDP.js → chunk-A6W53GVM.js} +5 -1
- package/dist/chunk-A6W53GVM.js.map +1 -0
- package/dist/{copy-context-Ddat__H5.d.ts → copy-context-CYLlPzAc.d.ts} +11 -5
- package/dist/index.cjs +111 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -13
- package/dist/index.d.ts +77 -13
- package/dist/index.js +111 -18
- package/dist/index.js.map +1 -1
- package/dist/ui/admin/index.d.ts +14 -3
- package/dist/ui/admin/index.js +4 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +5 -3
- package/dist/ui/member/index.d.ts +2 -2
- package/dist/ui/member/index.js +2 -2
- package/dist/worker/index.cjs +983 -368
- package/dist/worker/index.cjs.map +1 -1
- package/dist/worker/index.d.cts +52 -10
- package/dist/worker/index.d.ts +52 -10
- package/dist/worker/index.js +983 -368
- package/dist/worker/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-4EA5V4JE.js.map +0 -1
- package/dist/chunk-JXX4BFDP.js.map +0 -1
- package/dist/chunk-OS46ZE46.js.map +0 -1
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
DEFAULT_CHAPTER_COPY,
|
|
5
5
|
formatChapterCopy,
|
|
6
6
|
useChapterCopy
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-A6W53GVM.js";
|
|
8
8
|
|
|
9
9
|
// src/ui/admin.tsx
|
|
10
10
|
import { useEffect as useEffect12, useMemo as useMemo3, useRef as useRef3, useState as useState27 } from "preact/hooks";
|
|
@@ -750,7 +750,7 @@ function SeatPanel(props) {
|
|
|
750
750
|
if (resource.loading) return /* @__PURE__ */ jsx7("p", { role: "status", children: "Loading additional seat\u2026" });
|
|
751
751
|
if (resource.error || !resource.data) return null;
|
|
752
752
|
const { data } = resource, seat = data.seat;
|
|
753
|
-
const
|
|
753
|
+
const money5 = new Intl.NumberFormat("en-US", { style: "currency", currency: data.currency }).format(data.amountCents / 100);
|
|
754
754
|
const refund = async () => {
|
|
755
755
|
setBusy(true);
|
|
756
756
|
setNote(null);
|
|
@@ -783,7 +783,7 @@ function SeatPanel(props) {
|
|
|
783
783
|
seat.status.replaceAll("_", " ")
|
|
784
784
|
] }),
|
|
785
785
|
/* @__PURE__ */ jsxs7("p", { className: "muted", style: { margin: 0 }, children: [
|
|
786
|
-
|
|
786
|
+
money5,
|
|
787
787
|
" paid in full. The seat waits for its recipient and is never refunded automatically."
|
|
788
788
|
] }),
|
|
789
789
|
data.refundable ? /* @__PURE__ */ jsx7("div", { children: /* @__PURE__ */ jsx7(Button3, { variant: "danger", mini: true, disabled: busy, onClick: () => void refund(), children: busy ? "Refunding\u2026" : "Refund seat" }) }) : null
|
|
@@ -2046,6 +2046,11 @@ function networkRecordsWorkspace(chapter) {
|
|
|
2046
2046
|
|
|
2047
2047
|
// src/ui/admin-portfolio.tsx
|
|
2048
2048
|
import { StatBand as StatBand2, StepPipeline as StepPipeline2 } from "@odla-ai/ui/components";
|
|
2049
|
+
|
|
2050
|
+
// src/network-edge.ts
|
|
2051
|
+
var EDGE_UNPAIRED = "edge_unpaired";
|
|
2052
|
+
|
|
2053
|
+
// src/ui/admin-portfolio.tsx
|
|
2049
2054
|
import { jsx as jsx24, jsxs as jsxs22 } from "preact/jsx-runtime";
|
|
2050
2055
|
function LeaderNetworkOverview({ ctx }) {
|
|
2051
2056
|
const copy = useChapterCopy().admin.network;
|
|
@@ -2059,6 +2064,14 @@ function LeaderNetworkOverview({ ctx }) {
|
|
|
2059
2064
|
error ? `: ${error}` : "",
|
|
2060
2065
|
"."
|
|
2061
2066
|
] });
|
|
2067
|
+
return /* @__PURE__ */ jsx24(LeaderNetworkOverviewView, { data });
|
|
2068
|
+
}
|
|
2069
|
+
function unpairedEdge(target) {
|
|
2070
|
+
const error = target.transport.error;
|
|
2071
|
+
return error && error.code === EDGE_UNPAIRED ? error : null;
|
|
2072
|
+
}
|
|
2073
|
+
function LeaderNetworkOverviewView({ data }) {
|
|
2074
|
+
const copy = useChapterCopy().admin.network;
|
|
2062
2075
|
if (data.configured === 0) return /* @__PURE__ */ jsx24(AdminPage, { children: /* @__PURE__ */ jsx24(Panel, { title: copy.overview, children: /* @__PURE__ */ jsx24("p", { className: "muted", children: copy.noFollowers }) }) });
|
|
2063
2076
|
const stats = [
|
|
2064
2077
|
{ value: data.configured.toLocaleString(), label: copy.configuredFollowers },
|
|
@@ -2072,24 +2085,43 @@ function LeaderNetworkOverview({ ctx }) {
|
|
|
2072
2085
|
}));
|
|
2073
2086
|
return /* @__PURE__ */ jsxs22(AdminPage, { children: [
|
|
2074
2087
|
/* @__PURE__ */ jsx24(StatBand2, { stats }),
|
|
2075
|
-
/* @__PURE__ */ jsx24(Panel, { title: copy.followers, children: /* @__PURE__ */ jsx24("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "grid", gap: 10 }, children: data.targets.map((target) => /* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */ jsx24("strong", { style: { minWidth: 180 }, children: target.name }),
|
|
2077
|
-
/* @__PURE__ */ jsx24("span", { className: "badge", children: target.transport.reachable === null ? copy.transportNotChecked : target.transport.reachable ? copy.transportReachable : copy.transportUnavailable }),
|
|
2078
|
-
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.transport.kind === "binding" ? formatChapterCopy(copy.bindingTransport, { binding: target.transport.binding ?? "" }) : copy.urlTransport }),
|
|
2079
|
-
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.configuration.activeRevision === null ? copy.noActiveConfiguration : formatChapterCopy(copy.activeConfiguration, { revision: target.configuration.activeRevision }) }),
|
|
2080
|
-
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.publicSite.available === null ? copy.publicSiteNotChecked : target.publicSite.available ? copy.publicSiteAvailable : copy.publicSiteUnavailable }),
|
|
2081
|
-
target.error ? /* @__PURE__ */ jsx24("span", { className: "muted", children: target.error }) : null,
|
|
2082
|
-
/* @__PURE__ */ jsx24("a", { href: target.url, target: "_blank", rel: "noreferrer", style: { marginLeft: "auto" }, children: target.url })
|
|
2083
|
-
] }, target.id)) }) }),
|
|
2088
|
+
/* @__PURE__ */ jsx24(Panel, { title: copy.followers, children: /* @__PURE__ */ jsx24("ul", { style: { listStyle: "none", margin: 0, padding: 0, display: "grid", gap: 10 }, children: data.targets.map((target) => /* @__PURE__ */ jsx24(FollowerRow, { target }, target.id)) }) }),
|
|
2084
2089
|
/* @__PURE__ */ jsx24(Panel, { title: copy.recordTotals, children: steps.length ? /* @__PURE__ */ jsx24(StepPipeline2, { ariaLabel: copy.recordTotals, steps }) : /* @__PURE__ */ jsx24("p", { className: "muted", children: copy.noRecordTotals }) })
|
|
2085
2090
|
] });
|
|
2086
2091
|
}
|
|
2092
|
+
function FollowerRow({ target }) {
|
|
2093
|
+
const copy = useChapterCopy().admin.network;
|
|
2094
|
+
const unpaired = unpairedEdge(target);
|
|
2095
|
+
return /* @__PURE__ */ jsxs22(
|
|
2096
|
+
"li",
|
|
2097
|
+
{
|
|
2098
|
+
"data-network-target": target.id,
|
|
2099
|
+
"data-edge-state": unpaired ? "unpaired" : "paired",
|
|
2100
|
+
style: { display: "flex", gap: 12, alignItems: "baseline", flexWrap: "wrap" },
|
|
2101
|
+
children: [
|
|
2102
|
+
/* @__PURE__ */ jsx24("strong", { style: { minWidth: 180 }, children: target.name }),
|
|
2103
|
+
/* @__PURE__ */ jsx24("span", { className: "badge", children: unpaired ? copy.edgeUnpaired : target.transport.reachable === null ? copy.transportNotChecked : target.transport.reachable ? copy.transportReachable : copy.transportUnavailable }),
|
|
2104
|
+
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.transport.kind === "binding" ? formatChapterCopy(copy.bindingTransport, { binding: target.transport.binding ?? "" }) : copy.urlTransport }),
|
|
2105
|
+
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.configuration.activeRevision === null ? copy.noActiveConfiguration : formatChapterCopy(copy.activeConfiguration, { revision: target.configuration.activeRevision }) }),
|
|
2106
|
+
/* @__PURE__ */ jsx24("span", { className: "muted", children: target.publicSite.available === null ? copy.publicSiteNotChecked : target.publicSite.available ? copy.publicSiteAvailable : copy.publicSiteUnavailable }),
|
|
2107
|
+
unpaired ? /* @__PURE__ */ jsxs22("span", { className: "muted", style: { flexBasis: "100%" }, children: [
|
|
2108
|
+
copy.edgeUnpairedHint,
|
|
2109
|
+
" ",
|
|
2110
|
+
/* @__PURE__ */ jsx24("code", { children: unpaired.hint })
|
|
2111
|
+
] }) : target.error ? /* @__PURE__ */ jsx24("span", { className: "muted", children: target.error }) : null,
|
|
2112
|
+
/* @__PURE__ */ jsx24("a", { href: target.url, target: "_blank", rel: "noreferrer", style: { marginLeft: "auto" }, children: target.url })
|
|
2113
|
+
]
|
|
2114
|
+
}
|
|
2115
|
+
);
|
|
2116
|
+
}
|
|
2087
2117
|
|
|
2088
2118
|
// src/ui/admin-admission.tsx
|
|
2089
|
-
import { useEffect as useEffect8, useRef as useRef2, useState as useState20 } from "preact/hooks";
|
|
2119
|
+
import { useEffect as useEffect8, useId, useRef as useRef2, useState as useState20 } from "preact/hooks";
|
|
2120
|
+
import { Field as Field9, Input as Input2, Select as Select8 } from "@odla-ai/ui/components";
|
|
2090
2121
|
import { jsx as jsx25, jsxs as jsxs23 } from "preact/jsx-runtime";
|
|
2091
2122
|
function AdmissionGrantsWorkspace(props) {
|
|
2092
2123
|
const copy = useChapterCopy().admin.admission;
|
|
2124
|
+
const uid = useId();
|
|
2093
2125
|
const resource = useAdminResource(props.getToken, "/api/admin/admission-grants");
|
|
2094
2126
|
const [email, setEmail] = useState20("");
|
|
2095
2127
|
const [decision, setDecision] = useState20("waive_interview");
|
|
@@ -2137,25 +2169,13 @@ function AdmissionGrantsWorkspace(props) {
|
|
|
2137
2169
|
/* @__PURE__ */ jsxs23(Panel, { title: copy.title, children: [
|
|
2138
2170
|
/* @__PURE__ */ jsx25("p", { className: "muted", style: { margin: 0 }, children: copy.description }),
|
|
2139
2171
|
/* @__PURE__ */ jsxs23("form", { onSubmit: (event) => void submit(event), style: { display: "grid", gap: 12, gridTemplateColumns: "minmax(220px,2fr) minmax(180px,1fr) minmax(160px,1fr)" }, children: [
|
|
2140
|
-
/* @__PURE__ */
|
|
2141
|
-
|
|
2142
|
-
/* @__PURE__ */ jsx25("
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
/* @__PURE__ */ jsx25("option", { value: "waive_interview", children: copy.waive }),
|
|
2148
|
-
/* @__PURE__ */ jsx25("option", { value: "require_interview", children: copy.require })
|
|
2149
|
-
] })
|
|
2150
|
-
] }),
|
|
2151
|
-
/* @__PURE__ */ jsxs23("label", { children: [
|
|
2152
|
-
copy.expires,
|
|
2153
|
-
/* @__PURE__ */ jsx25("input", { type: "date", value: expires, onInput: (event) => setExpires(event.currentTarget.value) })
|
|
2154
|
-
] }),
|
|
2155
|
-
/* @__PURE__ */ jsxs23("label", { style: { gridColumn: "1 / -1" }, children: [
|
|
2156
|
-
copy.note,
|
|
2157
|
-
/* @__PURE__ */ jsx25("input", { value: note, maxLength: 2e3, onInput: (event) => setNote(event.currentTarget.value) })
|
|
2158
|
-
] }),
|
|
2172
|
+
/* @__PURE__ */ jsx25(Field9, { label: copy.email, htmlFor: `${uid}-email`, children: /* @__PURE__ */ jsx25(Input2, { id: `${uid}-email`, required: true, type: "email", value: email, onInput: (event) => setEmail(event.currentTarget.value) }) }),
|
|
2173
|
+
/* @__PURE__ */ jsx25(Field9, { label: copy.decision, htmlFor: `${uid}-decision`, children: /* @__PURE__ */ jsxs23(Select8, { id: `${uid}-decision`, value: decision, onChange: (event) => setDecision(event.currentTarget.value), children: [
|
|
2174
|
+
/* @__PURE__ */ jsx25("option", { value: "waive_interview", children: copy.waive }),
|
|
2175
|
+
/* @__PURE__ */ jsx25("option", { value: "require_interview", children: copy.require })
|
|
2176
|
+
] }) }),
|
|
2177
|
+
/* @__PURE__ */ jsx25(Field9, { label: copy.expires, htmlFor: `${uid}-expires`, children: /* @__PURE__ */ jsx25(Input2, { id: `${uid}-expires`, type: "date", value: expires, onInput: (event) => setExpires(event.currentTarget.value) }) }),
|
|
2178
|
+
/* @__PURE__ */ jsx25(Field9, { label: copy.note, htmlFor: `${uid}-note`, style: { gridColumn: "1 / -1" }, children: /* @__PURE__ */ jsx25(Input2, { id: `${uid}-note`, value: note, maxLength: 2e3, onInput: (event) => setNote(event.currentTarget.value) }) }),
|
|
2159
2179
|
/* @__PURE__ */ jsx25("button", { className: "btn secondary", type: "submit", disabled: busy, children: copy.add })
|
|
2160
2180
|
] }),
|
|
2161
2181
|
error ? /* @__PURE__ */ jsx25("p", { role: "alert", children: error }) : null
|
|
@@ -2192,6 +2212,7 @@ function LeaderAdmissionAction(props) {
|
|
|
2192
2212
|
return /* @__PURE__ */ jsx25(LeaderAdmissionForm, { ...props }, JSON.stringify([props.targetId, props.personId, props.sourceRecordId]));
|
|
2193
2213
|
}
|
|
2194
2214
|
function LeaderAdmissionForm(props) {
|
|
2215
|
+
const uid = useId();
|
|
2195
2216
|
const [decision, setDecision] = useState20("");
|
|
2196
2217
|
const [note, setNote] = useState20("");
|
|
2197
2218
|
const [loaded, setLoaded] = useState20(false);
|
|
@@ -2243,18 +2264,12 @@ function LeaderAdmissionForm(props) {
|
|
|
2243
2264
|
}
|
|
2244
2265
|
};
|
|
2245
2266
|
return /* @__PURE__ */ jsxs23("div", { style: { display: "grid", gap: 8 }, children: [
|
|
2246
|
-
/* @__PURE__ */
|
|
2247
|
-
"
|
|
2248
|
-
/* @__PURE__ */
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
] })
|
|
2253
|
-
] }),
|
|
2254
|
-
/* @__PURE__ */ jsxs23("label", { children: [
|
|
2255
|
-
"Internal note",
|
|
2256
|
-
/* @__PURE__ */ jsx25("input", { disabled: !loaded || busy, maxLength: 2e3, value: note, onInput: (event) => setNote(event.currentTarget.value) })
|
|
2257
|
-
] }),
|
|
2267
|
+
/* @__PURE__ */ jsx25(Field9, { label: "Interview", htmlFor: `${uid}-decision`, children: /* @__PURE__ */ jsxs23(Select8, { id: `${uid}-decision`, disabled: !loaded || busy, value: decision, onChange: (event) => setDecision(event.currentTarget.value), children: [
|
|
2268
|
+
/* @__PURE__ */ jsx25("option", { value: "", children: loaded ? "Choose an invitation setting" : "Loading saved setting\u2026" }),
|
|
2269
|
+
/* @__PURE__ */ jsx25("option", { value: "waive_interview", children: "Already completed" }),
|
|
2270
|
+
/* @__PURE__ */ jsx25("option", { value: "require_interview", children: "Required" })
|
|
2271
|
+
] }) }),
|
|
2272
|
+
/* @__PURE__ */ jsx25(Field9, { label: "Internal note", htmlFor: `${uid}-note`, children: /* @__PURE__ */ jsx25(Input2, { id: `${uid}-note`, disabled: !loaded || busy, maxLength: 2e3, value: note, onInput: (event) => setNote(event.currentTarget.value) }) }),
|
|
2258
2273
|
/* @__PURE__ */ jsx25("button", { className: "btn secondary", type: "button", disabled: busy || !loaded || !decision, onClick: () => void submit(), children: busy ? "Saving\u2026" : "Save invitation setting" }),
|
|
2259
2274
|
error ? /* @__PURE__ */ jsx25("p", { role: "alert", children: error }) : null,
|
|
2260
2275
|
status ? /* @__PURE__ */ jsx25("p", { role: "status", children: status }) : null
|
|
@@ -2266,7 +2281,7 @@ import { Tabs as Tabs2 } from "@odla-ai/ui/components";
|
|
|
2266
2281
|
|
|
2267
2282
|
// src/ui/admin-availability.tsx
|
|
2268
2283
|
import { useState as useState21 } from "preact/hooks";
|
|
2269
|
-
import { Button as Button14, Checkbox, Field as
|
|
2284
|
+
import { Button as Button14, Checkbox, Field as Field10, Input as Input3 } from "@odla-ai/ui/components";
|
|
2270
2285
|
import { jsx as jsx26, jsxs as jsxs24 } from "preact/jsx-runtime";
|
|
2271
2286
|
function AvailabilityBody({ ctx }) {
|
|
2272
2287
|
const copy = useChapterCopy().admin.availability;
|
|
@@ -2307,18 +2322,18 @@ function AvailabilityBody({ ctx }) {
|
|
|
2307
2322
|
setBusy(false);
|
|
2308
2323
|
}
|
|
2309
2324
|
};
|
|
2310
|
-
const numField = (key, label) => /* @__PURE__ */ jsx26(
|
|
2325
|
+
const numField = (key, label) => /* @__PURE__ */ jsx26(Field10, { label, error: errors[key], children: /* @__PURE__ */ jsx26(Input3, { type: "number", value: cfg[key], onInput: (e) => edit({ [key]: num(e.target.value, cfg[key]) }) }) });
|
|
2311
2326
|
return /* @__PURE__ */ jsx26(AdminPage, { children: /* @__PURE__ */ jsxs24(Panel, { title: copy.title, actions: note ? /* @__PURE__ */ jsx26("span", { className: "muted", children: note }) : void 0, children: [
|
|
2312
|
-
/* @__PURE__ */ jsx26(
|
|
2327
|
+
/* @__PURE__ */ jsx26(Field10, { label: copy.days, error: errors.days, children: /* @__PURE__ */ jsx26("div", { style: { display: "flex", gap: 14, flexWrap: "wrap" }, children: copy.dayLabels.map((d, i) => /* @__PURE__ */ jsx26(Checkbox, { label: d, checked: cfg.days.includes(i), onChange: () => toggleDay(i) }, d)) }) }),
|
|
2313
2328
|
/* @__PURE__ */ jsxs24("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(180px, 1fr))", gap: 14 }, children: [
|
|
2314
2329
|
numField("startHour", copy.startHour),
|
|
2315
2330
|
numField("endHour", copy.endHour),
|
|
2316
2331
|
numField("slotMinutes", copy.slotMinutes),
|
|
2317
2332
|
numField("minNoticeHours", copy.minNoticeHours),
|
|
2318
2333
|
numField("windowDays", copy.windowDays),
|
|
2319
|
-
/* @__PURE__ */ jsx26(
|
|
2334
|
+
/* @__PURE__ */ jsx26(Field10, { label: copy.timezone, error: errors.timezone, children: /* @__PURE__ */ jsx26(Input3, { value: cfg.timezone, onInput: (e) => edit({ timezone: e.target.value }) }) })
|
|
2320
2335
|
] }),
|
|
2321
|
-
/* @__PURE__ */ jsx26(
|
|
2336
|
+
/* @__PURE__ */ jsx26(Field10, { label: copy.summaryTemplate, error: errors.summaryTemplate, children: /* @__PURE__ */ jsx26(Input3, { value: cfg.summaryTemplate, onInput: (e) => edit({ summaryTemplate: e.target.value }) }) }),
|
|
2322
2337
|
/* @__PURE__ */ jsx26("div", { children: /* @__PURE__ */ jsx26(Button14, { disabled: !draft || busy, onClick: () => void save(), children: copy.save }) })
|
|
2323
2338
|
] }) });
|
|
2324
2339
|
}
|
|
@@ -2328,7 +2343,8 @@ function availabilitySection(options = {}) {
|
|
|
2328
2343
|
}
|
|
2329
2344
|
|
|
2330
2345
|
// src/ui/admin-builder-library.tsx
|
|
2331
|
-
import { useEffect as useEffect9, useMemo as useMemo2, useState as useState22 } from "preact/hooks";
|
|
2346
|
+
import { useEffect as useEffect9, useId as useId2, useMemo as useMemo2, useState as useState22 } from "preact/hooks";
|
|
2347
|
+
import { Field as Field11, Input as Input4, Select as Select9, Textarea as Textarea3 } from "@odla-ai/ui/components";
|
|
2332
2348
|
import { jsx as jsx27, jsxs as jsxs25 } from "preact/jsx-runtime";
|
|
2333
2349
|
var KINDS = ["document", "note", "link", "inspiration", "image", "file"];
|
|
2334
2350
|
var KIND_LABEL = { document: "Document", note: "Note", link: "Link", inspiration: "Inspiration", image: "Image", file: "File" };
|
|
@@ -2445,17 +2461,17 @@ function BuilderLibraryAdmin({ ctx, initialData }) {
|
|
|
2445
2461
|
"Builder Library ",
|
|
2446
2462
|
/* @__PURE__ */ jsx27("span", { className: "muted", children: "\xB7 private" })
|
|
2447
2463
|
] }), actions: /* @__PURE__ */ jsxs25("div", { style: ROW, children: [
|
|
2448
|
-
/* @__PURE__ */ jsx27(
|
|
2464
|
+
/* @__PURE__ */ jsx27(Select9, { "aria-label": "New resource type", value: newKind, onChange: (event) => setNewKind(event.currentTarget.value), children: KINDS.map((kind) => /* @__PURE__ */ jsx27("option", { value: kind, children: KIND_LABEL[kind] }, kind)) }),
|
|
2449
2465
|
/* @__PURE__ */ jsx27("button", { className: "btn primary", type: "button", disabled: !data.localAuthoring, onClick: add, children: "Add resource" })
|
|
2450
2466
|
] }), children: [
|
|
2451
2467
|
/* @__PURE__ */ jsx27("p", { className: "muted", style: { margin: 0 }, children: "Documents, links, and Brand assets used by site-building agents. Nothing here appears on a member page." }),
|
|
2452
2468
|
/* @__PURE__ */ jsxs25("div", { style: ROW, children: [
|
|
2453
|
-
/* @__PURE__ */ jsx27(
|
|
2454
|
-
/* @__PURE__ */ jsxs25(
|
|
2469
|
+
/* @__PURE__ */ jsx27(Input4, { "aria-label": "Search resources", placeholder: "Search resources", value: query, onInput: (event) => setQuery(event.currentTarget.value), style: { flex: "1 1 220px" } }),
|
|
2470
|
+
/* @__PURE__ */ jsxs25(Select9, { "aria-label": "Filter by type", value: kindFilter, onChange: (event) => setKindFilter(event.currentTarget.value), children: [
|
|
2455
2471
|
/* @__PURE__ */ jsx27("option", { value: "all", children: "All types" }),
|
|
2456
2472
|
KINDS.map((kind) => /* @__PURE__ */ jsx27("option", { value: kind, children: KIND_LABEL[kind] }, kind))
|
|
2457
2473
|
] }),
|
|
2458
|
-
/* @__PURE__ */ jsxs25(
|
|
2474
|
+
/* @__PURE__ */ jsxs25(Select9, { "aria-label": "Filter by status", value: statusFilter, onChange: (event) => setStatusFilter(event.currentTarget.value), children: [
|
|
2459
2475
|
/* @__PURE__ */ jsx27("option", { value: "all", children: "All statuses" }),
|
|
2460
2476
|
/* @__PURE__ */ jsx27("option", { value: "draft", children: "Draft" }),
|
|
2461
2477
|
/* @__PURE__ */ jsx27("option", { value: "published", children: "Published" }),
|
|
@@ -2506,6 +2522,7 @@ function BuilderLibraryAdmin({ ctx, initialData }) {
|
|
|
2506
2522
|
] });
|
|
2507
2523
|
}
|
|
2508
2524
|
function LocalEditor({ selected, data, scopeValue, update, setResources, setSelectedKey }) {
|
|
2525
|
+
const uid = useId2();
|
|
2509
2526
|
return /* @__PURE__ */ jsxs25("div", { style: STACK, children: [
|
|
2510
2527
|
/* @__PURE__ */ jsxs25("div", { style: META, children: [
|
|
2511
2528
|
"Local \xB7 resource revision ",
|
|
@@ -2514,77 +2531,41 @@ function LocalEditor({ selected, data, scopeValue, update, setResources, setSele
|
|
|
2514
2531
|
data.local?.revision ?? 0
|
|
2515
2532
|
] }),
|
|
2516
2533
|
/* @__PURE__ */ jsxs25("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }, children: [
|
|
2517
|
-
/* @__PURE__ */
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
/* @__PURE__ */ jsx27("
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
/* @__PURE__ */ jsx27("
|
|
2538
|
-
/* @__PURE__ */ jsxs25("
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
/* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2545
|
-
/* @__PURE__ */ jsx27("span", { children: "Visible to" }),
|
|
2546
|
-
/* @__PURE__ */ jsxs25("select", { value: scopeValue, onChange: (event) => {
|
|
2547
|
-
const value = event.currentTarget.value;
|
|
2548
|
-
update({ scope: value === "global" ? { kind: "global" } : value === "built_not_found" ? { kind: "built_not_found" } : { kind: "chapter", chapterId: value.slice("chapter:".length) } });
|
|
2549
|
-
}, children: [
|
|
2550
|
-
data.mode === "hub" ? /* @__PURE__ */ jsx27("option", { value: "built_not_found", children: "Built Not Found only" }) : null,
|
|
2551
|
-
data.mode === "hub" ? /* @__PURE__ */ jsx27("option", { value: "global", children: "All chapters" }) : null,
|
|
2552
|
-
data.chapterTargets.map(({ chapterId }) => /* @__PURE__ */ jsxs25("option", { value: `chapter:${chapterId}`, children: [
|
|
2553
|
-
"Only ",
|
|
2554
|
-
chapterId
|
|
2555
|
-
] }, chapterId))
|
|
2556
|
-
] })
|
|
2557
|
-
] }),
|
|
2558
|
-
/* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2559
|
-
/* @__PURE__ */ jsx27("span", { children: "Tags" }),
|
|
2560
|
-
/* @__PURE__ */ jsx27("input", { value: selected.tags.join(", "), placeholder: "brand, membership", onInput: (event) => update({ tags: event.currentTarget.value.split(",").map((tag) => tag.trim()).filter(Boolean) }) })
|
|
2561
|
-
] })
|
|
2562
|
-
] }),
|
|
2563
|
-
/* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2564
|
-
/* @__PURE__ */ jsx27("span", { children: "Summary" }),
|
|
2565
|
-
/* @__PURE__ */ jsx27("textarea", { rows: 2, value: selected.summary ?? "", onInput: (event) => update({ summary: event.currentTarget.value || void 0 }) })
|
|
2534
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Title", htmlFor: `${uid}-title`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-title`, value: selected.title, onInput: (event) => update({ title: event.currentTarget.value }) }) }),
|
|
2535
|
+
/* @__PURE__ */ jsx27(Field11, { label: "ID", htmlFor: `${uid}-id`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-id`, value: selected.id, onInput: (event) => {
|
|
2536
|
+
const id = cleanId(event.currentTarget.value);
|
|
2537
|
+
setResources((items) => items.map((item) => item.id === selected.id ? { ...item, id } : item));
|
|
2538
|
+
setSelectedKey(localKey(id));
|
|
2539
|
+
} }) }),
|
|
2540
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Type", htmlFor: `${uid}-kind`, children: /* @__PURE__ */ jsx27(Select9, { id: `${uid}-kind`, value: selected.kind, onChange: (event) => {
|
|
2541
|
+
const kind = event.currentTarget.value;
|
|
2542
|
+
update({ kind, bodyMarkdown: kind === "document" || kind === "note" ? selected.bodyMarkdown ?? "Start writing\u2026" : void 0, url: kind === "link" || kind === "inspiration" ? selected.url ?? "https://example.com" : void 0, brandAsset: kind === "image" || kind === "file" ? selected.brandAsset ?? { bookId: "brand-book", assetId: "replace-me" } : void 0 });
|
|
2543
|
+
}, children: KINDS.map((kind) => /* @__PURE__ */ jsx27("option", { value: kind, children: KIND_LABEL[kind] }, kind)) }) }),
|
|
2544
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Status", htmlFor: `${uid}-status`, children: /* @__PURE__ */ jsxs25(Select9, { id: `${uid}-status`, value: selected.status, onChange: (event) => update({ status: event.currentTarget.value }), children: [
|
|
2545
|
+
/* @__PURE__ */ jsx27("option", { value: "draft", children: "Draft" }),
|
|
2546
|
+
/* @__PURE__ */ jsx27("option", { value: "published", children: "Published" }),
|
|
2547
|
+
/* @__PURE__ */ jsx27("option", { value: "archived", children: "Archived" })
|
|
2548
|
+
] }) }),
|
|
2549
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Visible to", htmlFor: `${uid}-scope`, children: /* @__PURE__ */ jsxs25(Select9, { id: `${uid}-scope`, value: scopeValue, onChange: (event) => {
|
|
2550
|
+
const value = event.currentTarget.value;
|
|
2551
|
+
update({ scope: value === "global" ? { kind: "global" } : value === "built_not_found" ? { kind: "built_not_found" } : { kind: "chapter", chapterId: value.slice("chapter:".length) } });
|
|
2552
|
+
}, children: [
|
|
2553
|
+
data.mode === "hub" ? /* @__PURE__ */ jsx27("option", { value: "built_not_found", children: "Built Not Found only" }) : null,
|
|
2554
|
+
data.mode === "hub" ? /* @__PURE__ */ jsx27("option", { value: "global", children: "All chapters" }) : null,
|
|
2555
|
+
data.chapterTargets.map(({ chapterId }) => /* @__PURE__ */ jsxs25("option", { value: `chapter:${chapterId}`, children: [
|
|
2556
|
+
"Only ",
|
|
2557
|
+
chapterId
|
|
2558
|
+
] }, chapterId))
|
|
2559
|
+
] }) }),
|
|
2560
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Tags", htmlFor: `${uid}-tags`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-tags`, value: selected.tags.join(", "), placeholder: "brand, membership", onInput: (event) => update({ tags: event.currentTarget.value.split(",").map((tag) => tag.trim()).filter(Boolean) }) }) })
|
|
2566
2561
|
] }),
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
] }) : null,
|
|
2571
|
-
selected.kind === "link" || selected.kind === "inspiration" ? /* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2572
|
-
/* @__PURE__ */ jsx27("span", { children: "HTTPS URL" }),
|
|
2573
|
-
/* @__PURE__ */ jsx27("input", { type: "url", value: selected.url ?? "", onInput: (event) => update({ url: event.currentTarget.value }) })
|
|
2574
|
-
] }) : null,
|
|
2562
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Summary", htmlFor: `${uid}-summary`, children: /* @__PURE__ */ jsx27(Textarea3, { id: `${uid}-summary`, rows: 2, value: selected.summary ?? "", onInput: (event) => update({ summary: event.currentTarget.value || void 0 }) }) }),
|
|
2563
|
+
selected.kind === "document" || selected.kind === "note" ? /* @__PURE__ */ jsx27(Field11, { label: "Markdown", htmlFor: `${uid}-markdown`, children: /* @__PURE__ */ jsx27(Textarea3, { id: `${uid}-markdown`, rows: 12, value: selected.bodyMarkdown ?? "", onInput: (event) => update({ bodyMarkdown: event.currentTarget.value }) }) }) : null,
|
|
2564
|
+
selected.kind === "link" || selected.kind === "inspiration" ? /* @__PURE__ */ jsx27(Field11, { label: "HTTPS URL", htmlFor: `${uid}-url`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-url`, type: "url", value: selected.url ?? "", onInput: (event) => update({ url: event.currentTarget.value }) }) }) : null,
|
|
2575
2565
|
selected.kind === "image" || selected.kind === "file" ? /* @__PURE__ */ jsxs25("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }, children: [
|
|
2576
|
-
/* @__PURE__ */
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
] }),
|
|
2580
|
-
/* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2581
|
-
/* @__PURE__ */ jsx27("span", { children: "Asset ID" }),
|
|
2582
|
-
/* @__PURE__ */ jsx27("input", { value: selected.brandAsset?.assetId ?? "", onInput: (event) => update({ brandAsset: { bookId: selected.brandAsset?.bookId ?? "", assetId: event.currentTarget.value, ...selected.brandAsset?.filename ? { filename: selected.brandAsset.filename } : {} } }) })
|
|
2583
|
-
] }),
|
|
2584
|
-
/* @__PURE__ */ jsxs25("label", { className: "field", children: [
|
|
2585
|
-
/* @__PURE__ */ jsx27("span", { children: "Filename (optional)" }),
|
|
2586
|
-
/* @__PURE__ */ jsx27("input", { value: selected.brandAsset?.filename ?? "", onInput: (event) => update({ brandAsset: { bookId: selected.brandAsset?.bookId ?? "", assetId: selected.brandAsset?.assetId ?? "", ...event.currentTarget.value ? { filename: event.currentTarget.value } : {} } }) })
|
|
2587
|
-
] })
|
|
2566
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Brand book ID", htmlFor: `${uid}-book`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-book`, value: selected.brandAsset?.bookId ?? "", onInput: (event) => update({ brandAsset: { bookId: event.currentTarget.value, assetId: selected.brandAsset?.assetId ?? "", ...selected.brandAsset?.filename ? { filename: selected.brandAsset.filename } : {} } }) }) }),
|
|
2567
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Asset ID", htmlFor: `${uid}-asset`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-asset`, value: selected.brandAsset?.assetId ?? "", onInput: (event) => update({ brandAsset: { bookId: selected.brandAsset?.bookId ?? "", assetId: event.currentTarget.value, ...selected.brandAsset?.filename ? { filename: selected.brandAsset.filename } : {} } }) }) }),
|
|
2568
|
+
/* @__PURE__ */ jsx27(Field11, { label: "Filename (optional)", htmlFor: `${uid}-filename`, children: /* @__PURE__ */ jsx27(Input4, { id: `${uid}-filename`, value: selected.brandAsset?.filename ?? "", onInput: (event) => update({ brandAsset: { bookId: selected.brandAsset?.bookId ?? "", assetId: selected.brandAsset?.assetId ?? "", ...event.currentTarget.value ? { filename: event.currentTarget.value } : {} } }) }) })
|
|
2588
2569
|
] }) : null,
|
|
2589
2570
|
/* @__PURE__ */ jsx27(ResourcePreview, { item: selected })
|
|
2590
2571
|
] });
|
|
@@ -2595,11 +2576,11 @@ function builderLibrarySection() {
|
|
|
2595
2576
|
|
|
2596
2577
|
// src/ui/admin-email.tsx
|
|
2597
2578
|
import { useState as useState24 } from "preact/hooks";
|
|
2598
|
-
import { Button as Button16, Checkbox as Checkbox2, DataTable as DataTable3, Field as
|
|
2579
|
+
import { Button as Button16, Checkbox as Checkbox2, DataTable as DataTable3, Field as Field13, Input as Input6, Textarea as Textarea5 } from "@odla-ai/ui/components";
|
|
2599
2580
|
|
|
2600
2581
|
// src/ui/admin-email-resolution.tsx
|
|
2601
2582
|
import { useState as useState23 } from "preact/hooks";
|
|
2602
|
-
import { Button as Button15, Field as
|
|
2583
|
+
import { Button as Button15, Field as Field12, Input as Input5, Textarea as Textarea4 } from "@odla-ai/ui/components";
|
|
2603
2584
|
import { jsx as jsx28, jsxs as jsxs26 } from "preact/jsx-runtime";
|
|
2604
2585
|
function EmailDeliveryResolution({ row, ctx, onResolved }) {
|
|
2605
2586
|
const [open, setOpen] = useState23(false), [reason, setReason] = useState23(""), [messageId, setMessageId] = useState23("");
|
|
@@ -2636,8 +2617,8 @@ function EmailDeliveryResolution({ row, ctx, onResolved }) {
|
|
|
2636
2617
|
row.subject,
|
|
2637
2618
|
". Check provider evidence, not just whether the message is in an inbox. This action does not send mail."
|
|
2638
2619
|
] }),
|
|
2639
|
-
/* @__PURE__ */ jsx28(
|
|
2640
|
-
/* @__PURE__ */ jsx28(
|
|
2620
|
+
/* @__PURE__ */ jsx28(Field12, { label: "Provider evidence", children: /* @__PURE__ */ jsx28(Textarea4, { value: reason, onInput: (e) => setReason(e.target.value) }) }),
|
|
2621
|
+
/* @__PURE__ */ jsx28(Field12, { label: "Provider message ID (optional)", children: /* @__PURE__ */ jsx28(Input5, { value: messageId, onInput: (e) => setMessageId(e.target.value) }) }),
|
|
2641
2622
|
/* @__PURE__ */ jsx28(Button15, { mini: true, disabled: busy || reason.trim().length < 10, onClick: () => void resolve2("confirmed_delivered"), children: "Confirm delivered" }),
|
|
2642
2623
|
/* @__PURE__ */ jsx28(Button15, { mini: true, variant: "secondary", disabled: busy || reason.trim().length < 10, onClick: () => void resolve2("confirmed_not_delivered"), children: "Confirm not delivered" }),
|
|
2643
2624
|
/* @__PURE__ */ jsx28(Button15, { mini: true, variant: "secondary", disabled: busy, onClick: () => setOpen(false), children: "Cancel" }),
|
|
@@ -2710,16 +2691,17 @@ function EmailBody({ ctx }) {
|
|
|
2710
2691
|
data.fromEmail ? ` \xB7 ${data.fromEmail}` : ""
|
|
2711
2692
|
] }),
|
|
2712
2693
|
children: [
|
|
2713
|
-
/* @__PURE__ */ jsx29(
|
|
2714
|
-
/* @__PURE__ */ jsx29(
|
|
2715
|
-
/* @__PURE__ */ jsx29(
|
|
2694
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.notificationAddress, children: /* @__PURE__ */ jsx29(Input6, { value: data.notificationEmail, onInput: (e) => edit({ notificationEmail: e.target.value }) }) }),
|
|
2695
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.replyTo, children: /* @__PURE__ */ jsx29(Input6, { value: data.replyTo, onInput: (e) => edit({ replyTo: e.target.value }) }) }),
|
|
2696
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.fromName, hint: copy.fromNameHint, children: /* @__PURE__ */ jsx29(Input6, { value: data.fromName ?? "", onInput: (e) => edit({ fromName: e.target.value }) }) }),
|
|
2697
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.debugInbox, hint: copy.debugInboxHint, children: /* @__PURE__ */ jsx29(Input6, { value: data.debugEmail, onInput: (e) => edit({ debugEmail: e.target.value }) }) })
|
|
2716
2698
|
]
|
|
2717
2699
|
}
|
|
2718
2700
|
),
|
|
2719
2701
|
Object.entries(data.emailTemplates).map(([key, t]) => /* @__PURE__ */ jsxs27(Panel, { title: key, actions: /* @__PURE__ */ jsx29(Button16, { variant: "secondary", mini: true, disabled: busy === `test:${key}`, onClick: () => void test(key), children: copy.sendTest }), children: [
|
|
2720
2702
|
/* @__PURE__ */ jsx29(Checkbox2, { label: copy.enabled, checked: t.enabled, onChange: (e) => editTemplate(key, { enabled: e.target.checked }) }),
|
|
2721
|
-
/* @__PURE__ */ jsx29(
|
|
2722
|
-
/* @__PURE__ */ jsx29(
|
|
2703
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.subject, children: /* @__PURE__ */ jsx29(Input6, { value: t.subject, onInput: (e) => editTemplate(key, { subject: e.target.value }) }) }),
|
|
2704
|
+
/* @__PURE__ */ jsx29(Field13, { label: copy.body, children: /* @__PURE__ */ jsx29(Textarea5, { prose: true, rows: 5, value: t.text, onInput: (e) => editTemplate(key, { text: e.target.value }) }) })
|
|
2723
2705
|
] }, key)),
|
|
2724
2706
|
/* @__PURE__ */ jsxs27("div", { style: { display: "flex", gap: 12, alignItems: "center" }, children: [
|
|
2725
2707
|
/* @__PURE__ */ jsx29(Button16, { disabled: !draft || busy === "save", onClick: () => void save(), children: copy.save }),
|
|
@@ -3384,7 +3366,7 @@ function meetingsSection(options = {}) {
|
|
|
3384
3366
|
}
|
|
3385
3367
|
|
|
3386
3368
|
// src/ui/admin-network-record-editor.tsx
|
|
3387
|
-
import { Button as Button18, Field as
|
|
3369
|
+
import { Button as Button18, Field as Field14, Select as Select10 } from "@odla-ai/ui/components";
|
|
3388
3370
|
import { useRef as useRef4, useState as useState29 } from "preact/hooks";
|
|
3389
3371
|
import { Fragment as Fragment13, jsx as jsx36, jsxs as jsxs32 } from "preact/jsx-runtime";
|
|
3390
3372
|
function NetworkRecordEditor(props) {
|
|
@@ -3445,7 +3427,7 @@ function NetworkRecordEditor(props) {
|
|
|
3445
3427
|
pending.stage.replaceAll("_", " "),
|
|
3446
3428
|
". ",
|
|
3447
3429
|
ownPending ? "Retry reconciles the same operation." : "The original operator must reconcile it."
|
|
3448
|
-
] }) : record.edit.allowedStages.length ? /* @__PURE__ */ jsx36(
|
|
3430
|
+
] }) : record.edit.allowedStages.length ? /* @__PURE__ */ jsx36(Field14, { label: "Action", children: /* @__PURE__ */ jsxs32(Select10, { "aria-label": "Action", value: stage, disabled: busy, onChange: (event) => setStage(event.currentTarget.value), children: [
|
|
3449
3431
|
/* @__PURE__ */ jsx36("option", { value: "", children: "Choose an action" }),
|
|
3450
3432
|
record.edit.allowedStages.map((action) => /* @__PURE__ */ jsx36("option", { value: action.id, children: action.label }, action.id))
|
|
3451
3433
|
] }) }) : /* @__PURE__ */ jsx36("p", { children: "No membership action is currently allowed." }),
|
|
@@ -3523,6 +3505,126 @@ function NetworkSeatBilling(props) {
|
|
|
3523
3505
|
] });
|
|
3524
3506
|
}
|
|
3525
3507
|
|
|
3508
|
+
// src/ui/membership-policy-versions.tsx
|
|
3509
|
+
import { DataTable as DataTable5 } from "@odla-ai/ui/components";
|
|
3510
|
+
import { Fragment as Fragment14, jsx as jsx38, jsxs as jsxs34 } from "preact/jsx-runtime";
|
|
3511
|
+
var PATH = "/api/admin/membership-policy-versions";
|
|
3512
|
+
var day = (ms) => new Date(ms).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
|
|
3513
|
+
var money4 = (cents, currency) => new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
3514
|
+
var STATE = { active: "Active", scheduled: "Scheduled", superseded: "Superseded", draft: "Draft", retired: "Retired" };
|
|
3515
|
+
var MECHANISM = {
|
|
3516
|
+
none: "None: cohort status only, no provider discount",
|
|
3517
|
+
stripe_coupon_once: "Stripe coupon, applied once",
|
|
3518
|
+
stripe_coupon_forever: "Stripe coupon, applied while active",
|
|
3519
|
+
stripe_coupon_term_bound: "Stripe coupon, applied once; issuance refuses unless the offering's fixed term ends on the same date"
|
|
3520
|
+
};
|
|
3521
|
+
var State = ({ row }) => /* @__PURE__ */ jsx38("span", { className: row.state === "active" ? "badge" : "muted", children: STATE[row.state] });
|
|
3522
|
+
var superseded = (row) => row.supersededAt === void 0 ? "\u2014" : day(row.supersededAt);
|
|
3523
|
+
var Source = ({ row }) => /* @__PURE__ */ jsxs34("span", { children: [
|
|
3524
|
+
row.source ?? /* @__PURE__ */ jsx38("span", { className: "muted", children: "Unrecorded" }),
|
|
3525
|
+
row.actor ? /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3526
|
+
" \xB7 ",
|
|
3527
|
+
/* @__PURE__ */ jsx38("code", { children: row.actor })
|
|
3528
|
+
] }) : null,
|
|
3529
|
+
row.recordedAt !== void 0 ? /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3530
|
+
" \xB7 ",
|
|
3531
|
+
day(row.recordedAt)
|
|
3532
|
+
] }) : null
|
|
3533
|
+
] });
|
|
3534
|
+
var offeringColumns = [
|
|
3535
|
+
{ key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3536
|
+
/* @__PURE__ */ jsxs34("code", { children: [
|
|
3537
|
+
"v",
|
|
3538
|
+
row.version
|
|
3539
|
+
] }),
|
|
3540
|
+
" ",
|
|
3541
|
+
/* @__PURE__ */ jsx38(State, { row })
|
|
3542
|
+
] }), sortAs: "number", sortValue: (row) => row.version },
|
|
3543
|
+
{ key: "sku", header: "SKU", cell: (row) => /* @__PURE__ */ jsx38("code", { children: row.baseSkuId }) },
|
|
3544
|
+
{ key: "list", header: "List price", cell: (row) => `${money4(row.basePriceCents, row.currency)} / ${row.interval}` },
|
|
3545
|
+
{ key: "term", header: "Term", cell: (row) => row.term.kind === "fixed_end" ? `Ends ${day(row.term.endsAt)}` : `Rolling ${row.term.months} months` },
|
|
3546
|
+
{ key: "seat", header: "Seat", cell: (row) => `${money4(row.seatPriceCents, row.currency)} \xB7 ${row.seatPurchaseWindowCalendarMonths === void 0 ? "no window" : `${row.seatPurchaseWindowCalendarMonths}-month window`}` },
|
|
3547
|
+
{ key: "effectiveFrom", header: "Effective from", cell: (row) => day(row.effectiveFrom), sortAs: "number", sortValue: (row) => row.effectiveFrom },
|
|
3548
|
+
{ key: "effectiveUntil", header: "Effective until", cell: (row) => row.effectiveUntil === void 0 ? "Open" : day(row.effectiveUntil) },
|
|
3549
|
+
{ key: "supersededAt", header: "Superseded", cell: superseded },
|
|
3550
|
+
{ key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx38(Source, { row }) }
|
|
3551
|
+
];
|
|
3552
|
+
var policyColumns = [
|
|
3553
|
+
{ key: "version", header: "Version", cell: (row) => /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3554
|
+
/* @__PURE__ */ jsxs34("code", { children: [
|
|
3555
|
+
"v",
|
|
3556
|
+
row.version
|
|
3557
|
+
] }),
|
|
3558
|
+
" ",
|
|
3559
|
+
/* @__PURE__ */ jsx38(State, { row })
|
|
3560
|
+
] }), sortAs: "number", sortValue: (row) => row.version },
|
|
3561
|
+
{ key: "cohort", header: "Cohort", cell: (row) => /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3562
|
+
row.cohortLabel,
|
|
3563
|
+
" ",
|
|
3564
|
+
/* @__PURE__ */ jsxs34("span", { className: "muted", children: [
|
|
3565
|
+
"\xB7 soft target ",
|
|
3566
|
+
row.softTarget
|
|
3567
|
+
] })
|
|
3568
|
+
] }) },
|
|
3569
|
+
{ key: "percentOff", header: "Percent off", cell: (row) => `${row.percentOffBps / 100}%` },
|
|
3570
|
+
{ key: "skus", header: "Discounted SKUs", cell: (row) => row.discountEligibleSkuIds.length ? row.discountEligibleSkuIds.join(", ") : "None" },
|
|
3571
|
+
{ key: "qualifying", header: "Qualifying window", cell: (row) => `${day(row.qualifyingStartsAt)} \u2192 ${day(row.qualifyingEndsAt)}` },
|
|
3572
|
+
{ key: "benefit", header: "Benefit duration", cell: (row) => row.benefitDuration.kind === "fixed_end" ? `Until ${day(row.benefitDuration.endsAt)}` : row.benefitDuration.kind === "first_term" ? "First term" : "While active" },
|
|
3573
|
+
{ key: "mechanism", header: "Provider mechanism", cell: (row) => MECHANISM[row.mechanism] },
|
|
3574
|
+
{ key: "supersededAt", header: "Superseded", cell: superseded },
|
|
3575
|
+
{ key: "source", header: "Source", cell: (row) => /* @__PURE__ */ jsx38(Source, { row }) }
|
|
3576
|
+
];
|
|
3577
|
+
function MembershipPolicyVersions(props) {
|
|
3578
|
+
const path = props.chapterId ? `${PATH}?chapterId=${encodeURIComponent(props.chapterId)}` : PATH;
|
|
3579
|
+
const { data, loading, error } = useAdminResource(props.getToken, path);
|
|
3580
|
+
const scope = props.chapterId ? `chapter ${props.chapterId}` : "any chapter";
|
|
3581
|
+
if (loading) return /* @__PURE__ */ jsx38(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsx38("p", { role: "status", children: "Loading offering versions\u2026" }) });
|
|
3582
|
+
if (error || !data) return /* @__PURE__ */ jsx38(Panel, { title: "Membership offering versions", children: /* @__PURE__ */ jsxs34("p", { role: "alert", children: [
|
|
3583
|
+
"Offering versions could not be loaded: ",
|
|
3584
|
+
error ?? "empty response"
|
|
3585
|
+
] }) });
|
|
3586
|
+
return /* @__PURE__ */ jsxs34(Fragment14, { children: [
|
|
3587
|
+
/* @__PURE__ */ jsxs34(Panel, { title: "Membership offering versions", actions: data.truncated ? /* @__PURE__ */ jsx38("span", { className: "badge", children: "Truncated" }) : void 0, children: [
|
|
3588
|
+
/* @__PURE__ */ jsxs34("p", { className: "muted", children: [
|
|
3589
|
+
"The list price a card shows comes from the active offering; the payable price applies the active discount policy. State is judged as of ",
|
|
3590
|
+
day(data.now),
|
|
3591
|
+
", exactly as checkout issuance judges it."
|
|
3592
|
+
] }),
|
|
3593
|
+
/* @__PURE__ */ jsx38(
|
|
3594
|
+
DataTable5,
|
|
3595
|
+
{
|
|
3596
|
+
rows: data.offerings,
|
|
3597
|
+
columns: offeringColumns,
|
|
3598
|
+
rowKey: (row) => row.id,
|
|
3599
|
+
ariaLabel: "Membership offering versions",
|
|
3600
|
+
emptyState: `No offering versions are recorded for ${scope}.`
|
|
3601
|
+
}
|
|
3602
|
+
)
|
|
3603
|
+
] }),
|
|
3604
|
+
/* @__PURE__ */ jsxs34(Panel, { title: "Discount policy versions", children: [
|
|
3605
|
+
/* @__PURE__ */ jsx38(
|
|
3606
|
+
DataTable5,
|
|
3607
|
+
{
|
|
3608
|
+
rows: data.discountPolicies,
|
|
3609
|
+
columns: policyColumns,
|
|
3610
|
+
rowKey: (row) => row.id,
|
|
3611
|
+
ariaLabel: "Discount policy versions",
|
|
3612
|
+
emptyState: `No discount policy versions are recorded for ${scope}.`
|
|
3613
|
+
}
|
|
3614
|
+
),
|
|
3615
|
+
data.invalid.length ? /* @__PURE__ */ jsxs34("p", { role: "alert", children: [
|
|
3616
|
+
data.invalid.length,
|
|
3617
|
+
" recorded version",
|
|
3618
|
+
data.invalid.length === 1 ? " no longer normalizes and blocks" : "s no longer normalize and block",
|
|
3619
|
+
" ",
|
|
3620
|
+
"issuance: ",
|
|
3621
|
+
data.invalid.map((item) => `${item.collection} ${item.id} (${item.error})`).join("; "),
|
|
3622
|
+
"."
|
|
3623
|
+
] }) : null
|
|
3624
|
+
] })
|
|
3625
|
+
] });
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3526
3628
|
export {
|
|
3527
3629
|
AdminPage,
|
|
3528
3630
|
Panel,
|
|
@@ -3565,6 +3667,7 @@ export {
|
|
|
3565
3667
|
defaultAdminSections,
|
|
3566
3668
|
meetingsSection,
|
|
3567
3669
|
NetworkRecordEditor,
|
|
3568
|
-
NetworkSeatBilling
|
|
3670
|
+
NetworkSeatBilling,
|
|
3671
|
+
MembershipPolicyVersions
|
|
3569
3672
|
};
|
|
3570
|
-
//# sourceMappingURL=chunk-
|
|
3673
|
+
//# sourceMappingURL=chunk-7N4VDWM5.js.map
|