@odla-ai/chapter 0.18.0 → 0.20.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.
@@ -0,0 +1,366 @@
1
+ import { CrmConfig, Crm } from '@odla-ai/crm';
2
+
3
+ /** Which feature profile a site runs. `chapter` is the full public member site
4
+ * (join, Stripe membership, booking, member area, admin, CRM); `hub` is
5
+ * admin-only and CRM-focused (a directory/registry over the same CRM). */
6
+ type ChapterMode = "chapter" | "hub";
7
+ /** The scalar kinds an odla-db attribute can hold. */
8
+ type AttrType = "string" | "number" | "boolean" | "json";
9
+ /** One odla-db attribute: its type and index/uniqueness/optionality flags. */
10
+ interface Attr {
11
+ type: AttrType;
12
+ unique: boolean;
13
+ indexed: boolean;
14
+ optional: boolean;
15
+ }
16
+ /** One odla-db namespace: its attribute map. */
17
+ interface Entity {
18
+ attrs: Record<string, Attr>;
19
+ }
20
+ /** A serialized odla-db schema fragment (namespaces + links). */
21
+ interface DbSchema {
22
+ entities: Record<string, Entity>;
23
+ links: Record<string, unknown>;
24
+ }
25
+ /** Per-namespace CEL rule strings (deny-all is `"false"` for each action). */
26
+ interface Rule {
27
+ view: string;
28
+ create: string;
29
+ update: string;
30
+ delete: string;
31
+ }
32
+ /** Namespace → rule set. */
33
+ type DbRules = Record<string, Rule>;
34
+ /** Brand tokens that theme the site: palette, fonts, wordmark, nav, logos. */
35
+ interface ChapterBrand {
36
+ /** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
37
+ * or `--ui-*` token names). Applies in BOTH light and dark unless overridden
38
+ * by {@link paletteDark}. */
39
+ palette?: Record<string, string>;
40
+ /** Dark-mode palette overrides. Same shape as {@link palette}; emitted under
41
+ * `:root[data-theme="dark"]` and `@media (prefers-color-scheme: dark)`, so a
42
+ * site brands both modes. */
43
+ paletteDark?: Record<string, string>;
44
+ fonts?: {
45
+ display?: string;
46
+ body?: string;
47
+ numeral?: string;
48
+ };
49
+ /** Short glyph used in compact admin chrome. Defaults to the first three
50
+ * letters of the chapter name. */
51
+ badge?: string;
52
+ wordmark?: string;
53
+ tagline?: string;
54
+ /** Header/footer nav sections for the web-component chrome: label → entries. */
55
+ nav?: Record<string, ReadonlyArray<{
56
+ label: string;
57
+ href: string;
58
+ }>>;
59
+ logos?: string;
60
+ }
61
+ /** One follower site a leader can push CRM records to. The secret VALUE never
62
+ * lives in config: `secretName` names the leader tenant's vaulted copy of the
63
+ * follower's `network_share_secret`. */
64
+ interface ChapterNetworkTarget {
65
+ /** Stable lowercase slug used by the UI, audit tags, and default secret name. */
66
+ id: string;
67
+ /** Human-facing site name. Defaults to `id`. */
68
+ name?: string;
69
+ /** Absolute follower origin, e.g. `https://silver.example.com`. */
70
+ url: string;
71
+ /** Leader-vault key holding this follower's share secret. Defaults to
72
+ * `network_share_<id-with-underscores>`. */
73
+ secretName?: string;
74
+ /** Per-record-type field allowlist. If present, omitted types cannot be sent
75
+ * to this target. Without it, package-safe person/company defaults apply. */
76
+ fields?: Record<string, readonly string[]>;
77
+ }
78
+ /** Leader/follower network configuration. Followers need no code config to
79
+ * receive records; they only vault `network_share_secret`. */
80
+ interface ChapterNetwork {
81
+ targets?: readonly ChapterNetworkTarget[];
82
+ }
83
+ /** A validated network target carried on the resolved chapter engine. */
84
+ interface ResolvedNetworkTarget {
85
+ id: string;
86
+ name: string;
87
+ url: string;
88
+ secretName: string;
89
+ fields?: Record<string, readonly string[]>;
90
+ }
91
+ /** Fully-resolved leader network configuration. */
92
+ interface ResolvedNetwork {
93
+ targets: readonly ResolvedNetworkTarget[];
94
+ }
95
+ /** Membership pricing for the group row (chapter mode). */
96
+ interface ChapterPrices {
97
+ standardCents: number;
98
+ foundingDiscountCents?: number;
99
+ /** ISO currency, default "usd". */
100
+ currency?: string;
101
+ /** Billing interval, default "year". */
102
+ interval?: "year" | "month";
103
+ }
104
+ /** Membership policy + compliance copy stored on the group row. */
105
+ interface ChapterPolicy {
106
+ disclaimerText?: string;
107
+ refundPolicyText?: string;
108
+ trustCopy?: string;
109
+ commitmentText?: string;
110
+ normsText?: string;
111
+ }
112
+ /** One owner-editable transactional email template. */
113
+ interface EmailTemplate {
114
+ subject: string;
115
+ text: string;
116
+ enabled?: boolean;
117
+ }
118
+ /** Notification/reply/debug addresses + operational email templates. */
119
+ interface ChapterEmails {
120
+ notificationEmail: string;
121
+ replyTo?: string;
122
+ debugEmail?: string;
123
+ /** Operational lifecycle templates: adminNotification / paymentConfirmation /
124
+ * prepEmail / onboardingInvite, each `{ subject, text, enabled? }`. */
125
+ templates?: Record<string, EmailTemplate>;
126
+ }
127
+ /** Booking rules for the intro-call scheduler (stored as schedulingJson). */
128
+ interface ChapterScheduling {
129
+ slotMinutes?: number;
130
+ days?: readonly number[];
131
+ startHour?: number;
132
+ endHour?: number;
133
+ timezone?: string;
134
+ minNoticeHours?: number;
135
+ windowDays?: number;
136
+ summaryTemplate?: string;
137
+ }
138
+ /** How a signed-in user's role is determined.
139
+ *
140
+ * - `"claim"` reads a role ladder from a JWT claim (Silver & Salt's model:
141
+ * `provisional → member → admin`). Admin is the last (highest) rung; the
142
+ * read-only `superAdmins` tier sits above it.
143
+ * - `"table"` gates on the deny-all `admins` allowlist (Built Not Found's model):
144
+ * a binary "email is an admin or isn't", set only in odla Studio.
145
+ *
146
+ * Defaults: `"claim"` in `chapter` mode, `"table"` in `hub` mode. */
147
+ interface ChapterAuth {
148
+ source?: "claim" | "table";
149
+ /** JWT claim holding the role, for `source: "claim"`. Default `"role"`. */
150
+ claim?: string;
151
+ /** Role ladder low→high, for `source: "claim"`. The last entry is admin.
152
+ * Default `["provisional", "member", "admin"]`. */
153
+ ladder?: readonly string[];
154
+ /** Provision the read-only `superAdmins` tier table — the only tier that may
155
+ * create/modify admins, and (like every namespace) deny-all + written only in
156
+ * odla Studio. Default: `true` for `"claim"`, `false` for `"table"`. */
157
+ superAdmins?: boolean;
158
+ }
159
+ /** The fully-resolved auth policy (defaults applied) carried on the {@link Chapter}. */
160
+ interface ResolvedAuth {
161
+ source: "claim" | "table";
162
+ claim: string;
163
+ ladder: readonly string[];
164
+ /** The highest ladder rung (last entry) — the "admin" gate. */
165
+ adminRole: string;
166
+ superAdmins: boolean;
167
+ }
168
+ /** The application status pipeline. Which statuses exist, and the subsets a site
169
+ * allows a call to be booked from / an application approved from. Defaults to
170
+ * Silver & Salt's pipeline. Status never moves backwards (package-enforced). */
171
+ interface ChapterPipeline {
172
+ stages?: readonly string[];
173
+ bookableFrom?: readonly string[];
174
+ approvableFrom?: readonly string[];
175
+ /** The status a new application starts at. Default: the first stage. */
176
+ initial?: string;
177
+ }
178
+ /** The fully-resolved pipeline (defaults applied) carried on the {@link Chapter}. */
179
+ interface ResolvedPipeline {
180
+ stages: readonly string[];
181
+ bookableFrom: readonly string[];
182
+ approvableFrom: readonly string[];
183
+ initial: string;
184
+ }
185
+ /** The application (join form) validation surface — which string fields are
186
+ * required vs accepted, their max lengths, and the request body cap. Drives
187
+ * submit validation + the CRM slot projection; defaults to Silver & Salt's form.
188
+ * The `applications` schema attrs stay fixed (byte-equal to S&S); this is
189
+ * validation config, not schema generation. */
190
+ interface ChapterApplication {
191
+ required?: readonly string[];
192
+ optional?: readonly string[];
193
+ /** Per-field character cap. Fields not listed use `defaultMaxLen`. */
194
+ maxLen?: Record<string, number>;
195
+ defaultMaxLen?: number;
196
+ /** Max JSON request body in bytes. Default 32768. */
197
+ bodyCap?: number;
198
+ /** Reject a submit that carries no truthy `disclaimerAck` (400), instead of
199
+ * writing a row with no consent record. Default `false` for back-compat —
200
+ * but turn it on if the disclaimer is a compliance record: a missing ack is
201
+ * otherwise silent, permanent and unreconstructible. Failure is deterministic
202
+ * and surfaces on the first test submit, not intermittently in production. */
203
+ requireDisclaimerAck?: boolean;
204
+ /** Allowlist of fields that reach the Clerk account's client-readable
205
+ * `public_metadata.profile`. Default (unset) projects every non-identity
206
+ * configured field — convenient, but it also exposes free-text and
207
+ * third-party fields (`message`, `referral`). Set this to a curated list
208
+ * (e.g. `["phone", "state", "focus"]`) to keep confidential fields db-only.
209
+ * Expected to become required-in-spirit at 1.0. */
210
+ profileFields?: readonly string[];
211
+ /** Extra application fields carried into the one-way CRM projection, on top of
212
+ * the built-in identity/contact set. Each MUST be declared on your crm person
213
+ * type or the enrichment is dropped (the base person still projects). Default
214
+ * none. */
215
+ crmFields?: readonly string[];
216
+ /** Cap on the element count of array-valued fields (e.g. `focus`), so a client
217
+ * cannot post a 10k-element array into a row or into Clerk metadata.
218
+ * Non-primitive elements are dropped. Default 100. */
219
+ maxArrayLen?: number;
220
+ /** Validate that a field literally named `email` looks like an email address,
221
+ * returning a 400 rather than accepting input the downstream Clerk create will
222
+ * reject anyway. Default `true`; a valid application is never newly rejected. */
223
+ validateEmail?: boolean;
224
+ }
225
+ /** The fully-resolved application config carried on the {@link Chapter}. */
226
+ interface ResolvedApplication {
227
+ required: readonly string[];
228
+ optional: readonly string[];
229
+ maxLen: Record<string, number>;
230
+ defaultMaxLen: number;
231
+ bodyCap: number;
232
+ requireDisclaimerAck: boolean;
233
+ /** Resolved Clerk-metadata allowlist; `null` means "all non-identity fields". */
234
+ profileFields: readonly string[] | null;
235
+ crmFields: readonly string[];
236
+ maxArrayLen: number;
237
+ validateEmail: boolean;
238
+ }
239
+ /** The `defineChapter()` config a site fills in. */
240
+ interface ChapterConfig {
241
+ /** Slug: app id, tenant, group id, worker name. `[a-z0-9-]`. */
242
+ id: string;
243
+ name: string;
244
+ url?: string;
245
+ /** Default `"chapter"`. */
246
+ mode?: ChapterMode;
247
+ /** A `defineCrm()` config or a resolved `Crm`. Omit for the per-mode default. */
248
+ crm?: CrmConfig | Crm;
249
+ brand?: ChapterBrand;
250
+ /** Leader → follower delivery targets. Secret values stay in the leader
251
+ * tenant vault; see {@link ChapterNetworkTarget}. */
252
+ network?: ChapterNetwork;
253
+ thesis?: unknown;
254
+ /** Required in `chapter` mode. */
255
+ prices?: ChapterPrices;
256
+ policy?: ChapterPolicy;
257
+ /** `notificationEmail` required in `chapter` mode. */
258
+ emails?: ChapterEmails;
259
+ scheduling?: ChapterScheduling;
260
+ /** Application status pipeline (stages + bookable/approvable subsets). Defaults to S&S's. */
261
+ pipeline?: ChapterPipeline;
262
+ /** Join-form validation (required/optional fields, max lengths, body cap). */
263
+ application?: ChapterApplication;
264
+ /** Role source + ladder + super-admin tier. Defaults by mode (see {@link ChapterAuth}). */
265
+ auth?: ChapterAuth;
266
+ /** odla services (db implied). Default `["db","calendar","o11y"]`. */
267
+ services?: readonly string[];
268
+ /** Apply-time account provisioning. **Default `"none"`** — it provisions
269
+ * nothing, because the alternatives have an outbound side effect and a site
270
+ * that never made the choice must not be mailing people. `"create"` makes the
271
+ * Clerk account server-side (so join can say the account is ready);
272
+ * `"invite"` **emails the applicant a Clerk invitation**. Both non-default
273
+ * models need a `clerk_secret_key` vault secret to act. Opt in explicitly —
274
+ * leaving this unset provisions no accounts. */
275
+ account?: AccountModel;
276
+ /** WHEN lifecycle email fires. Addressing and content live on the group row
277
+ * (owner-editable at runtime); this is the trigger, which is a build-time
278
+ * decision. See {@link ChapterSends}. */
279
+ sends?: ChapterSends;
280
+ /** Site policy for admin operations (approve side effects, refund rules).
281
+ * See {@link ChapterOperations}. */
282
+ operations?: ChapterOperations;
283
+ }
284
+ /** Apply-time Clerk account provisioning model. */
285
+ type AccountModel = "invite" | "create" | "none";
286
+ /** Site policy for admin OPERATIONS: the DECISIONS, where the mechanics stay
287
+ * package-owned. Same model as {@link ChapterSends} — a site declares the rule,
288
+ * chapter enforces it. Distinct from {@link ChapterPolicy}, which is member-facing
289
+ * copy. (The privilege-escalation rules are NOT here: they are package-enforced
290
+ * in `canChangeRole`, gated on `auth.superAdmins`, so a site cannot weaken them.) */
291
+ interface ChapterOperations {
292
+ /** What approving an application does. */
293
+ onApprove?: {
294
+ /** Role to promote the applicant to in Clerk. Defaults to the ladder rung
295
+ * directly below admin (e.g. `"member"`); `false` promotes nobody. */
296
+ promoteTo?: string | false;
297
+ /** Group email template to send on approve. Default `"onboardingInvite"`;
298
+ * `false` sends nothing. */
299
+ send?: string | false;
300
+ };
301
+ /** Refund rules. */
302
+ refund?: {
303
+ /** Application statuses a refund may be issued from. Default: any status. */
304
+ allowedFrom?: readonly string[];
305
+ /** Also cancel the Stripe subscription. Default `true`. */
306
+ cancelSubscription?: boolean;
307
+ };
308
+ }
309
+ /** The fully-resolved {@link ChapterOperations} carried on the {@link Chapter}. */
310
+ interface ResolvedOperations {
311
+ onApprove: {
312
+ promoteTo: string | false;
313
+ send: string | false;
314
+ };
315
+ /** `allowedFrom: null` means "any status". */
316
+ refund: {
317
+ allowedFrom: readonly string[] | null;
318
+ cancelSubscription: boolean;
319
+ };
320
+ }
321
+ /** When the admin notification fires: on application `submit` (default), on the
322
+ * first successful `payment`, or `never` (the site drives it itself). */
323
+ type AdminNotificationTrigger = "submit" | "payment" | "never";
324
+ /** Send-policy config: the trigger for each lifecycle email chapter owns. */
325
+ interface ChapterSends {
326
+ adminNotification?: AdminNotificationTrigger;
327
+ }
328
+ /** Resolved send policy (every trigger present). */
329
+ interface ResolvedSends {
330
+ adminNotification: AdminNotificationTrigger;
331
+ }
332
+ /** The resolved engine `defineChapter()` returns. */
333
+ interface Chapter {
334
+ config: ChapterConfig;
335
+ id: string;
336
+ name: string;
337
+ url?: string;
338
+ mode: ChapterMode;
339
+ /** Resolved site identity. `wordmark` always falls back to `name`, so the
340
+ * admin/member UI never needs a second brand declaration. */
341
+ brand: ChapterBrand;
342
+ /** Validated follower targets for leader-driven record pushes. */
343
+ network: ResolvedNetwork;
344
+ /** Resolved CRM engine (from `defineCrm`). */
345
+ crm: Crm;
346
+ /** Resolved auth policy (source, claim, ladder, super-admin tier). */
347
+ auth: ResolvedAuth;
348
+ /** Resolved application status pipeline (stages + bookable/approvable subsets). */
349
+ pipeline: ResolvedPipeline;
350
+ /** Resolved join-form validation config. */
351
+ application: ResolvedApplication;
352
+ /** The chapter's own odla-db namespaces (mode-dependent; excludes `crm_*`). */
353
+ schema: DbSchema;
354
+ rules: DbRules;
355
+ services: readonly string[];
356
+ /** Resolved apply-time account provisioning model (default `"none"`). */
357
+ account: AccountModel;
358
+ /** Resolved send policy — when each lifecycle email fires. */
359
+ sends: ResolvedSends;
360
+ /** Resolved admin-operation policy (approve side effects, refund rules). */
361
+ operations: ResolvedOperations;
362
+ /** The seed `groups` row derived from config (chapter mode), else `null`. */
363
+ groupSeed(): Record<string, unknown> | null;
364
+ }
365
+
366
+ export type { Chapter as C, ChapterBrand as a };
@@ -1,6 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { CrmClient, Crm, CrmRecord } from '@odla-ai/crm';
4
+ import { C as Chapter } from '../../types-D2fGiNG8.js';
4
5
 
