@odla-ai/chapter 0.20.2 → 0.22.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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ui/admin.tsx","../src/ui/chrome.tsx","../src/ui/admin-layout.tsx","../src/ui/admin-availability.tsx","../src/ui/admin-api.ts","../src/ui/admin-billing.tsx","../src/ui/admin-dashboard.tsx","../src/ui/admin-email.tsx","../src/ui/admin-meetings.tsx","../src/ui/admin-people.tsx","../src/ui/admin-record-actions.tsx","../src/ui/admin-network.tsx","../src/ui/admin-defaults.ts"],"sourcesContent":["// ChapterAdmin — the whole admin console for a chapter/hub, owned by the package\n// so no site re-wires (or re-bugs) it: the Clerk publishable-key fetch\n// (/api/config), the themed sign-in with the post-sign-in redirect DERIVED from\n// basePath (so it never bounces to \"/\"), the odla-db admins-allowlist check\n// (/api/me), and a TopBar shell (chrome.tsx) that renders the caller's sections.\nimport { useEffect, useMemo, useState } from \"react\";\nimport { ClerkGate, SignedIn, SignedOut, SignIn, useClerkAuth, clerkAppearanceFromTokens } from \"@odla-ai/auth-clerk\";\nimport { CrmClient } from \"@odla-ai/crm\";\nimport { S, Gate, AdminShell } from \"./chrome.js\";\nimport { defaultAdminSections } from \"./admin-defaults.js\";\nimport { BrandStyle } from \"./brand-style.js\";\nimport type { AdminRouting, AdminSection, Brand } from \"./chrome.js\";\nimport type { Chapter } from \"../types\";\n\nexport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\n/** Props for {@link ChapterAdmin}. */\nexport interface ChapterAdminProps {\n /** The resolved site config. When present it supplies the brand and, unless\n * `sections` is passed, the complete standard section catalog. */\n chapter?: Chapter;\n /** Explicit admin sections. Omit with `chapter` for the standard console. */\n sections?: AdminSection[];\n /** Admin mount path. The sign-in redirect + section routing derive from it,\n * so the \"bounce to home after sign-in\" bug is impossible. Default \"/admin\". */\n basePath?: string;\n /** Wordmark shown in the gate + top bar. */\n brand?: Brand;\n /** CRM route mount. Default \"/api/crm\". */\n crmBasePath?: string;\n /** Origin for /api/config and /api/me. Default same origin. */\n apiBase?: string;\n /** Section URL strategy. Default `\"query\"` (`/admin/?tab=people`), which\n * works with both SPA and ordinary static hosting. `\"path\"` requires the host\n * to serve the admin entry for every `/admin/<section>` URL. */\n routing?: AdminRouting;\n}\n\n// After sign-in: build a token-bound CrmClient, confirm the account is an\n// allowlisted admin (/api/me), then render the shell.\nfunction Authed(props: {\n sections: AdminSection[];\n basePath: string;\n brand: Brand;\n crmBasePath: string;\n apiBase: string;\n routing: AdminRouting;\n}) {\n const { sections, basePath, brand, crmBasePath, apiBase, routing } = props;\n const { getToken, signOut } = useClerkAuth();\n const client = useMemo(\n () =>\n new CrmClient({\n basePath: crmBasePath,\n headers: async (): Promise<Record<string, string>> => {\n const t = await getToken();\n return t ? { authorization: `Bearer ${t}` } : {};\n },\n }),\n [getToken, crmBasePath],\n );\n const [state, setState] = useState<{ status: \"checking\" | \"ok\" | \"denied\"; email?: string | null }>({\n status: \"checking\",\n });\n\n useEffect(() => {\n let live = true;\n void (async () => {\n try {\n const t = await getToken();\n const res = await fetch(`${apiBase}/api/me`, { headers: t ? { authorization: `Bearer ${t}` } : {} });\n const body = (await res.json().catch(() => ({}))) as { authorized?: boolean; email?: string | null };\n if (live) setState({ status: body.authorized ? \"ok\" : \"denied\", email: body.email ?? null });\n } catch {\n if (live) setState({ status: \"denied\" });\n }\n })();\n return () => {\n live = false;\n };\n }, [getToken, apiBase]);\n\n if (state.status === \"checking\") {\n return (\n <Gate brand={brand}>\n <p style={S.muted}>Checking access…</p>\n </Gate>\n );\n }\n if (state.status === \"denied\") {\n return (\n <Gate brand={brand}>\n <div className=\"card\" style={S.card}>\n <h2 style={{ marginTop: 0 }}>Not authorized</h2>\n <p style={S.muted}>\n {state.email ? `${state.email} isn't` : \"This account isn't\"} on the admin list. Ask an existing admin to add\n you in odla Studio.\n </p>\n <button className=\"btn secondary\" onClick={() => signOut()} style={{ marginTop: 12 }}>\n Sign out\n </button>\n </div>\n </Gate>\n );\n }\n return (\n <AdminShell\n sections={sections}\n basePath={basePath}\n brand={brand}\n client={client}\n getToken={getToken}\n signOut={signOut}\n email={state.email ?? null}\n routing={routing}\n />\n );\n}\n\n/**\n * The whole admin console for a chapter/hub: fetches the Clerk publishable key\n * (/api/config), gates on sign-in with the post-sign-in redirect derived from\n * `basePath`, checks the odla-db admins allowlist (/api/me), and renders a\n * TopBar shell over the caller's `sections`. The gate/shell/redirect are owned\n * here so no site re-wires (or re-bugs) them.\n */\nexport function ChapterAdmin(props: ChapterAdminProps) {\n const sections = useMemo(\n () => props.sections ?? (props.chapter ? defaultAdminSections(props.chapter) : []),\n [props.sections, props.chapter],\n );\n const basePath = props.basePath ?? \"/admin\";\n const brand = props.brand ?? {\n name: props.chapter?.name ?? \"Admin\",\n badge: props.chapter?.brand.badge,\n wordmark: props.chapter?.brand.wordmark,\n };\n const crmBasePath = props.crmBasePath ?? \"/api/crm\";\n const apiBase = props.apiBase ?? \"\";\n const routing = props.routing ?? \"query\";\n const brandStyle = <BrandStyle brand={props.chapter?.brand} />;\n\n const [pk, setPk] = useState<string | null | undefined>(undefined);\n useEffect(() => {\n let live = true;\n void (async () => {\n try {\n const res = await fetch(`${apiBase}/api/config`);\n const body = (await res.json()) as { clerkPublishableKey?: string | null };\n if (live) setPk(body.clerkPublishableKey ?? null);\n } catch {\n if (live) setPk(null);\n }\n })();\n return () => {\n live = false;\n };\n }, [apiBase]);\n\n if (pk === undefined) {\n return (\n <>\n {brandStyle}\n <Gate brand={brand}>\n <p style={S.muted}>Loading…</p>\n </Gate>\n </>\n );\n }\n if (!pk) {\n return (\n <>\n {brandStyle}\n <Gate brand={brand}>\n <div className=\"card\" style={S.card}>\n <h2 style={{ marginTop: 0 }}>Sign-in not configured</h2>\n <p style={S.muted}>No Clerk publishable key is set for this environment yet.</p>\n </div>\n </Gate>\n </>\n );\n }\n if (sections.length === 0) {\n return (\n <>\n {brandStyle}\n <Gate brand={brand}>\n <div className=\"card\" style={S.card}>\n <h2 style={{ marginTop: 0 }}>No admin sections</h2>\n <p style={S.muted}>Pass a chapter or at least one explicit section.</p>\n </div>\n </Gate>\n </>\n );\n }\n return (\n <>\n {brandStyle}\n <ClerkGate publishableKey={pk} appearance={clerkAppearanceFromTokens()} afterSignOutUrl=\"/\">\n <SignedOut>\n <Gate brand={brand} tagline=\"Admin sign-in — invite only\">\n <SignIn routing=\"hash\" forceRedirectUrl={basePath} signUpForceRedirectUrl={basePath} />\n </Gate>\n </SignedOut>\n <SignedIn>\n <Authed\n sections={sections}\n basePath={basePath}\n brand={brand}\n crmBasePath={crmBasePath}\n apiBase={apiBase}\n routing={routing}\n />\n </SignedIn>\n </ClerkGate>\n </>\n );\n}\n","// Shared chrome for ChapterAdmin: the section contract, the centered gate\n// screen, the signed-in TopBar shell, and the inline style tokens. Split out of\n// admin.tsx to stay under the repo's per-file LOC cap. Uses only @odla-ai/ui\n// classes + --ui-* tokens, so a consumer needs nothing beyond the odla-ui sheet.\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\nimport { TopBar, TopBarLink } from \"@odla-ai/ui/components\";\nimport type { CrmClient } from \"@odla-ai/crm\";\nimport { ThemeWarning } from \"./admin-layout.js\";\n\n/** What each admin section receives. `client` is a CrmClient bound to the\n * signed-in admin's bearer token; `navigate` switches sections. */\nexport interface AdminSectionContext {\n client: CrmClient;\n getToken: () => Promise<string | null>;\n /** Switch to another section by id (e.g. Overview \"jump in\" buttons). */\n navigate: (sectionId: string) => void;\n}\n\n/** One admin-console section: a nav label and a body renderer. */\nexport interface AdminSection {\n id: string;\n label: string;\n render: (ctx: AdminSectionContext) => ReactNode;\n}\n\n/** How admin section state is reflected in the URL. Query routing is the\n * host-independent default: `/admin/?tab=people` reloads through the same static\n * file on SPA and multi-page sites alike. Path routing requires a host SPA\n * fallback for every `/admin/<section>` URL. */\nexport type AdminRouting = \"query\" | \"path\";\n\n/** Wordmark shown in the gate and top bar. `name` is the plain-text identity (and\n * the badge fallback); `wordmark` is an optional rich display node for brands\n * whose typography can't be a plain string (e.g. an ampersand wrapped to render\n * upright), and `badge` overrides the glyph. */\nexport type Brand = { name: string; badge?: string; wordmark?: ReactNode };\n\n/** The badge glyph: the explicit `badge`, else the first 3 letters of `name`. */\nexport const badgeText = (brand: Brand): string => brand.badge ?? brand.name.slice(0, 3).toUpperCase();\n\n/** The display node: the rich `wordmark` if given, else the plain `name`. */\nexport const brandDisplay = (brand: Brand): ReactNode => {\n const display = brand.wordmark ?? brand.name;\n if (typeof display !== \"string\" || !display.includes(\"&\")) return display;\n return (\n <>\n {display.split(\"&\").map((part, index, all) => (\n <span key={`${part}:${index}`}>\n {part}\n {index < all.length - 1 ? <span className=\"mk-amp\">&amp;</span> : null}\n </span>\n ))}\n </>\n );\n};\n\nconst cleanBase = (basePath: string): string => basePath.length > 1 ? basePath.replace(/\\/+$/, \"\") : basePath;\n\n/** Resolve a section from the stable `?tab=` URL first, then a legacy path\n * segment for backwards-compatible deep links. */\nexport function adminSectionFromUrl(url: URL, basePath: string, sectionIds: readonly string[]): string {\n const fallback = sectionIds[0] ?? \"\";\n const tab = url.searchParams.get(\"tab\");\n if (tab && sectionIds.includes(tab)) return tab;\n const base = cleanBase(basePath);\n const rest = url.pathname.startsWith(base) ? url.pathname.slice(base.length).replace(/^\\//, \"\") : \"\";\n const legacy = rest.split(\"/\")[0] ?? \"\";\n return sectionIds.includes(legacy) ? legacy : fallback;\n}\n\n/** Build the next section URL without depending on the static host's 404/SPA\n * policy. Query mode collapses a legacy path route back to the admin mount. */\nexport function adminSectionHref(current: URL, basePath: string, id: string, routing: AdminRouting = \"query\"): string {\n const next = new URL(current);\n const base = cleanBase(basePath);\n if (routing === \"path\") {\n next.pathname = `${base}/${id}`;\n next.searchParams.delete(\"tab\");\n } else {\n const mountPaths = new Set([base, `${base}/`, `${base}/index.html`]);\n if (!mountPaths.has(next.pathname)) next.pathname = `${base}/`;\n next.searchParams.set(\"tab\", id);\n }\n next.hash = \"\";\n return `${next.pathname}${next.search}${next.hash}`;\n}\n\n/** Inline style tokens (keyed to --ui-* custom properties). */\nexport const S: Record<string, CSSProperties> = {\n gate: {\n minHeight: \"100vh\",\n display: \"grid\",\n placeItems: \"center\",\n padding: 24,\n background:\n \"radial-gradient(900px 480px at 50% -8%, var(--ui-accent-soft), transparent 70%),\" +\n \" radial-gradient(700px 500px at 110% 10%, var(--ui-good-soft), transparent 60%)\",\n },\n gateInner: { width: \"100%\", maxWidth: 400, display: \"flex\", flexDirection: \"column\", alignItems: \"center\" },\n brandBox: { textAlign: \"center\", marginBottom: 22 },\n badge: {\n width: 52,\n height: 52,\n margin: \"0 auto 14px\",\n display: \"grid\",\n placeItems: \"center\",\n fontSize: 15,\n fontWeight: 700,\n color: \"var(--ui-on-accent)\",\n background: \"linear-gradient(135deg, var(--ui-accent), var(--ui-accent-strong))\",\n borderRadius: 14,\n boxShadow: \"0 10px 28px var(--ui-accent-soft)\",\n },\n badgeSm: {\n width: 26,\n height: 26,\n display: \"grid\",\n placeItems: \"center\",\n fontSize: 10,\n fontWeight: 700,\n color: \"var(--ui-on-accent)\",\n background: \"linear-gradient(135deg, var(--ui-accent), var(--ui-accent-strong))\",\n borderRadius: 7,\n marginRight: 9,\n },\n h1: { margin: 0, fontSize: 28, letterSpacing: \"-0.02em\", fontWeight: 700 },\n muted: { color: \"var(--ui-text-muted)\" },\n role: {\n fontFamily: \"var(--ui-font-mono)\",\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n padding: \"2px 8px\",\n borderRadius: 999,\n background: \"var(--ui-accent-soft)\",\n border: \"1px solid var(--ui-accent)\",\n color: \"var(--ui-accent-strong)\",\n },\n whoami: { display: \"flex\", alignItems: \"center\", gap: 8, fontSize: 12 },\n // Sections own their own width/padding (e.g. a .wrap container).\n main: { minHeight: \"calc(100vh - 61px)\" },\n card: { width: \"100%\", textAlign: \"center\" },\n};\n\n/** Centered gate screen used for loading / sign-in / denied / not-configured. */\nexport function Gate(props: { brand: Brand; tagline?: string; children: ReactNode }) {\n const { brand, tagline, children } = props;\n return (\n <div style={S.gate}>\n <div style={S.gateInner}>\n <div style={S.brandBox}>\n <div style={S.badge}>{badgeText(brand)}</div>\n <h1 style={S.h1}>{brandDisplay(brand)}</h1>\n {tagline ? <p style={{ ...S.muted, margin: \"8px 0 0\", fontSize: 14 }}>{tagline}</p> : null}\n </div>\n {children}\n </div>\n </div>\n );\n}\n\n/** The signed-in shell: a TopBar of the caller's sections + the active body. */\nexport function AdminShell(props: {\n sections: AdminSection[];\n basePath: string;\n brand: Brand;\n client: CrmClient;\n getToken: () => Promise<string | null>;\n signOut: () => void;\n email: string | null;\n routing?: AdminRouting;\n}) {\n const { sections, basePath, brand, client, getToken, signOut, email, routing = \"query\" } = props;\n\n const sectionFromPath = useCallback(() => {\n if (typeof window === \"undefined\") return sections[0]?.id ?? \"\";\n return adminSectionFromUrl(new URL(window.location.href), basePath, sections.map((section) => section.id));\n }, [sections, basePath]);\n\n const [section, setSection] = useState(sectionFromPath);\n\n const go = useCallback(\n (id: string) => {\n window.history.pushState(null, \"\", adminSectionHref(new URL(window.location.href), basePath, id, routing));\n setSection(id);\n },\n [basePath, routing],\n );\n\n useEffect(() => {\n const onPop = () => setSection(sectionFromPath());\n window.addEventListener(\"popstate\", onPop);\n return () => window.removeEventListener(\"popstate\", onPop);\n }, [sectionFromPath]);\n\n const active = sections.find((s) => s.id === section) ?? sections[0];\n\n return (\n <>\n <TopBar>\n <a className=\"topbar-brand\" href=\"/\" style={{ display: \"inline-flex\", alignItems: \"center\" }}>\n <span style={S.badgeSm}>{badgeText(brand)}</span>\n {brandDisplay(brand)}\n </a>\n <nav className=\"topbar-nav\" aria-label=\"Admin navigation\">\n {sections.map((s) => (\n <TopBarLink key={s.id} active={section === s.id} onClick={() => go(s.id)}>\n {s.label}\n </TopBarLink>\n ))}\n </nav>\n <div className=\"topbar-spacer\" />\n <div className=\"topbar-actions\">\n <span style={S.whoami}>\n <span style={S.role}>admin</span>\n {email ? <span style={S.muted}>{email}</span> : null}\n </span>\n <button className=\"btn secondary mini\" onClick={() => signOut()}>\n Sign out\n </button>\n </div>\n </TopBar>\n <main className=\"shell-main\" style={S.main}>\n <ThemeWarning />\n {active ? active.render({ client, getToken, navigate: go }) : null}\n </main>\n </>\n );\n}\n","// Shared layout for the admin sections, so every section is a centered column of\n// odla-ui `.panel` cards with consistent width and spacing — the container the\n// chrome expects sections to own. No invented classes: `.panel`/`.muted` are\n// odla-ui's, and the width/gap is inline so it works without a per-site stylesheet.\nimport { useEffect, useState } from \"react\";\nimport type { CSSProperties, ReactNode } from \"react\";\n\nconst PAGE: CSSProperties = { maxWidth: 1120, margin: \"0 auto\", padding: \"28px 20px 64px\", display: \"flex\", flexDirection: \"column\", gap: 20 };\nconst HEAD: CSSProperties = { display: \"flex\", alignItems: \"baseline\", justifyContent: \"space-between\", gap: 16, flexWrap: \"wrap\" };\n\n/** The centered content column every admin section renders into. */\nexport function AdminPage({ children }: { children: ReactNode }) {\n return <div style={PAGE}>{children}</div>;\n}\n\n/** An odla-ui `.panel` card with an optional heading + trailing actions. */\nexport function Panel({ title, actions, children }: { title?: ReactNode; actions?: ReactNode; children: ReactNode }) {\n return (\n <section className=\"panel\" style={{ display: \"flex\", flexDirection: \"column\", gap: 14 }}>\n {title || actions ? (\n <header style={HEAD}>\n {title ? <h2 style={{ margin: 0, fontSize: 18 }}>{title}</h2> : <span />}\n {actions ? <div style={{ display: \"flex\", gap: 8, alignItems: \"center\" }}>{actions}</div> : null}\n </header>\n ) : null}\n {children}\n </section>\n );\n}\n\n// odla-ui components read their colors from `--ui-*` design tokens whose VALUES\n// come from the theme layer (e.g. @odla-ai/ui/themes/salt/tokens.css + ui.css),\n// NOT from @odla-ai/ui/index.css. Loading only index.css (or a theme whose remap\n// has no primitives behind it) leaves tokens like `--ui-surface` undefined, and\n// the whole console renders transparent/broken — silently. This probes a real\n// `.panel` background and, if it's transparent, says so LOUDLY instead.\nfunction themeLooksMissing(): boolean {\n if (typeof document === \"undefined\") return false;\n const probe = document.createElement(\"div\");\n probe.className = \"panel\";\n probe.style.cssText = \"position:absolute;visibility:hidden;pointer-events:none\";\n document.body.appendChild(probe);\n const bg = getComputedStyle(probe).backgroundColor;\n probe.remove();\n return !bg || bg === \"transparent\" || bg === \"rgba(0, 0, 0, 0)\";\n}\n\n/** A loud banner when the odla-ui theme token layer is missing — the silent-and-\n * total failure S&S flagged. Renders nothing when the theme is present. */\nexport function ThemeWarning() {\n const [missing, setMissing] = useState(false);\n useEffect(() => setMissing(themeLooksMissing()), []);\n if (!missing) return null;\n return (\n <div\n role=\"alert\"\n style={{ background: \"#7f1d1d\", color: \"#fff\", padding: \"12px 20px\", fontSize: 14, lineHeight: 1.5, textAlign: \"center\" }}\n >\n <strong>odla-ui theme tokens are missing.</strong> The console reads colors from a theme layer, not{\" \"}\n <code>@odla-ai/ui/index.css</code> alone. Import a theme before it — e.g.{\" \"}\n <code>@odla-ai/ui/themes/salt/tokens.css</code> and <code>@odla-ai/ui/themes/salt/ui.css</code> — then{\" \"}\n <code>@odla-ai/ui/index.css</code>. See the @odla-ai/chapter README (“Theme tokens”).\n </div>\n );\n}\n\n/** A centered status line for loading / empty / error states. */\nexport function AdminNote({ children }: { children: ReactNode }) {\n return (\n <AdminPage>\n <section className=\"panel\">\n <p className=\"muted\" style={{ margin: 0 }}>{children}</p>\n </section>\n </AdminPage>\n );\n}\n","// Availability section: the owner-editable booking rules from GET/PUT\n// /api/admin/scheduling, as an odla-ui form. The PUT returns field-keyed\n// validation messages, surfaced inline on each Field.\nimport { useState } from \"react\";\nimport { Button, Checkbox, Field, Input } from \"@odla-ai/ui/components\";\nimport { useAdminResource } from \"./admin-api.js\";\nimport { AdminPage, AdminNote, Panel } from \"./admin-layout.js\";\nimport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\ninterface Scheduling {\n slotMinutes: number;\n days: number[];\n startHour: number;\n endHour: number;\n timezone: string;\n minNoticeHours: number;\n windowDays: number;\n summaryTemplate: string;\n}\nconst DAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\nfunction AvailabilityBody({ ctx }: { ctx: AdminSectionContext }) {\n const { data, loading, error, refresh } = useAdminResource<{ scheduling: Scheduling }>(ctx.getToken, \"/api/admin/scheduling\");\n const [draft, setDraft] = useState<Scheduling | null>(null);\n const [busy, setBusy] = useState(false);\n const [note, setNote] = useState<string | null>(null);\n const [errors, setErrors] = useState<Record<string, string>>({});\n\n const cfg = draft ?? data?.scheduling ?? null;\n if (loading) return <AdminNote>Loading…</AdminNote>;\n if (error || !cfg) return <AdminNote>Couldn’t load availability{error ? `: ${error}` : \"\"}.</AdminNote>;\n\n const edit = (patch: Partial<Scheduling>) => setDraft({ ...cfg, ...patch });\n const toggleDay = (d: number) => edit({ days: cfg.days.includes(d) ? cfg.days.filter((x) => x !== d) : [...cfg.days, d].sort() });\n const num = (v: string, fallback: number) => (Number.isFinite(Number(v)) ? Number(v) : fallback);\n\n const save = async () => {\n setBusy(true);\n setNote(null);\n setErrors({});\n const token = await ctx.getToken();\n try {\n const r = await fetch(\"/api/admin/scheduling\", { method: \"PUT\", headers: { authorization: `Bearer ${token ?? \"\"}`, \"content-type\": \"application/json\" }, body: JSON.stringify(cfg) });\n const body = (await r.json().catch(() => ({}))) as { error?: string; errors?: Record<string, string> };\n if (!r.ok) {\n setErrors(body.errors ?? {});\n setNote(body.error ?? `save failed (${r.status})`);\n return;\n }\n setDraft(null);\n refresh();\n setNote(\"Saved.\");\n } catch (e) {\n setNote(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(false);\n }\n };\n\n const numField = (key: keyof Scheduling, label: string) => (\n <Field label={label} error={errors[key]}>\n <Input type=\"number\" value={cfg[key] as number} onChange={(e) => edit({ [key]: num((e.target as HTMLInputElement).value, cfg[key] as number) } as Partial<Scheduling>)} />\n </Field>\n );\n\n return (\n <AdminPage>\n <Panel title=\"Booking availability\" actions={note ? <span className=\"muted\">{note}</span> : undefined}>\n <Field label=\"Days\" error={errors.days}>\n <div style={{ display: \"flex\", gap: 14, flexWrap: \"wrap\" }}>\n {DAYS.map((d, i) => (\n <Checkbox key={d} label={d} checked={cfg.days.includes(i)} onChange={() => toggleDay(i)} />\n ))}\n </div>\n </Field>\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fit, minmax(180px, 1fr))\", gap: 14 }}>\n {numField(\"startHour\", \"Start hour (0–24)\")}\n {numField(\"endHour\", \"End hour (0–24)\")}\n {numField(\"slotMinutes\", \"Slot length (minutes)\")}\n {numField(\"minNoticeHours\", \"Minimum notice (hours)\")}\n {numField(\"windowDays\", \"Booking window (days)\")}\n <Field label=\"Timezone\" error={errors.timezone}>\n <Input value={cfg.timezone} onChange={(e) => edit({ timezone: (e.target as HTMLInputElement).value })} />\n </Field>\n </div>\n <Field label=\"Event summary template\" error={errors.summaryTemplate}>\n <Input value={cfg.summaryTemplate} onChange={(e) => edit({ summaryTemplate: (e.target as HTMLInputElement).value })} />\n </Field>\n <div><Button disabled={!draft || busy} onClick={() => void save()}>Save availability</Button></div>\n </Panel>\n </AdminPage>\n );\n}\n\n/** Options for {@link availabilitySection}. */\nexport interface AvailabilitySectionOptions {\n id?: string;\n label?: string;\n}\n\n/** Build the Availability admin section: the booking-rules editor over\n * `GET/PUT /api/admin/scheduling`, with field-keyed validation surfaced inline. */\nexport function availabilitySection(options: AvailabilitySectionOptions = {}): AdminSection {\n const { id = \"availability\", label = \"Availability\" } = options;\n return { id, label, render: (ctx) => <AvailabilityBody ctx={ctx} /> };\n}\n","// Token-bound access to the /api/admin/* routes for the console sections. Every\n// section fetches with the signed-in admin's bearer token (from ChapterAdmin's\n// getToken) — the worker gates each route with verifyUser + isAdmin, so the UI\n// carries no privilege of its own.\nimport { useCallback, useEffect, useState } from \"react\";\n\n/** Fetch a JSON `/api/admin/*` route with the admin bearer token. Throws on a\n * non-2xx (the body's `error`, else the status). */\nexport async function adminFetch<T = unknown>(\n getToken: () => Promise<string | null>,\n path: string,\n init?: RequestInit,\n): Promise<T> {\n const token = await getToken();\n const headers = new Headers(init?.headers);\n if (token) headers.set(\"authorization\", `Bearer ${token}`);\n if (init?.body) headers.set(\"content-type\", \"application/json\");\n const res = await fetch(path, { ...init, headers });\n const body = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) throw new Error(typeof body.error === \"string\" ? body.error : `request failed (${res.status})`);\n return body as T;\n}\n\n/** The state of one admin resource load. */\nexport interface AdminResource<T> {\n data: T | null;\n loading: boolean;\n error: string | null;\n /** Re-fetch (e.g. after a mutation). */\n refresh: () => void;\n}\n\n/** Load a `/api/admin/*` GET route into React state, re-fetching on `refresh()`\n * or when `path` changes. */\nexport function useAdminResource<T = unknown>(getToken: () => Promise<string | null>, path: string): AdminResource<T> {\n const [data, setData] = useState<T | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [nonce, setNonce] = useState(0);\n\n useEffect(() => {\n let live = true;\n setLoading(true);\n setError(null);\n adminFetch<T>(getToken, path)\n .then((d) => live && setData(d))\n .catch((e: unknown) => live && setError(e instanceof Error ? e.message : String(e)))\n .finally(() => live && setLoading(false));\n return () => {\n live = false;\n };\n }, [getToken, path, nonce]);\n\n const refresh = useCallback(() => setNonce((n) => n + 1), []);\n return { data, loading, error, refresh };\n}\n","// Billing section: applications joined with live Stripe subscription state from\n// GET /api/admin/billing, rendered with odla-ui StatBand + DataTable. Degrades to\n// a note when billingReady:false, and surfaces the route's `truncated` flag.\nimport { DataTable, StatBand } from \"@odla-ai/ui/components\";\nimport type { DataTableColumn, StatCell } from \"@odla-ai/ui/components\";\nimport { useAdminResource } from \"./admin-api.js\";\nimport { AdminPage, AdminNote, Panel } from \"./admin-layout.js\";\nimport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\ninterface BillingRow {\n id: string;\n name: string;\n email: string;\n applicationStatus: string;\n subscriptionStatus: string | null;\n cancelAtPeriodEnd: boolean;\n amountCents: number;\n interval: string;\n renewalAt: number | null;\n}\ninterface BillingData {\n billingReady: boolean;\n testMode?: boolean;\n truncated?: boolean;\n rows: BillingRow[];\n summary: { activeCount: number; annualizedCents: number; renewingSoonCount: number; pastDueCount: number; canceledCount: number; refundedCount: number } | null;\n}\n\nconst money = (cents: number): string => `$${(cents / 100).toLocaleString()}`;\nconst date = (t: number | null): string => (t ? new Date(t).toLocaleDateString([], { dateStyle: \"medium\" }) : \"—\");\n\nconst COLUMNS: readonly DataTableColumn<BillingRow>[] = [\n { key: \"name\", header: \"Name\", cell: (r) => r.name, sortAs: \"string\" },\n { key: \"email\", header: \"Email\", cell: (r) => r.email },\n { key: \"applicationStatus\", header: \"Application\", cell: (r) => r.applicationStatus },\n { key: \"subscriptionStatus\", header: \"Subscription\", cell: (r) => (r.subscriptionStatus ? `${r.subscriptionStatus}${r.cancelAtPeriodEnd ? \" · cancelling\" : \"\"}` : \"—\") },\n { key: \"amountCents\", header: \"Amount\", cell: (r) => `${money(r.amountCents)}/${r.interval === \"month\" ? \"mo\" : \"yr\"}`, sortAs: \"number\", sortValue: (r) => r.amountCents },\n { key: \"renewalAt\", header: \"Renews\", cell: (r) => date(r.renewalAt), sortAs: \"number\", sortValue: (r) => r.renewalAt ?? 0 },\n];\n\nfunction BillingBody({ ctx }: { ctx: AdminSectionContext }) {\n const { data, loading, error } = useAdminResource<BillingData>(ctx.getToken, \"/api/admin/billing\");\n if (loading) return <AdminNote>Loading…</AdminNote>;\n if (error || !data) return <AdminNote>Couldn’t load billing{error ? `: ${error}` : \"\"}.</AdminNote>;\n if (!data.billingReady) return <AdminNote>Billing isn’t configured — no Stripe key is vaulted for this group.</AdminNote>;\n\n const s = data.summary;\n const stats: StatCell[] = s\n ? [\n { value: s.activeCount, label: \"Active\" },\n { value: money(s.annualizedCents), label: \"Annualized\" },\n { value: s.renewingSoonCount, label: \"Renewing ≤60d\" },\n { value: s.pastDueCount, label: \"Past due\" },\n ]\n : [];\n\n return (\n <AdminPage>\n {s ? <StatBand stats={stats} /> : null}\n <Panel title=\"Subscriptions\" actions={data.testMode ? <span className=\"badge\">Stripe test mode</span> : undefined}>\n {data.truncated ? <p className=\"badge\">Showing the first 100 subscriptions — the list is truncated.</p> : null}\n <DataTable rows={data.rows} columns={COLUMNS} rowKey={(r) => r.id} />\n </Panel>\n </AdminPage>\n );\n}\n\n/** Options for {@link billingSection}. */\nexport interface BillingSectionOptions {\n id?: string;\n label?: string;\n}\n\n/** Build the Billing admin section over `GET /api/admin/billing`. Renders a\n * \"not configured\" note when the group has no Stripe key vaulted. */\nexport function billingSection(options: BillingSectionOptions = {}): AdminSection {\n const { id = \"billing\", label = \"Billing\" } = options;\n return { id, label, render: (ctx) => <BillingBody ctx={ctx} /> };\n}\n","// Dashboard section: the operational overview from GET /api/admin/dashboard —\n// application flow, pipeline stage counts, the upcoming call agenda, and (when\n// billing is wired) live revenue. Built from odla-ui primitives (StatBand,\n// .panel) so it matches the rest of the console.\nimport { StatBand } from \"@odla-ai/ui/components\";\nimport type { StatCell } from \"@odla-ai/ui/components\";\nimport { useAdminResource } from \"./admin-api.js\";\nimport { AdminPage, AdminNote, Panel } from \"./admin-layout.js\";\nimport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\ninterface DashboardData {\n applications: { total: number; last7: number; last30: number };\n pipeline: Record<string, number>;\n pipelineDelta: Record<string, number>;\n calls: { upcoming: number; needsAttention: number };\n agenda: Array<{ id: string; startAt: number; name: string; email: string | null; drift: string; meetUrl: string | null }>;\n timezone: string;\n revenue: { billingReady: boolean; activeCount?: number; annualRunRateCents?: number };\n}\n\nconst money = (cents: number): string => `$${Math.round(cents / 100).toLocaleString()}`;\nconst when = (t: number): string => new Date(t).toLocaleString([], { dateStyle: \"medium\", timeStyle: \"short\" });\n\nfunction DashboardBody({ ctx }: { ctx: AdminSectionContext }) {\n const { data, loading, error } = useAdminResource<DashboardData>(ctx.getToken, \"/api/admin/dashboard\");\n if (loading) return <AdminNote>Loading…</AdminNote>;\n if (error || !data) return <AdminNote>Couldn’t load the dashboard{error ? `: ${error}` : \"\"}.</AdminNote>;\n\n const kpis: StatCell[] = [\n { value: data.applications.total, label: \"Applications\", description: `+${data.applications.last7} in the last 7 days` },\n { value: data.calls.upcoming, label: \"Upcoming calls\", description: data.calls.needsAttention ? `${data.calls.needsAttention} need attention` : \"all on track\" },\n ];\n if (data.revenue.billingReady) {\n kpis.push({ value: data.revenue.activeCount ?? 0, label: \"Active members\", description: \"paid subscriptions\" });\n kpis.push({ value: money(data.revenue.annualRunRateCents ?? 0), label: \"Annual run rate\", description: \"from active subscriptions\" });\n }\n const stages: StatCell[] = Object.entries(data.pipeline).map(([stage, count]) => ({\n value: count,\n label: stage,\n description: data.pipelineDelta[stage] ? `+${data.pipelineDelta[stage]} this week` : undefined,\n }));\n\n return (\n <AdminPage>\n <StatBand stats={kpis} />\n <Panel title=\"Pipeline\">\n <StatBand stats={stages} />\n </Panel>\n <Panel title={<>Upcoming calls <span className=\"muted\" style={{ fontWeight: 400 }}>· {data.timezone}</span></>}>\n {data.agenda.length === 0 ? (\n <p className=\"muted\" style={{ margin: 0 }}>No calls scheduled.</p>\n ) : (\n <ul style={{ listStyle: \"none\", margin: 0, padding: 0, display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n {data.agenda.map((m) => (\n <li key={m.id} style={{ display: \"flex\", alignItems: \"center\", gap: 12, flexWrap: \"wrap\" }}>\n <strong style={{ minWidth: 170 }}>{when(m.startAt)}</strong>\n <span>{m.name}{m.email ? ` · ${m.email}` : \"\"}</span>\n {m.drift && m.drift !== \"none\" ? <span className=\"badge\">drift: {m.drift}</span> : null}\n {m.meetUrl ? <a href={m.meetUrl} target=\"_blank\" rel=\"noreferrer\">Meet</a> : null}\n </li>\n ))}\n </ul>\n )}\n </Panel>\n </AdminPage>\n );\n}\n\n/** Options for {@link dashboardSection}. */\nexport interface DashboardSectionOptions {\n id?: string;\n label?: string;\n}\n\n/** Build the Dashboard admin section over `GET /api/admin/dashboard`. */\nexport function dashboardSection(options: DashboardSectionOptions = {}): AdminSection {\n const { id = \"dashboard\", label = \"Dashboard\" } = options;\n return { id, label, render: (ctx) => <DashboardBody ctx={ctx} /> };\n}\n","// Email section: the owner-editable email config (templates + addresses) from\n// GET/PUT /api/admin/group/email, the send audit from GET /api/admin/email/log,\n// and a POST /api/admin/email/test button. Built from odla-ui form primitives.\nimport { useState } from \"react\";\nimport { Button, Checkbox, DataTable, Field, Input, Textarea } from \"@odla-ai/ui/components\";\nimport type { DataTableColumn } from \"@odla-ai/ui/components\";\nimport { adminFetch, useAdminResource } from \"./admin-api.js\";\nimport { AdminPage, AdminNote, Panel } from \"./admin-layout.js\";\nimport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\ninterface Template { subject: string; text: string; enabled: boolean }\ninterface EmailConfig {\n emailTemplates: Record<string, Template>;\n replyTo: string;\n notificationEmail: string;\n debugEmail: string;\n commitmentText: string;\n normsText: string;\n transport: string;\n fromEmail: string | null;\n envName: string;\n}\ninterface LogRow { id: string; template: string; to: string; subject: string; transport: string; redirected: boolean; error: string | null; sentAt: number }\n\nconst LOG_COLUMNS: readonly DataTableColumn<LogRow>[] = [\n { key: \"sentAt\", header: \"Sent\", cell: (r) => new Date(r.sentAt).toLocaleString(), sortAs: \"number\", sortValue: (r) => r.sentAt },\n { key: \"template\", header: \"Template\", cell: (r) => r.template },\n { key: \"to\", header: \"To\", cell: (r) => r.to },\n { key: \"status\", header: \"Status\", cell: (r) => (r.error ? <span className=\"badge\">failed</span> : r.redirected ? <span className=\"badge\">redirected</span> : \"delivered\") },\n];\n\nfunction EmailBody({ ctx }: { ctx: AdminSectionContext }) {\n const cfg = useAdminResource<EmailConfig>(ctx.getToken, \"/api/admin/group/email\");\n const log = useAdminResource<{ sends: LogRow[] }>(ctx.getToken, \"/api/admin/email/log\");\n const [draft, setDraft] = useState<EmailConfig | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [note, setNote] = useState<string | null>(null);\n\n const data = draft ?? cfg.data;\n if (cfg.loading) return <AdminNote>Loading…</AdminNote>;\n if (cfg.error || !data) return <AdminNote>Couldn’t load email config{cfg.error ? `: ${cfg.error}` : \"\"}.</AdminNote>;\n\n const edit = (patch: Partial<EmailConfig>) => setDraft({ ...data, ...patch });\n const editTemplate = (key: string, patch: Partial<Template>) =>\n edit({ emailTemplates: { ...data.emailTemplates, [key]: { ...data.emailTemplates[key], ...patch } as Template } });\n\n const run = async (key: string, fn: () => Promise<void>) => {\n setBusy(key);\n setNote(null);\n try {\n await fn();\n } catch (e) {\n setNote(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(null);\n }\n };\n const save = () =>\n run(\"save\", async () => {\n await adminFetch(ctx.getToken, \"/api/admin/group/email\", { method: \"PUT\", body: JSON.stringify(data) });\n setDraft(null);\n cfg.refresh();\n setNote(\"Saved.\");\n });\n const test = (template: string) =>\n run(`test:${template}`, async () => {\n const r = await adminFetch<{ ok: boolean; to: string; redirected: boolean }>(ctx.getToken, \"/api/admin/email/test\", { method: \"POST\", body: JSON.stringify({ template }) });\n setNote(r.ok ? `Sent ${template} to ${r.to}${r.redirected ? \" (dev-redirected)\" : \"\"}.` : \"Test send did not deliver.\");\n log.refresh();\n });\n\n return (\n <AdminPage>\n <Panel\n title=\"Delivery\"\n actions={<span className=\"muted\">{data.envName} · {data.transport}{data.fromEmail ? ` · ${data.fromEmail}` : \"\"}</span>}\n >\n <Field label=\"Notification address\"><Input value={data.notificationEmail} onChange={(e) => edit({ notificationEmail: (e.target as HTMLInputElement).value })} /></Field>\n <Field label=\"Reply-to\"><Input value={data.replyTo} onChange={(e) => edit({ replyTo: (e.target as HTMLInputElement).value })} /></Field>\n <Field label=\"Debug inbox\" hint=\"Non-prod sends redirect here.\"><Input value={data.debugEmail} onChange={(e) => edit({ debugEmail: (e.target as HTMLInputElement).value })} /></Field>\n </Panel>\n\n {Object.entries(data.emailTemplates).map(([key, t]) => (\n <Panel key={key} title={key} actions={<Button variant=\"secondary\" mini disabled={busy === `test:${key}`} onClick={() => void test(key)}>Send test</Button>}>\n <Checkbox label=\"Enabled\" checked={t.enabled} onChange={(e) => editTemplate(key, { enabled: (e.target as HTMLInputElement).checked })} />\n <Field label=\"Subject\"><Input value={t.subject} onChange={(e) => editTemplate(key, { subject: (e.target as HTMLInputElement).value })} /></Field>\n <Field label=\"Body\"><Textarea prose rows={5} value={t.text} onChange={(e) => editTemplate(key, { text: (e.target as HTMLTextAreaElement).value })} /></Field>\n </Panel>\n ))}\n\n <div style={{ display: \"flex\", gap: 12, alignItems: \"center\" }}>\n <Button disabled={!draft || busy === \"save\"} onClick={() => void save()}>Save changes</Button>\n {note ? <span className=\"muted\">{note}</span> : null}\n </div>\n\n <Panel title=\"Send log\">\n <DataTable rows={log.data?.sends ?? []} columns={LOG_COLUMNS} rowKey={(r) => r.id} />\n </Panel>\n </AdminPage>\n );\n}\n\n/** Options for {@link emailSection}. */\nexport interface EmailSectionOptions {\n id?: string;\n label?: string;\n}\n\n/** Build the Email admin section: template + address editor over\n * `GET/PUT /api/admin/group/email`, the send log, and per-template test sends. */\nexport function emailSection(options: EmailSectionOptions = {}): AdminSection {\n const { id = \"email\", label = \"Email\" } = options;\n return { id, label, render: (ctx) => <EmailBody ctx={ctx} /> };\n}\n","// Meetings section: the reconciled agenda from GET /api/admin/meetings, with the\n// reschedule and cancel actions wired to POST /api/admin/meetings/:id/{...}.\n// Built from odla-ui .panel + Button; drift against live Google state is flagged.\nimport { useState } from \"react\";\nimport { Button } from \"@odla-ai/ui/components\";\nimport { adminFetch, useAdminResource } from \"./admin-api.js\";\nimport { AdminPage, AdminNote, Panel } from \"./admin-layout.js\";\nimport type { AdminSection, AdminSectionContext } from \"./chrome.js\";\n\ninterface MeetingRow {\n id: string;\n startAt: number;\n endAt: number;\n status: string;\n drift: string;\n meetUrl: string | null;\n applicant: { name: string; email: string; status: string } | null;\n}\n\nconst when = (t: number): string => new Date(t).toLocaleString([], { dateStyle: \"medium\", timeStyle: \"short\" });\n\nfunction MeetingsBody({ ctx }: { ctx: AdminSectionContext }) {\n const { data, loading, error, refresh } = useAdminResource<{ meetings: MeetingRow[]; timezone: string }>(ctx.getToken, \"/api/admin/meetings?all=1\");\n const [busy, setBusy] = useState<string | null>(null);\n const [note, setNote] = useState<string | null>(null);\n if (loading) return <AdminNote>Loading…</AdminNote>;\n if (error || !data) return <AdminNote>Couldn’t load meetings{error ? `: ${error}` : \"\"}.</AdminNote>;\n\n const run = async (id: string, fn: () => Promise<void>) => {\n setBusy(id);\n setNote(null);\n try {\n await fn();\n refresh();\n } catch (e) {\n setNote(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(null);\n }\n };\n const cancel = (id: string) => {\n if (!globalThis.confirm?.(\"Cancel this call? Google notifies the attendee.\")) return;\n void run(id, () => adminFetch(ctx.getToken, `/api/admin/meetings/${id}/cancel`, { method: \"POST\" }));\n };\n const reschedule = (id: string) => {\n const input = globalThis.prompt?.(\"New start time (e.g. 2026-08-01 14:00):\");\n if (!input) return;\n const startAt = Date.parse(input);\n if (!Number.isFinite(startAt)) {\n setNote(\"Couldn’t parse that time.\");\n return;\n }\n void run(id, () => adminFetch(ctx.getToken, `/api/admin/meetings/${id}/reschedule`, { method: \"POST\", body: JSON.stringify({ startAt }) }));\n };\n\n return (\n <AdminPage>\n <Panel title={<>Agenda <span className=\"muted\" style={{ fontWeight: 400 }}>· {data.timezone}</span></>} actions={note ? <span className=\"muted\">{note}</span> : undefined}>\n {data.meetings.length === 0 ? (\n <p className=\"muted\" style={{ margin: 0 }}>No meetings.</p>\n ) : (\n <ul style={{ listStyle: \"none\", margin: 0, padding: 0, display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n {data.meetings.map((m) => (\n <li key={m.id} style={{ display: \"flex\", alignItems: \"center\", gap: 12, flexWrap: \"wrap\", opacity: m.status === \"cancelled\" ? 0.55 : 1 }}>\n <strong style={{ minWidth: 170 }}>{when(m.startAt)}</strong>\n <span style={{ flex: 1 }}>{m.applicant ? `${m.applicant.name} · ${m.applicant.email}` : \"(unknown)\"}</span>\n <span className=\"badge\">{m.status}</span>\n {m.drift && m.drift !== \"none\" ? <span className=\"badge\">drift: {m.drift}</span> : null}\n {m.meetUrl ? <a href={m.meetUrl} target=\"_blank\" rel=\"noreferrer\">Meet</a> : null}\n {m.status === \"scheduled\" ? (\n <>\n <Button variant=\"secondary\" mini disabled={busy === m.id} onClick={() => reschedule(m.id)}>Reschedule</Button>\n <Button variant=\"danger\" mini disabled={busy === m.id} onClick={() => cancel(m.id)}>Cancel</Button>\n </>\n ) : null}\n </li>\n ))}\n </ul>\n )}\n </Panel>\n </AdminPage>\n );\n}\n\n/** Options for {@link meetingsSection}. */\nexport interface MeetingsSectionOptions {\n id?: string;\n label?: string;\n}\n\n/** Build the Meetings admin section: the reconciled agenda over\n * `GET /api/admin/meetings`, with reschedule/cancel actions. */\nexport function meetingsSection(options: MeetingsSectionOptions = {}): AdminSection {\n const { id = \"meetings\", label = \"Meetings\" } = options;\n return { id, label, render: (ctx) => <MeetingsBody ctx={ctx} /> };\n}\n","// People/CRM admin section — the core admin workflow, assembled from the shipped\n// @odla-ai/crm/ui kit against the /api/crm/* routes the worker already mounts.\n// It's a FACTORY: peopleSection({ crm }) → an AdminSection you drop into\n// ChapterAdmin's `sections`. Every lifecycle action (edit fields, move pipeline\n// stage, tag) goes through the token-bound CrmClient — never a direct db write,\n// so the package's operational invariants hold (G7).\nimport { useState } from \"react\";\nimport { CrmList, RecordPanel, useCrmQuery, useCrmRecord } from \"@odla-ai/crm/ui\";\nimport type { Crm, CrmClient, CrmRecord } from \"@odla-ai/crm\";\nimport type { AdminSection } from \"./chrome.js\";\nimport { RecordActions } from \"./admin-record-actions.js\";\nimport { NetworkShareActions } from \"./admin-network.js\";\nimport { AdminPage } from \"./admin-layout.js\";\n\nconst DEFAULT_ROLES = [\"provisional\", \"member\", \"admin\"] as const;\n\nfunction PeopleBody(props: { crm: Crm; client: CrmClient; type: string; getToken: () => Promise<string | null>; roles: readonly string[]; lifecycle: boolean }) {\n const { crm, client, type, getToken, roles, lifecycle } = props;\n // The crm/ui hooks type their client against @odla-ai/crm's ui-entry bundled\n // declaration; ctx.client is the core-entry declaration. Same runtime class,\n // but their private field makes the two .d.ts copies nominally distinct — cast\n // to the param type the hooks expect.\n const hookClient = client as unknown as Parameters<typeof useCrmQuery>[0];\n const query = useCrmQuery(hookClient, type);\n const [openId, setOpenId] = useState<string | null>(null);\n const record = useCrmRecord(hookClient, openId);\n const [saving, setSaving] = useState(false);\n\n const saveFields = async (input: Record<string, unknown>) => {\n if (!openId) return;\n setSaving(true);\n try {\n await client.updateRecord(openId, { input });\n record.refresh();\n query.refresh();\n } finally {\n setSaving(false);\n }\n };\n const moveStage = async (to: string) => {\n if (!openId) return;\n await client.setStage(openId, to);\n record.refresh();\n query.refresh();\n };\n const addTag = async (tag: string) => {\n if (openId) {\n await client.addTag(openId, tag);\n record.refresh();\n }\n };\n const removeTag = async (tag: string) => {\n if (openId) {\n await client.removeTag(openId, tag);\n record.refresh();\n }\n };\n\n return (\n <AdminPage>\n <CrmList crm={crm} type={type} query={query} onOpenRecord={(r: CrmRecord) => setOpenId(r.id)} />\n {record.detail ? (\n <div>\n <RecordPanel\n crm={crm}\n detail={record.detail}\n onSaveFields={saveFields}\n onMoveStage={moveStage}\n onAddTag={addTag}\n onRemoveTag={removeTag}\n saving={saving}\n />\n {lifecycle ? (\n <RecordActions\n getToken={getToken}\n record={record.detail.record}\n roles={roles}\n onChanged={() => {\n record.refresh();\n query.refresh();\n }}\n />\n ) : null}\n <NetworkShareActions\n recordId={record.detail.record.id}\n recordType={record.detail.record.type}\n getToken={getToken}\n />\n </div>\n ) : null}\n </AdminPage>\n );\n}\n\n/** Options for {@link peopleSection}. */\nexport interface PeopleSectionOptions {\n /** The chapter's resolved CRM engine — `chapter.crm` from defineChapter. */\n crm: Crm;\n /** Section id / route segment. Default \"people\". */\n id?: string;\n /** Nav label. Default \"People\". */\n label?: string;\n /** The record type to list. Default \"person\". */\n type?: string;\n}\n\n/** Options for {@link collectionSection}. */\nexport interface CollectionSectionOptions {\n /** The chapter's resolved CRM engine — `chapter.crm` from defineChapter. */\n crm: Crm;\n /** The CRM record type to list (e.g. `\"person\"`, `\"deal\"`, `\"investment\"`). */\n type: string;\n /** Section id / route segment. Defaults to `type`. */\n id?: string;\n /** Nav label. Defaults to the type's plural label from the CRM config. */\n label?: string;\n /** Show the lifecycle action panel (role change / approve / refund) on an open\n * record — for application-backed people. Default `true` for `type: \"person\"`,\n * `false` otherwise (a `deal`/`investment` has no approve/refund). */\n lifecycle?: boolean;\n /** Role ladder for the role selector. Default `[\"provisional\",\"member\",\"admin\"]`\n * — pass your `chapter.auth.ladder` if you use a custom ladder. */\n roles?: readonly string[];\n}\n\n/**\n * Build a CRM collection admin section for ANY declared record type: a\n * server-driven records table plus a facet-composed detail drawer (fields,\n * pipeline stage, tags) over the token-bound CrmClient, and — for people — a\n * lifecycle action panel (role change, approve, refund) wired to the\n * `/api/admin/*` routes. This is the generic kit — call it once per collection a\n * site runs (members, deals, investments), and each renders with the same UX.\n * CRM edits go through `/api/crm/*` and lifecycle actions through `/api/admin/*`,\n * never a direct db write, so the invariants hold.\n */\nexport function collectionSection(options: CollectionSectionOptions): AdminSection {\n const { crm, type } = options;\n let fallbackLabel = type;\n try {\n fallbackLabel = crm.type(type).labelPlural ?? crm.type(type).label ?? type;\n } catch {\n // Unknown type — the section still renders; the CRM route reports the error.\n }\n const { id = type, label = fallbackLabel, lifecycle = type === \"person\", roles = DEFAULT_ROLES } = options;\n return { id, label, render: (ctx) => <PeopleBody crm={crm} client={ctx.client} type={type} getToken={ctx.getToken} roles={roles} lifecycle={lifecycle} /> };\n}\n\n/**\n * Build the People/CRM admin section — {@link collectionSection} preset to the\n * `person` type (so the lifecycle actions are on). New collections use\n * `collectionSection`.\n */\nexport function peopleSection(options: PeopleSectionOptions & { roles?: readonly string[] }): AdminSection {\n const { crm, id = \"people\", label = \"People\", type = \"person\", roles } = options;\n return collectionSection({ crm, type, id, label, ...(roles ? { roles } : {}) });\n}\n","// The lifecycle action panel shown beside an open person record: role change\n// (POST /api/admin/people/role), approve (POST /api/admin/applications/:id/\n// approve) and refund (POST .../refund). Each control appears only when the\n// record carries what it needs — a linked Clerk account for role, an\n// applicationId for approve/refund. Built from odla-ui Field/Select/Button.\nimport { useEffect, useState } from \"react\";\nimport { Button, Field, Select } from \"@odla-ai/ui/components\";\nimport { adminFetch } from \"./admin-api.js\";\nimport type { CrmRecord } from \"@odla-ai/crm\";\n\ninterface Access {\n role: string;\n superAdmin: boolean;\n}\n\n/** Props for {@link RecordActions}. */\nexport interface RecordActionsProps {\n getToken: () => Promise<string | null>;\n record: CrmRecord;\n /** The role ladder offered by the role selector. Default provisional→admin. */\n roles: readonly string[];\n /** Called after any action mutates state, so the caller can refresh. */\n onChanged: () => void;\n}\n\n/** The role/approve/refund controls for one person record. Renders only the\n * actions the record supports. */\nexport function RecordActions({ getToken, record, roles, onChanged }: RecordActionsProps) {\n const userId = typeof record.clerkUserId === \"string\" ? record.clerkUserId : null;\n const applicationId = typeof record.fields?.applicationId === \"string\" ? (record.fields.applicationId as string) : null;\n const [access, setAccess] = useState<Access | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n const [note, setNote] = useState<string | null>(null);\n\n useEffect(() => {\n if (!userId) {\n setAccess(null);\n return;\n }\n let live = true;\n adminFetch<Access>(getToken, `/api/admin/people/access?userId=${encodeURIComponent(userId)}`)\n .then((a) => live && setAccess(a))\n .catch(() => live && setAccess(null));\n return () => {\n live = false;\n };\n }, [getToken, userId]);\n\n const act = async (key: string, run: () => Promise<unknown>, ok: string) => {\n setBusy(key);\n setNote(null);\n try {\n await run();\n setNote(ok);\n onChanged();\n } catch (e) {\n setNote(e instanceof Error ? e.message : String(e));\n } finally {\n setBusy(null);\n }\n };\n const setRole = (role: string) =>\n act(\"role\", () => adminFetch(getToken, \"/api/admin/people/role\", { method: \"POST\", body: JSON.stringify({ userId, role }) }), `Role set to ${role}.`);\n const approve = () =>\n act(\"approve\", () => adminFetch(getToken, `/api/admin/applications/${applicationId}/approve`, { method: \"POST\" }), \"Approved.\");\n const refund = () =>\n act(\"refund\", () => adminFetch(getToken, `/api/admin/applications/${applicationId}/refund`, { method: \"POST\" }), \"Refund issued.\");\n\n if (!userId && !applicationId) return null;\n return (\n <section className=\"panel\" style={{ display: \"flex\", flexDirection: \"column\", gap: 14, marginTop: 16 }}>\n <h3 style={{ margin: 0, fontSize: 16 }}>Access &amp; lifecycle</h3>\n {userId ? (\n <Field label=\"Role\" hint={access?.superAdmin ? \"Super-admin — managed in odla Studio.\" : undefined}>\n <Select\n value={access?.role ?? \"\"}\n disabled={busy === \"role\" || access?.superAdmin}\n options={roles.map((r) => ({ value: r, label: r }))}\n onChange={(e) => void setRole((e.target as HTMLSelectElement).value)}\n />\n </Field>\n ) : (\n <p className=\"muted\" style={{ margin: 0 }}>No linked account yet — role is set once they sign in.</p>\n )}\n {applicationId ? (\n <div style={{ display: \"flex\", gap: 8 }}>\n <Button variant=\"secondary\" mini disabled={busy === \"approve\"} onClick={() => void approve()}>Approve</Button>\n <Button variant=\"danger\" mini disabled={busy === \"refund\"} onClick={() => void refund()}>Refund</Button>\n </div>\n ) : null}\n {note ? <p className=\"muted\" style={{ margin: 0 }}>{note}</p> : null}\n </section>\n );\n}\n","// Leader-side \"share to follower\" action. It is intentionally record-local:\n// the operator opens the person/business/deal they already reviewed, chooses a\n// configured follower, and sees an explicit delivery result.\nimport { useState } from \"react\";\nimport { adminFetch, useAdminResource } from \"./admin-api.js\";\n\ninterface Target {\n id: string;\n name: string;\n url: string;\n types: string[];\n}\n\ninterface TargetResponse {\n targets: Target[];\n}\n\ninterface PushResponse {\n ok: boolean;\n results: Array<{ id: string; name: string; ok: boolean; error?: string }>;\n}\n\n/** Props for {@link NetworkShareActions}. */\nexport interface NetworkShareActionsProps {\n recordId: string;\n recordType: string;\n getToken: () => Promise<string | null>;\n}\n\n/** Render follower delivery buttons when this chapter configured network\n * targets. Targets with an explicit type allowlist hide incompatible records. */\nexport function NetworkShareActions(props: NetworkShareActionsProps) {\n const { recordId, recordType, getToken } = props;\n const targets = useAdminResource<TargetResponse>(getToken, \"/api/admin/network/targets\");\n const [busy, setBusy] = useState<string | null>(null);\n const [message, setMessage] = useState<string | null>(null);\n const compatible = (targets.data?.targets ?? []).filter((target) => target.types.includes(recordType));\n\n if (targets.loading || targets.error || compatible.length === 0) return null;\n\n const push = async (target: Target) => {\n setBusy(target.id);\n setMessage(null);\n try {\n const result = await adminFetch<PushResponse>(getToken, \"/api/admin/network/push\", {\n method: \"POST\",\n body: JSON.stringify({ recordId, targetIds: [target.id] }),\n });\n const delivery = result.results[0];\n setMessage(delivery?.ok ? `Shared with ${target.name}.` : delivery?.error ?? `Could not share with ${target.name}.`);\n } catch (err) {\n setMessage(err instanceof Error ? err.message : \"Delivery failed.\");\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <section className=\"panel\" style={{ marginTop: 14, display: \"flex\", flexDirection: \"column\", gap: 10 }}>\n <div>\n <h3 style={{ margin: 0, fontSize: 16 }}>Share to a follower</h3>\n <p className=\"muted\" style={{ margin: \"4px 0 0\", fontSize: 13 }}>\n Sends the target's allowlisted fields. Its pipeline and account state remain local.\n </p>\n </div>\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: 8 }}>\n {compatible.map((target) => (\n <button className=\"btn secondary mini\" disabled={busy !== null} onClick={() => void push(target)} key={target.id}>\n {busy === target.id ? \"Sharing…\" : `Share with ${target.name}`}\n </button>\n ))}\n </div>\n {message ? <p role=\"status\" style={{ margin: 0, fontSize: 13 }}>{message}</p> : null}\n </section>\n );\n}\n","// The standard console composition derived from one resolved Chapter. A new\n// follower can render <ChapterAdmin chapter={chapter}/> and receives the same\n// collection/lifecycle surface as every other site; established sites may still\n// pass an explicit sections array to replace or extend it.\nimport type { Chapter } from \"../types\";\nimport type { AdminSection } from \"./chrome.js\";\nimport { availabilitySection } from \"./admin-availability.js\";\nimport { billingSection } from \"./admin-billing.js\";\nimport { dashboardSection } from \"./admin-dashboard.js\";\nimport { emailSection } from \"./admin-email.js\";\nimport { meetingsSection } from \"./admin-meetings.js\";\nimport { collectionSection } from \"./admin-people.js\";\n\n/** Build the familiar admin surface from a chapter's configured CRM types.\n * Hubs receive every CRM collection. Membership chapters additionally receive\n * dashboard, meeting, availability, billing, and email operations. */\nexport function defaultAdminSections(chapter: Chapter): AdminSection[] {\n const collections = Object.entries(chapter.crm.config.types).map(([type, def]) =>\n collectionSection({\n crm: chapter.crm,\n type,\n id: type === \"person\" ? \"people\" : type,\n label: def.labelPlural ?? def.label,\n lifecycle: chapter.mode === \"chapter\" && type === \"person\",\n roles: chapter.auth.ladder,\n }),\n );\n if (chapter.mode === \"hub\") return collections;\n return [\n dashboardSection(),\n ...collections,\n meetingsSection(),\n availabilitySection(),\n billingSection(),\n emailSection(),\n ];\n}\n"],"mappings":"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","names":["useEffect","useState","useEffect","useState","jsx","jsxs","section","useState","useEffect","useState","useCallback","useEffect","useState","jsx","jsxs","useState","jsx","jsxs","StatBand","Fragment","jsx","jsxs","money","StatBand","useState","Button","Checkbox","DataTable","Field","Input","jsx","jsxs","useState","Field","Input","Button","Checkbox","DataTable","useState","Button","Fragment","jsx","jsxs","when","useState","Button","useState","useEffect","useState","Button","Field","jsx","jsxs","useState","useEffect","Field","Button","useState","jsx","jsxs","useState","jsx","jsxs","useState","Fragment","jsx","jsxs","useState","useEffect"]}