5
6
  /** What each admin section receives. `client` is a CrmClient bound to the
6
7
  * signed-in admin's bearer token; `navigate` switches sections. */
@@ -16,6 +17,11 @@ interface AdminSection {
16
17
  label: string;
17
18
  render: (ctx: AdminSectionContext) => ReactNode;
18
19
  }
20
+ /** How admin section state is reflected in the URL. Query routing is the
21
+ * host-independent default: `/admin/?tab=people` reloads through the same static
22
+ * file on SPA and multi-page sites alike. Path routing requires a host SPA
23
+ * fallback for every `/admin/<section>` URL. */
24
+ type AdminRouting = "query" | "path";
19
25
  /** Wordmark shown in the gate and top bar. `name` is the plain-text identity (and
20
26
  * the badge fallback); `wordmark` is an optional rich display node for brands
21
27
  * whose typography can't be a plain string (e.g. an ampersand wrapped to render
@@ -25,11 +31,20 @@ type Brand = {
25
31
  badge?: string;
26
32
  wordmark?: ReactNode;
27
33
  };
34
+ /** Resolve a section from the stable `?tab=` URL first, then a legacy path
35
+ * segment for backwards-compatible deep links. */
36
+ declare function adminSectionFromUrl(url: URL, basePath: string, sectionIds: readonly string[]): string;
37
+ /** Build the next section URL without depending on the static host's 404/SPA
38
+ * policy. Query mode collapses a legacy path route back to the admin mount. */
39
+ declare function adminSectionHref(current: URL, basePath: string, id: string, routing?: AdminRouting): string;
28
40
 
29
41
  /** Props for {@link ChapterAdmin}. */
30
42
  interface ChapterAdminProps {
31
- /** The admin sections to render (nav label + body). */
32
- sections: AdminSection[];
43
+ /** The resolved site config. When present it supplies the brand and, unless
44
+ * `sections` is passed, the complete standard section catalog. */
45
+ chapter?: Chapter;
46
+ /** Explicit admin sections. Omit with `chapter` for the standard console. */
47
+ sections?: AdminSection[];
33
48
  /** Admin mount path. The sign-in redirect + section routing derive from it,
34
49
  * so the "bounce to home after sign-in" bug is impossible. Default "/admin". */
35
50
  basePath?: string;
@@ -39,6 +54,10 @@ interface ChapterAdminProps {
39
54
  crmBasePath?: string;
40
55
  /** Origin for /api/config and /api/me. Default same origin. */
41
56
  apiBase?: string;
57
+ /** Section URL strategy. Default `"query"` (`/admin/?tab=people`), which
58
+ * works with both SPA and ordinary static hosting. `"path"` requires the host
59
+ * to serve the admin entry for every `/admin/<section>` URL. */
60
+ routing?: AdminRouting;
42
61
  }
43
62
  /**
44
63
  * The whole admin console for a chapter/hub: fetches the Clerk publishable key
@@ -49,6 +68,11 @@ interface ChapterAdminProps {
49
68
  */
50
69
  declare function ChapterAdmin(props: ChapterAdminProps): react.JSX.Element;
51
70
 
71
+ /** Build the familiar admin surface from a chapter's configured CRM types.
72
+ * Hubs receive every CRM collection. Membership chapters additionally receive
73
+ * dashboard, meeting, availability, billing, and email operations. */
74
+ declare function defaultAdminSections(chapter: Chapter): AdminSection[];
75
+
52
76
  /** Options for {@link peopleSection}. */
53
77
  interface PeopleSectionOptions {
54
78
  /** The chapter's resolved CRM engine — `chapter.crm` from defineChapter. */
@@ -103,8 +127,7 @@ interface DashboardSectionOptions {
103
127
  id?: string;
104
128
  label?: string;
105
129
  }
106
- /** Build the Dashboard admin section over `GET /api/admin/dashboard`. Drop the
107
- * result into `ChapterAdmin`'s `sections`. */
130
+ /** Build the Dashboard admin section over `GET /api/admin/dashboard`. */
108
131
  declare function dashboardSection(options?: DashboardSectionOptions): AdminSection;
109
132
 
110
133
  /** Options for {@link billingSection}. */
@@ -156,6 +179,16 @@ interface RecordActionsProps {
156
179
  * actions the record supports. */
157
180
  declare function RecordActions({ getToken, record, roles, onChanged }: RecordActionsProps): react.JSX.Element | null;
158
181
 
182
+ /** Props for {@link NetworkShareActions}. */
183
+ interface NetworkShareActionsProps {
184
+ recordId: string;
185
+ recordType: string;
186
+ getToken: () => Promise<string | null>;
187
+ }
188
+ /** Render follower delivery buttons when this chapter configured network
189
+ * targets. Targets with an explicit type allowlist hide incompatible records. */
190
+ declare function NetworkShareActions(props: NetworkShareActionsProps): react.JSX.Element | null;
191
+
159
192
  /** Fetch a JSON `/api/admin/*` route with the admin bearer token. Throws on a
160
193
  * non-2xx (the body's `error`, else the status). */
161
194
  declare function adminFetch<T = unknown>(getToken: () => Promise<string | null>, path: string, init?: RequestInit): Promise<T>;
@@ -171,4 +204,22 @@ interface AdminResource<T> {
171
204
  * or when `path` changes. */
172
205
  declare function useAdminResource<T = unknown>(getToken: () => Promise<string | null>, path: string): AdminResource<T>;
173
206
 
174
- export { type AdminResource, type AdminSection, type AdminSectionContext, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminProps, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, type PeopleSectionOptions, RecordActions, type RecordActionsProps, adminFetch, availabilitySection, billingSection, collectionSection, dashboardSection, emailSection, meetingsSection, peopleSection, useAdminResource };
207
+ /** The centered content column every admin section renders into. */
208
+ declare function AdminPage({ children }: {
209
+ children: ReactNode;
210
+ }): react.JSX.Element;
211
+ /** An odla-ui `.panel` card with an optional heading + trailing actions. */
212
+ declare function Panel({ title, actions, children }: {
213
+ title?: ReactNode;
214
+ actions?: ReactNode;
215
+ children: ReactNode;
216
+ }): react.JSX.Element;
217
+ /** A loud banner when the odla-ui theme token layer is missing — the silent-and-
218
+ * total failure S&S flagged. Renders nothing when the theme is present. */
219
+ declare function ThemeWarning(): react.JSX.Element | null;
220
+ /** A centered status line for loading / empty / error states. */
221
+ declare function AdminNote({ children }: {
222
+ children: ReactNode;
223
+ }): react.JSX.Element;
224
+
225
+ export { AdminNote, AdminPage, type AdminResource, type AdminRouting, type AdminSection, type AdminSectionContext, type AvailabilitySectionOptions, type BillingSectionOptions, ChapterAdmin, type ChapterAdminProps, type CollectionSectionOptions, type DashboardSectionOptions, type EmailSectionOptions, type MeetingsSectionOptions, NetworkShareActions, type NetworkShareActionsProps, Panel, type PeopleSectionOptions, RecordActions, type RecordActionsProps, ThemeWarning, adminFetch, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, emailSection, meetingsSection, peopleSection, useAdminResource };
@@ -1,24 +1,41 @@
1
1
  import {
2
+ AdminNote,
3
+ AdminPage,
2
4
  ChapterAdmin,
5
+ NetworkShareActions,
6
+ Panel,
3
7
  RecordActions,
8
+ ThemeWarning,
4
9
  adminFetch,
10
+ adminSectionFromUrl,
11
+ adminSectionHref,
5
12
  availabilitySection,
6
13
  billingSection,
7
14
  collectionSection,
8
15
  dashboardSection,
16
+ defaultAdminSections,
9
17
  emailSection,
10
18
  meetingsSection,
11
19
  peopleSection,
12
20
  useAdminResource
13
- } from "../../chunk-K6BDIFCJ.js";
21
+ } from "../../chunk-UIWFEESI.js";
22
+ import "../../chunk-MKXHZMAP.js";
14
23
  export {
24
+ AdminNote,
25
+ AdminPage,
15
26
  ChapterAdmin,
27
+ NetworkShareActions,
28
+ Panel,
16
29
  RecordActions,
30
+ ThemeWarning,
17
31
  adminFetch,
32
+ adminSectionFromUrl,
33
+ adminSectionHref,
18
34
  availabilitySection,
19
35
  billingSection,
20
36
  collectionSection,
21
37
  dashboardSection,
38
+ defaultAdminSections,
22
39
  emailSection,
23
40
  meetingsSection,
24
41
  peopleSection,
@@ -1,4 +1,5 @@
1
- export { AdminResource, AdminSection, AdminSectionContext, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminProps, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, PeopleSectionOptions, RecordActions, RecordActionsProps, adminFetch, availabilitySection, billingSection, collectionSection, dashboardSection, emailSection, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
1
+ export { AdminNote, AdminPage, AdminResource, AdminRouting, AdminSection, AdminSectionContext, AvailabilitySectionOptions, BillingSectionOptions, ChapterAdmin, ChapterAdminProps, CollectionSectionOptions, DashboardSectionOptions, EmailSectionOptions, MeetingsSectionOptions, NetworkShareActions, NetworkShareActionsProps, Panel, PeopleSectionOptions, RecordActions, RecordActionsProps, ThemeWarning, adminFetch, adminSectionFromUrl, adminSectionHref, availabilitySection, billingSection, collectionSection, dashboardSection, defaultAdminSections, emailSection, meetingsSection, peopleSection, useAdminResource } from './admin/index.js';
2
2
  export { ApiFn, BrandStyle, BrandStyleProps, JoinConfig, JoinIsland, JoinIslandProps, MembersArea, MembersAreaProps, PaymentStep, PaymentStepProps, RescheduleProps, Rescheduler, Slot, SlotPicker, SlotPickerClasses, SlotPickerProps, dayKey, dayLabel, fmtDate, fmtMoney, fullLabel, groupSlotsByDay, timeLabel, tzShort } from './member/index.js';
3
3
  import 'react';
4
4
  import '@odla-ai/crm';
5
+ import '../types-D2fGiNG8.js';
package/dist/ui/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import {
2
- BrandStyle,
3
2
  JoinIsland,
4
3
  MembersArea,
5
4
  PaymentStep,
@@ -13,36 +12,55 @@ import {
13
12
  groupSlotsByDay,
14
13
  timeLabel,
15
14
  tzShort
16
- } from "../chunk-ZCZK6QLC.js";
15
+ } from "../chunk-LME2IHY5.js";
17
16
  import {
17
+ AdminNote,
18
+ AdminPage,
18
19
  ChapterAdmin,
20
+ NetworkShareActions,
21
+ Panel,
19
22
  RecordActions,
23
+ ThemeWarning,
20
24
  adminFetch,
25
+ adminSectionFromUrl,
26
+ adminSectionHref,
21
27
  availabilitySection,
22
28
  billingSection,
23
29
  collectionSection,
24
30
  dashboardSection,
31
+ defaultAdminSections,
25
32
  emailSection,
26
33
  meetingsSection,
27
34
  peopleSection,
28
35
  useAdminResource
29
- } from "../chunk-K6BDIFCJ.js";
36
+ } from "../chunk-UIWFEESI.js";
37
+ import {
38
+ BrandStyle
39
+ } from "../chunk-MKXHZMAP.js";
30
40
  export {
41
+ AdminNote,
42
+ AdminPage,
31
43
  BrandStyle,
32
44
  ChapterAdmin,
33
45
  JoinIsland,
34
46
  MembersArea,
47
+ NetworkShareActions,
48
+ Panel,
35
49
  PaymentStep,
36
50
  RecordActions,
37
51
  Rescheduler,
38
52
  SlotPicker,
53
+ ThemeWarning,
39
54
  adminFetch,
55
+ adminSectionFromUrl,
56
+ adminSectionHref,
40
57
  availabilitySection,
41
58
  billingSection,
42
59
  collectionSection,
43
60
  dashboardSection,
44
61
  dayKey,
45
62
  dayLabel,
63
+ defaultAdminSections,
46
64
  emailSection,
47
65
  fmtDate,
48
66
  fmtMoney,
@@ -1,5 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
+ import { a as ChapterBrand } from '../../types-D2fGiNG8.js';
4
+ import '@odla-ai/crm';
3
5
 
4
6
  /** A bookable slot: a start instant in epoch milliseconds. */
5
7
  interface Slot {
@@ -121,26 +123,6 @@ interface PaymentStepProps {
121
123
  * → mount Stripe Elements → confirm. */
122
124
  declare function PaymentStep(props: PaymentStepProps): react.JSX.Element;
123
125
 
124
- /** Brand tokens that theme the site: palette, fonts, wordmark, nav, logos. */
125
- interface ChapterBrand {
126
- /** Palette overrides written into styles.css :root (e.g. `{ moss: "#2F3E34" }`
127
- * or `--ui-*` token names). */
128
- palette?: Record<string, string>;
129
- fonts?: {
130
- display?: string;
131
- body?: string;
132
- numeral?: string;
133
- };
134
- wordmark?: string;
135
- tagline?: string;
136
- /** Header/footer nav sections for the web-component chrome: label → entries. */
137
- nav?: Record<string, ReadonlyArray<{
138
- label: string;
139
- href: string;
140
- }>>;
141
- logos?: string;
142
- }
143
-
144
126
  /** Props for {@link BrandStyle}. */
145
127
  interface BrandStyleProps {
146
128
  brand: ChapterBrand | undefined;
@@ -1,5 +1,4 @@
1
1
  import {
2
- BrandStyle,
3
2
  JoinIsland,
4
3
  MembersArea,
5
4
  PaymentStep,
@@ -13,7 +12,10 @@ import {
13
12
  groupSlotsByDay,
14
13
  timeLabel,
15
14
  tzShort
16
- } from "../../chunk-ZCZK6QLC.js";
15
+ } from "../../chunk-LME2IHY5.js";
16
+ import {
17
+ BrandStyle
18
+ } from "../../chunk-MKXHZMAP.js";
17
19
  export {
18
20
  BrandStyle,
19
21
  JoinIsland,