@base316/react 0.5.1 → 0.5.2

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/dist/index.cjs CHANGED
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  "use strict";
3
+ var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
6
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
9
  var __export = (target, all) => {
8
10
  for (var name in all)
@@ -16,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
16
18
  }
17
19
  return to;
18
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
19
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
30
 
21
31
  // index.ts
@@ -2092,7 +2102,9 @@ function SignIn({
2092
2102
  if (cause instanceof DOMException && (cause.name === "NotAllowedError" || cause.name === "AbortError")) {
2093
2103
  return;
2094
2104
  }
2095
- if (!conditional) {
2105
+ if (cause instanceof import_sdk3.Base316Error && cause.reason === "EMAIL_NOT_VERIFIED") {
2106
+ setError(cause.message);
2107
+ } else if (!conditional) {
2096
2108
  console.error("[base316] passkey sign-in failed", cause);
2097
2109
  setError("That passkey did not work.");
2098
2110
  }
@@ -3092,8 +3104,62 @@ function PrivacyControls({
3092
3104
  }
3093
3105
 
3094
3106
  // src/TwoFactorManager.tsx
3107
+ var import_react15 = require("react");
3108
+
3109
+ // src/QrCode.tsx
3110
+ var import_qrcode_generator = __toESM(require("qrcode-generator"));
3095
3111
  var import_react14 = require("react");
3096
3112
  var import_jsx_runtime16 = require("react/jsx-runtime");
3113
+ var QUIET_ZONE = 4;
3114
+ function utf8Binary(value) {
3115
+ let binary = "";
3116
+ for (const byte of new TextEncoder().encode(value)) {
3117
+ binary += String.fromCharCode(byte);
3118
+ }
3119
+ return binary;
3120
+ }
3121
+ function qrPath(value) {
3122
+ const code = (0, import_qrcode_generator.default)(0, "M");
3123
+ code.addData(utf8Binary(value), "Byte");
3124
+ code.make();
3125
+ const modules = code.getModuleCount();
3126
+ let path = "";
3127
+ for (let row = 0; row < modules; row += 1) {
3128
+ for (let col = 0; col < modules; col += 1) {
3129
+ if (code.isDark(row, col)) {
3130
+ path += `M${col + QUIET_ZONE} ${row + QUIET_ZONE}h1v1h-1z`;
3131
+ }
3132
+ }
3133
+ }
3134
+ return { path, modules };
3135
+ }
3136
+ function QrCode({ value, label, size = 180, className }) {
3137
+ const { path, modules } = (0, import_react14.useMemo)(() => qrPath(value), [value]);
3138
+ const extent = modules + QUIET_ZONE * 2;
3139
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3140
+ "svg",
3141
+ {
3142
+ className,
3143
+ role: "img",
3144
+ "aria-label": label,
3145
+ width: size,
3146
+ height: size,
3147
+ viewBox: `0 0 ${extent} ${extent}`,
3148
+ shapeRendering: "crispEdges",
3149
+ xmlns: "http://www.w3.org/2000/svg",
3150
+ children: [
3151
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("rect", { width: extent, height: extent, fill: "#ffffff" }),
3152
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: path, fill: "#000000" })
3153
+ ]
3154
+ }
3155
+ );
3156
+ }
3157
+
3158
+ // src/TwoFactorManager.tsx
3159
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3160
+ function groupKey(secret) {
3161
+ return secret.replace(/\s+/g, "").replace(/(.{4})(?=.)/g, "$1 ");
3162
+ }
3097
3163
  function TwoFactorManager({
3098
3164
  enabled = false,
3099
3165
  allowSms = false,
@@ -3103,12 +3169,12 @@ function TwoFactorManager({
3103
3169
  style
3104
3170
  }) {
3105
3171
  const { client, token } = useBase316();
3106
- const [stage, setStage] = (0, import_react14.useState)({ name: "idle" });
3107
- const [on, setOn] = (0, import_react14.useState)(enabled);
3108
- const [code, setCode] = (0, import_react14.useState)("");
3109
- const [phone, setPhone] = (0, import_react14.useState)("");
3110
- const [error, setError] = (0, import_react14.useState)(null);
3111
- const [busy, setBusy] = (0, import_react14.useState)(false);
3172
+ const [stage, setStage] = (0, import_react15.useState)({ name: "idle" });
3173
+ const [on, setOn] = (0, import_react15.useState)(enabled);
3174
+ const [code, setCode] = (0, import_react15.useState)("");
3175
+ const [phone, setPhone] = (0, import_react15.useState)("");
3176
+ const [error, setError] = (0, import_react15.useState)(null);
3177
+ const [busy, setBusy] = (0, import_react15.useState)(false);
3112
3178
  if (!token) {
3113
3179
  return null;
3114
3180
  }
@@ -3186,17 +3252,17 @@ function TwoFactorManager({
3186
3252
  setBusy(false);
3187
3253
  }
3188
3254
  }
3189
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3190
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3191
- error ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3192
- stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-codes", children: [
3193
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3194
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("code", { children: recovery }) }, recovery)) }),
3195
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3196
- ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-enrol", children: [
3197
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3198
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3199
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3255
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card b316-mfa", className), style, children: [
3256
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-mfa-title", children: "Two-factor authentication" }),
3257
+ error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3258
+ stage.name === "saved" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-codes", children: [
3259
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Save these recovery codes somewhere safe. Each one signs you in once if you lose your authenticator, and they are not shown again." }),
3260
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("ul", { className: "b316-mfa-code-list", children: stage.recoveryCodes.map((recovery) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("code", { children: recovery }) }, recovery)) }),
3261
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", onClick: () => setStage({ name: "idle" }), children: "I have saved them" })
3262
+ ] }) : stage.name === "smsNumber" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3263
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "We will text a code to this number now, and each time you sign in." }),
3264
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-phone", children: "Mobile number" }),
3265
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3200
3266
  "input",
3201
3267
  {
3202
3268
  id: "b316-mfa-phone",
@@ -3208,8 +3274,8 @@ function TwoFactorManager({
3208
3274
  onChange: (event) => setPhone(event.target.value)
3209
3275
  }
3210
3276
  ),
3211
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-actions", children: [
3212
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3277
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3278
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3213
3279
  "button",
3214
3280
  {
3215
3281
  type: "button",
@@ -3218,16 +3284,16 @@ function TwoFactorManager({
3218
3284
  children: "Cancel"
3219
3285
  }
3220
3286
  ),
3221
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3287
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: beginSms, children: busy ? "Sending\u2026" : "Send code" })
3222
3288
  ] })
3223
- ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-enrol", children: [
3224
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("p", { children: [
3289
+ ] }) : stage.name === "enrollingEmail" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3290
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { children: [
3225
3291
  "We sent a code to ",
3226
3292
  stage.destinationHint,
3227
3293
  ". Enter it below to turn this on."
3228
3294
  ] }),
3229
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3230
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3295
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3296
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3231
3297
  "input",
3232
3298
  {
3233
3299
  id: "b316-mfa-code",
@@ -3238,8 +3304,8 @@ function TwoFactorManager({
3238
3304
  onChange: (event) => setCode(event.target.value)
3239
3305
  }
3240
3306
  ),
3241
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-actions", children: [
3242
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3307
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3308
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3243
3309
  "button",
3244
3310
  {
3245
3311
  type: "button",
@@ -3248,7 +3314,7 @@ function TwoFactorManager({
3248
3314
  children: "Cancel"
3249
3315
  }
3250
3316
  ),
3251
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3317
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3252
3318
  "button",
3253
3319
  {
3254
3320
  type: "button",
@@ -3259,12 +3325,23 @@ function TwoFactorManager({
3259
3325
  }
3260
3326
  )
3261
3327
  ] })
3262
- ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-enrol", children: [
3263
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: "Add this to your authenticator app, then enter the six-digit code it shows." }),
3264
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "b316-mfa-secret", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("code", { children: stage.secret }) }),
3265
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3266
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3267
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3328
+ ] }) : stage.name === "enrolling" ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-enrol", children: [
3329
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { children: "Scan this with your authenticator app (Google Authenticator, 1Password, Authy\u2026), then enter the six-digit code it shows." }),
3330
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3331
+ QrCode,
3332
+ {
3333
+ className: "b316-mfa-qr",
3334
+ value: stage.uri,
3335
+ label: "QR code for your authenticator app"
3336
+ }
3337
+ ),
3338
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-secret", children: [
3339
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "b316-label", id: "b316-mfa-manual-key", children: "Can't scan? Enter this key" }),
3340
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("code", { "aria-labelledby": "b316-mfa-manual-key", children: groupKey(stage.secret) })
3341
+ ] }),
3342
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { className: "b316-mfa-uri", href: stage.uri, children: "Open in an authenticator app" }),
3343
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-mfa-code", children: "Code" }),
3344
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3268
3345
  "input",
3269
3346
  {
3270
3347
  id: "b316-mfa-code",
@@ -3275,8 +3352,8 @@ function TwoFactorManager({
3275
3352
  onChange: (event) => setCode(event.target.value)
3276
3353
  }
3277
3354
  ),
3278
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-actions", children: [
3279
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3355
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3356
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3280
3357
  "button",
3281
3358
  {
3282
3359
  type: "button",
@@ -3285,7 +3362,7 @@ function TwoFactorManager({
3285
3362
  children: "Cancel"
3286
3363
  }
3287
3364
  ),
3288
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3365
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3289
3366
  "button",
3290
3367
  {
3291
3368
  type: "button",
@@ -3296,9 +3373,9 @@ function TwoFactorManager({
3296
3373
  }
3297
3374
  )
3298
3375
  ] })
3299
- ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-on", children: [
3300
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3301
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3376
+ ] }) : on ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-on", children: [
3377
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "On. You will be asked for a code when you sign in." }),
3378
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3302
3379
  ConfirmButton,
3303
3380
  {
3304
3381
  className: "b316-button-quiet b316-danger",
@@ -3308,11 +3385,11 @@ function TwoFactorManager({
3308
3385
  children: "Turn off"
3309
3386
  }
3310
3387
  )
3311
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-off", children: [
3312
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3313
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "b316-mfa-actions", children: [
3314
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3315
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3388
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-off", children: [
3389
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "b316-muted", children: "Off. Turning it on means a code as well as your password, every time you sign in." }),
3390
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-mfa-actions", children: [
3391
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: begin, children: busy ? "Starting\u2026" : "Use an authenticator app" }),
3392
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3316
3393
  "button",
3317
3394
  {
3318
3395
  type: "button",
@@ -3322,7 +3399,7 @@ function TwoFactorManager({
3322
3399
  children: "Email me a code"
3323
3400
  }
3324
3401
  ),
3325
- allowSms ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3402
+ allowSms ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3326
3403
  "button",
3327
3404
  {
3328
3405
  type: "button",
@@ -3338,14 +3415,14 @@ function TwoFactorManager({
3338
3415
  }
3339
3416
 
3340
3417
  // src/ForgotPassword.tsx
3341
- var import_react15 = require("react");
3342
- var import_jsx_runtime17 = require("react/jsx-runtime");
3418
+ var import_react16 = require("react");
3419
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3343
3420
  function ForgotPassword({ onSent, signInUrl, className, style }) {
3344
3421
  const { client } = useBase316();
3345
- const [email, setEmail] = (0, import_react15.useState)("");
3346
- const [sent, setSent] = (0, import_react15.useState)(false);
3347
- const [busy, setBusy] = (0, import_react15.useState)(false);
3348
- const [error, setError] = (0, import_react15.useState)(null);
3422
+ const [email, setEmail] = (0, import_react16.useState)("");
3423
+ const [sent, setSent] = (0, import_react16.useState)(false);
3424
+ const [busy, setBusy] = (0, import_react16.useState)(false);
3425
+ const [error, setError] = (0, import_react16.useState)(null);
3349
3426
  async function submit(event) {
3350
3427
  event.preventDefault();
3351
3428
  setBusy(true);
@@ -3361,22 +3438,22 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3361
3438
  }
3362
3439
  }
3363
3440
  if (sent) {
3364
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: cls("b316-card", className), style, children: [
3365
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3366
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("p", { className: "b316-muted", children: [
3441
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card", className), style, children: [
3442
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Check your email" }),
3443
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "b316-muted", children: [
3367
3444
  "If there is an account for ",
3368
3445
  email.trim(),
3369
3446
  ", a link to set a new password is on its way."
3370
3447
  ] }),
3371
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3448
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3372
3449
  ] });
3373
3450
  }
3374
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3375
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3376
- error ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3377
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "b316-field", children: [
3378
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3379
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3451
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3452
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Reset your password" }),
3453
+ error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3454
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-field", children: [
3455
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "b316-label", htmlFor: "b316-forgot-email", children: "Email" }),
3456
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3380
3457
  "input",
3381
3458
  {
3382
3459
  id: "b316-forgot-email",
@@ -3389,14 +3466,14 @@ function ForgotPassword({ onSent, signInUrl, className, style }) {
3389
3466
  }
3390
3467
  )
3391
3468
  ] }),
3392
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3393
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3469
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Send reset link" }),
3470
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Back to sign in" }) : null
3394
3471
  ] });
3395
3472
  }
3396
3473
 
3397
3474
  // src/ResetPassword.tsx
3398
- var import_react16 = require("react");
3399
- var import_jsx_runtime18 = require("react/jsx-runtime");
3475
+ var import_react17 = require("react");
3476
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3400
3477
  function ResetPassword({
3401
3478
  token: supplied,
3402
3479
  onReset,
@@ -3405,13 +3482,13 @@ function ResetPassword({
3405
3482
  style
3406
3483
  }) {
3407
3484
  const { client } = useBase316();
3408
- const [token, setToken] = (0, import_react16.useState)(supplied ?? null);
3409
- const [password, setPassword] = (0, import_react16.useState)("");
3410
- const [confirmation, setConfirmation] = (0, import_react16.useState)("");
3411
- const [done, setDone] = (0, import_react16.useState)(false);
3412
- const [busy, setBusy] = (0, import_react16.useState)(false);
3413
- const [error, setError] = (0, import_react16.useState)(null);
3414
- (0, import_react16.useEffect)(() => {
3485
+ const [token, setToken] = (0, import_react17.useState)(supplied ?? null);
3486
+ const [password, setPassword] = (0, import_react17.useState)("");
3487
+ const [confirmation, setConfirmation] = (0, import_react17.useState)("");
3488
+ const [done, setDone] = (0, import_react17.useState)(false);
3489
+ const [busy, setBusy] = (0, import_react17.useState)(false);
3490
+ const [error, setError] = (0, import_react17.useState)(null);
3491
+ (0, import_react17.useEffect)(() => {
3415
3492
  if (supplied || typeof window === "undefined") {
3416
3493
  return;
3417
3494
  }
@@ -3446,24 +3523,24 @@ function ResetPassword({
3446
3523
  }
3447
3524
  }
3448
3525
  if (done) {
3449
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card", className), style, children: [
3450
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3451
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3452
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3526
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3527
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Password changed" }),
3528
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "You can sign in with your new password." }),
3529
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-button-link", href: signInUrl, children: "Sign in" }) : null
3453
3530
  ] });
3454
3531
  }
3455
3532
  if (!token) {
3456
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: cls("b316-card", className), style, children: [
3457
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3458
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3533
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: cls("b316-card", className), style, children: [
3534
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Nothing to reset" }),
3535
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email. Request a new one if yours has expired." })
3459
3536
  ] });
3460
3537
  }
3461
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3462
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3463
- error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3464
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-field", children: [
3465
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3466
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3538
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
3539
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Choose a new password" }),
3540
+ error ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3541
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3542
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-password", children: "New password" }),
3543
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3467
3544
  "input",
3468
3545
  {
3469
3546
  id: "b316-reset-password",
@@ -3476,9 +3553,9 @@ function ResetPassword({
3476
3553
  }
3477
3554
  )
3478
3555
  ] }),
3479
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "b316-field", children: [
3480
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3481
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3556
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "b316-field", children: [
3557
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { className: "b316-label", htmlFor: "b316-reset-confirm", children: "Repeat it" }),
3558
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3482
3559
  "input",
3483
3560
  {
3484
3561
  id: "b316-reset-confirm",
@@ -3491,13 +3568,13 @@ function ResetPassword({
3491
3568
  }
3492
3569
  )
3493
3570
  ] }),
3494
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3571
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !password, children: busy ? "Saving\u2026" : "Set password" })
3495
3572
  ] });
3496
3573
  }
3497
3574
 
3498
3575
  // src/VerifyEmail.tsx
3499
- var import_react17 = require("react");
3500
- var import_jsx_runtime19 = require("react/jsx-runtime");
3576
+ var import_react18 = require("react");
3577
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3501
3578
  function VerifyEmail({
3502
3579
  token: supplied,
3503
3580
  onVerified,
@@ -3506,9 +3583,9 @@ function VerifyEmail({
3506
3583
  style
3507
3584
  }) {
3508
3585
  const { client } = useBase316();
3509
- const [state, setState] = (0, import_react17.useState)("waiting");
3510
- const spent = (0, import_react17.useRef)(false);
3511
- (0, import_react17.useEffect)(() => {
3586
+ const [state, setState] = (0, import_react18.useState)("waiting");
3587
+ const spent = (0, import_react18.useRef)(false);
3588
+ (0, import_react18.useEffect)(() => {
3512
3589
  if (spent.current) {
3513
3590
  return;
3514
3591
  }
@@ -3534,22 +3611,22 @@ function VerifyEmail({
3534
3611
  setState("failed");
3535
3612
  });
3536
3613
  }, [client, supplied, onVerified]);
3537
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3538
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3539
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3540
- continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3541
- ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3542
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3543
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3544
- ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3545
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3546
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3547
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3614
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cls("b316-card", className), style, children: state === "verified" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3615
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Email confirmed" }),
3616
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Thanks \u2014 your address is verified." }),
3617
+ continueUrl ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("a", { className: "b316-button-link", href: continueUrl, children: "Continue" }) : null
3618
+ ] }) : state === "failed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3619
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "That link did not work" }),
3620
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "It may have expired or already been used. Ask for a new one and try again." })
3621
+ ] }) : state === "missing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3622
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-form-title", children: "Nothing to confirm" }),
3623
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "This page needs the link from your email." })
3624
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "b316-muted", children: "Confirming your email\u2026" }) });
3548
3625
  }
3549
3626
 
3550
3627
  // src/TeamMembers.tsx
3551
- var import_react18 = require("react");
3552
- var import_jsx_runtime20 = require("react/jsx-runtime");
3628
+ var import_react19 = require("react");
3629
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3553
3630
  function TeamMembers({
3554
3631
  organizationId,
3555
3632
  onInvited,
@@ -3559,16 +3636,16 @@ function TeamMembers({
3559
3636
  style
3560
3637
  }) {
3561
3638
  const { client, token, session } = useBase316();
3562
- const [teams, setTeams] = (0, import_react18.useState)(null);
3563
- const [members, setMembers] = (0, import_react18.useState)(null);
3564
- const [invitations, setInvitations] = (0, import_react18.useState)(null);
3565
- const [email, setEmail] = (0, import_react18.useState)("");
3566
- const [busy, setBusy] = (0, import_react18.useState)(false);
3567
- const [error, setError] = (0, import_react18.useState)(null);
3568
- const [copied, setCopied] = (0, import_react18.useState)(null);
3639
+ const [teams, setTeams] = (0, import_react19.useState)(null);
3640
+ const [members, setMembers] = (0, import_react19.useState)(null);
3641
+ const [invitations, setInvitations] = (0, import_react19.useState)(null);
3642
+ const [email, setEmail] = (0, import_react19.useState)("");
3643
+ const [busy, setBusy] = (0, import_react19.useState)(false);
3644
+ const [error, setError] = (0, import_react19.useState)(null);
3645
+ const [copied, setCopied] = (0, import_react19.useState)(null);
3569
3646
  const chosen = organizationId ?? (teams?.length === 1 ? teams[0].id : null);
3570
3647
  const team = teams?.find((candidate) => candidate.id === chosen) ?? null;
3571
- const load = (0, import_react18.useCallback)(() => {
3648
+ const load = (0, import_react19.useCallback)(() => {
3572
3649
  if (!token) {
3573
3650
  return;
3574
3651
  }
@@ -3576,8 +3653,8 @@ function TeamMembers({
3576
3653
  (cause) => setError(cause instanceof Error ? cause.message : "Could not load your teams.")
3577
3654
  );
3578
3655
  }, [client, token]);
3579
- (0, import_react18.useEffect)(load, [load]);
3580
- (0, import_react18.useEffect)(() => {
3656
+ (0, import_react19.useEffect)(load, [load]);
3657
+ (0, import_react19.useEffect)(() => {
3581
3658
  if (!token || !chosen) {
3582
3659
  return;
3583
3660
  }
@@ -3608,10 +3685,10 @@ function TeamMembers({
3608
3685
  return null;
3609
3686
  }
3610
3687
  if (!teams) {
3611
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3688
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: error ?? "Loading\u2026" });
3612
3689
  }
3613
3690
  if (!chosen) {
3614
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
3691
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: teams.length === 0 ? "You are not in a team yet." : "You are in more than one team. Name which with the organizationId prop." });
3615
3692
  }
3616
3693
  const canManage = invitations !== null;
3617
3694
  async function invite(event) {
@@ -3661,30 +3738,30 @@ function TeamMembers({
3661
3738
  setError(cause instanceof Error ? cause.message : "That invitation could not be withdrawn.");
3662
3739
  }
3663
3740
  }
3664
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
3665
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
3741
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card b316-team", className), style, children: [
3742
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-team-title", children: team?.name ?? "Team" }),
3666
3743
  team?.inherited ? (
3667
3744
  // Not a member of this team, so not in the list below and with nothing
3668
3745
  // to leave: access comes from the team that manages it, and ends there.
3669
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-muted", children: [
3746
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
3670
3747
  "You have access through",
3671
3748
  " ",
3672
3749
  teams.find((candidate) => candidate.id === team.via)?.name ?? "the organization that manages this team",
3673
3750
  "."
3674
3751
  ] })
3675
3752
  ) : null,
3676
- error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3677
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("li", { className: "b316-team-member", children: [
3678
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
3679
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3680
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-muted", children: [
3753
+ error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3754
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "b316-team-list", children: (members ?? []).map((member) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "b316-team-member", children: [
3755
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3756
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: member.user.name ?? member.user.email ?? "Someone" }),
3757
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
3681
3758
  member.user.email,
3682
3759
  member.user.id === session?.userId ? " \xB7 you" : ""
3683
3760
  ] })
3684
3761
  ] }),
3685
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-team-member-side", children: [
3686
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "b316-chip", children: member.role.name }),
3687
- canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3762
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-member-side", children: [
3763
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "b316-chip", children: member.role.name }),
3764
+ canManage || member.user.id === session?.userId ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3688
3765
  ConfirmButton,
3689
3766
  {
3690
3767
  className: "b316-button-quiet b316-danger",
@@ -3696,19 +3773,19 @@ function TeamMembers({
3696
3773
  ) : null
3697
3774
  ] })
3698
3775
  ] }, member.id)) }),
3699
- canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3700
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
3701
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("li", { className: "b316-team-member", children: [
3702
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { children: [
3703
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { children: invitation.email }),
3704
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-muted", children: [
3776
+ canManage && (invitations ?? []).length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3777
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h4", { className: "b316-team-subtitle", children: "Invited" }),
3778
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("ul", { className: "b316-team-list", children: (invitations ?? []).map((invitation) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "b316-team-member", children: [
3779
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
3780
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: invitation.email }),
3781
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-muted", children: [
3705
3782
  invitation.role.name,
3706
3783
  " \xB7 expires",
3707
3784
  " ",
3708
3785
  new Date(invitation.expiresAt).toLocaleDateString()
3709
3786
  ] })
3710
3787
  ] }),
3711
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3788
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3712
3789
  "button",
3713
3790
  {
3714
3791
  type: "button",
@@ -3719,10 +3796,10 @@ function TeamMembers({
3719
3796
  )
3720
3797
  ] }, invitation.id)) })
3721
3798
  ] }) : null,
3722
- canManage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
3723
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3724
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-team-invite-row", children: [
3725
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3799
+ canManage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("form", { className: "b316-team-invite", onSubmit: invite, children: [
3800
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "b316-label", htmlFor: "b316-invite-email", children: "Invite by email" }),
3801
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-invite-row", children: [
3802
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3726
3803
  "input",
3727
3804
  {
3728
3805
  id: "b316-invite-email",
@@ -3734,19 +3811,19 @@ function TeamMembers({
3734
3811
  onChange: (event) => setEmail(event.target.value)
3735
3812
  }
3736
3813
  ),
3737
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
3814
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "submit", className: "b316-button", disabled: busy || !email, children: busy ? "Sending\u2026" : "Invite" })
3738
3815
  ] })
3739
3816
  ] }) : null,
3740
- copied ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "b316-team-link", children: [
3741
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3742
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("code", { children: copied })
3817
+ copied ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-team-link", children: [
3818
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-muted", children: "Send them this link. It is shown once and cannot be fetched again." }),
3819
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("code", { children: copied })
3743
3820
  ] }) : null
3744
3821
  ] });
3745
3822
  }
3746
3823
 
3747
3824
  // src/AcceptInvitation.tsx
3748
- var import_react19 = require("react");
3749
- var import_jsx_runtime21 = require("react/jsx-runtime");
3825
+ var import_react20 = require("react");
3826
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3750
3827
  function signUpUrlWithInvitation(url, token) {
3751
3828
  const [beforeHash, ...hash] = url.split("#");
3752
3829
  const base = beforeHash ?? "";
@@ -3765,18 +3842,18 @@ function AcceptInvitation({
3765
3842
  style
3766
3843
  }) {
3767
3844
  const { client, token: session, session: user } = useBase316();
3768
- const [invitationToken, setInvitationToken] = (0, import_react19.useState)(supplied ?? null);
3769
- const [preview, setPreview] = (0, import_react19.useState)(null);
3770
- const [state, setState] = (0, import_react19.useState)("loading");
3771
- const [error, setError] = (0, import_react19.useState)(null);
3772
- const [busy, setBusy] = (0, import_react19.useState)(false);
3773
- (0, import_react19.useEffect)(() => {
3845
+ const [invitationToken, setInvitationToken] = (0, import_react20.useState)(supplied ?? null);
3846
+ const [preview, setPreview] = (0, import_react20.useState)(null);
3847
+ const [state, setState] = (0, import_react20.useState)("loading");
3848
+ const [error, setError] = (0, import_react20.useState)(null);
3849
+ const [busy, setBusy] = (0, import_react20.useState)(false);
3850
+ (0, import_react20.useEffect)(() => {
3774
3851
  if (supplied || typeof window === "undefined") {
3775
3852
  return;
3776
3853
  }
3777
3854
  setInvitationToken(new URL(window.location.href).searchParams.get("invitation"));
3778
3855
  }, [supplied]);
3779
- (0, import_react19.useEffect)(() => {
3856
+ (0, import_react20.useEffect)(() => {
3780
3857
  if (!invitationToken) {
3781
3858
  setState(supplied === void 0 ? "loading" : "invalid");
3782
3859
  return;
@@ -3813,42 +3890,42 @@ function AcceptInvitation({
3813
3890
  }
3814
3891
  }
3815
3892
  if (state === "loading") {
3816
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3893
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
3817
3894
  }
3818
3895
  if (state === "invalid") {
3819
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card", className), style, children: [
3820
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3821
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
3896
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card", className), style, children: [
3897
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "b316-form-title", children: "That invitation is no longer valid" }),
3898
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-muted", children: "It may have expired, been withdrawn, or already been used. Ask for a new one." })
3822
3899
  ] });
3823
3900
  }
3824
3901
  if (state === "accepted") {
3825
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("h3", { className: "b316-form-title", children: [
3902
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("h3", { className: "b316-form-title", children: [
3826
3903
  "You have joined ",
3827
3904
  preview?.organizationName
3828
3905
  ] }) });
3829
3906
  }
3830
3907
  const matches = !user || (user.user.email ?? "").toLowerCase() === preview?.email.toLowerCase();
3831
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
3832
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("h3", { className: "b316-form-title", children: [
3908
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cls("b316-card b316-invitation", className), style, children: [
3909
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("h3", { className: "b316-form-title", children: [
3833
3910
  "Join ",
3834
3911
  preview?.organizationName
3835
3912
  ] }),
3836
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "b316-muted", children: [
3913
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "b316-muted", children: [
3837
3914
  "Invited as ",
3838
3915
  preview?.email,
3839
3916
  " \xB7 ",
3840
3917
  preview?.roleName
3841
3918
  ] }),
3842
- error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3843
- !session ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3844
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { children: [
3919
+ error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
3920
+ !session ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3921
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { children: [
3845
3922
  "Sign in as ",
3846
3923
  preview?.email,
3847
3924
  " to accept."
3848
3925
  ] }),
3849
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "b316-invitation-actions", children: [
3850
- signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3851
- signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3926
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "b316-invitation-actions", children: [
3927
+ signInUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: "b316-button", href: signInUrl, children: "Sign in" }) : null,
3928
+ signUpUrl ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3852
3929
  "a",
3853
3930
  {
3854
3931
  className: "b316-button-link",
@@ -3861,20 +3938,20 @@ function AcceptInvitation({
3861
3938
  // Said before they press anything. The server refuses this, but
3862
3939
  // finding out after a click reads as a broken invitation rather than
3863
3940
  // as being signed in as the wrong person.
3864
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { children: [
3941
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { children: [
3865
3942
  "You are signed in as ",
3866
3943
  user?.user.email,
3867
3944
  ". This invitation was sent to ",
3868
3945
  preview?.email,
3869
3946
  " \u2014 sign in as that address to accept it."
3870
3947
  ] })
3871
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
3948
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type: "button", className: "b316-button", disabled: busy, onClick: accept, children: busy ? "Joining\u2026" : `Join ${preview?.organizationName}` })
3872
3949
  ] });
3873
3950
  }
3874
3951
 
3875
3952
  // src/PayInvoice.tsx
3876
- var import_react20 = require("react");
3877
- var import_jsx_runtime22 = require("react/jsx-runtime");
3953
+ var import_react21 = require("react");
3954
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3878
3955
  var STRIPE_SRC = "https://js.stripe.com/v3/";
3879
3956
  function loadStripeScript() {
3880
3957
  if (typeof window === "undefined") {
@@ -3906,14 +3983,14 @@ function PayInvoice({
3906
3983
  style
3907
3984
  }) {
3908
3985
  const { client } = useBase316();
3909
- const mountRef = (0, import_react20.useRef)(null);
3910
- const stripeRef = (0, import_react20.useRef)(null);
3911
- const elementsRef = (0, import_react20.useRef)(null);
3912
- const [ready, setReady] = (0, import_react20.useState)(false);
3913
- const [paying, setPaying] = (0, import_react20.useState)(false);
3914
- const [done, setDone] = (0, import_react20.useState)(false);
3915
- const [error, setError] = (0, import_react20.useState)(null);
3916
- (0, import_react20.useEffect)(() => {
3986
+ const mountRef = (0, import_react21.useRef)(null);
3987
+ const stripeRef = (0, import_react21.useRef)(null);
3988
+ const elementsRef = (0, import_react21.useRef)(null);
3989
+ const [ready, setReady] = (0, import_react21.useState)(false);
3990
+ const [paying, setPaying] = (0, import_react21.useState)(false);
3991
+ const [done, setDone] = (0, import_react21.useState)(false);
3992
+ const [error, setError] = (0, import_react21.useState)(null);
3993
+ (0, import_react21.useEffect)(() => {
3917
3994
  let cancelled = false;
3918
3995
  async function start() {
3919
3996
  const base = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}`;
@@ -3966,17 +4043,17 @@ function PayInvoice({
3966
4043
  onPaid?.();
3967
4044
  };
3968
4045
  if (done) {
3969
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
4046
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-pay", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-pay__done", children: "Paid \u2014 thank you." }) });
3970
4047
  }
3971
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
3972
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
3973
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
3974
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
4048
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: cls("b316-pay", className), style, onSubmit: submit, children: [
4049
+ error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "b316-pay__error", role: "alert", children: error }) : null,
4050
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: mountRef, className: "b316-pay__element" }),
4051
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { className: "b316-pay__submit", type: "submit", disabled: !ready || paying, children: paying ? "Paying\u2026" : "Pay" })
3975
4052
  ] });
3976
4053
  }
3977
4054
 
3978
4055
  // src/usePaymentLink.ts
3979
- var import_react21 = require("react");
4056
+ var import_react22 = require("react");
3980
4057
  function usePaymentLink({
3981
4058
  token,
3982
4059
  environmentId,
@@ -3984,10 +4061,10 @@ function usePaymentLink({
3984
4061
  onPaid
3985
4062
  }) {
3986
4063
  const { client } = useBase316();
3987
- const [status2, setStatus] = (0, import_react21.useState)({ state: "loading" });
3988
- const onPaidRef = (0, import_react21.useRef)(onPaid);
4064
+ const [status2, setStatus] = (0, import_react22.useState)({ state: "loading" });
4065
+ const onPaidRef = (0, import_react22.useRef)(onPaid);
3989
4066
  onPaidRef.current = onPaid;
3990
- (0, import_react21.useEffect)(() => {
4067
+ (0, import_react22.useEffect)(() => {
3991
4068
  let stopped = false;
3992
4069
  let timer;
3993
4070
  const statusUrl = `${client.baseUrl}/pay/${encodeURIComponent(environmentId)}/${encodeURIComponent(token)}/status`;
@@ -4036,23 +4113,23 @@ function usePaymentLink({
4036
4113
  }
4037
4114
 
4038
4115
  // src/PricingTable.tsx
4039
- var import_react23 = require("react");
4116
+ var import_react24 = require("react");
4040
4117
 
4041
4118
  // src/usePlans.ts
4042
- var import_react22 = require("react");
4119
+ var import_react23 = require("react");
4043
4120
  var CHECKOUT_STATUSES = /* @__PURE__ */ new Set([402, 409]);
4044
4121
  function usePlans(options = {}) {
4045
4122
  const { client, token } = useBase316();
4046
- const [plans, setPlans] = (0, import_react22.useState)(null);
4047
- const [error, setError] = (0, import_react22.useState)(false);
4048
- const [busyPlanVersionId, setBusy] = (0, import_react22.useState)(null);
4049
- const [lastError, setLastError] = (0, import_react22.useState)(null);
4050
- const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react22.useState)(null);
4051
- const [managedBy, setManagedBy] = (0, import_react22.useState)(null);
4052
- const [reloadCount, setReloadCount] = (0, import_react22.useState)(0);
4123
+ const [plans, setPlans] = (0, import_react23.useState)(null);
4124
+ const [error, setError] = (0, import_react23.useState)(false);
4125
+ const [busyPlanVersionId, setBusy] = (0, import_react23.useState)(null);
4126
+ const [lastError, setLastError] = (0, import_react23.useState)(null);
4127
+ const [ownPlanVersionId, setOwnPlanVersionId] = (0, import_react23.useState)(null);
4128
+ const [managedBy, setManagedBy] = (0, import_react23.useState)(null);
4129
+ const [reloadCount, setReloadCount] = (0, import_react23.useState)(0);
4053
4130
  const supplied = options.currentPlanVersionId;
4054
4131
  const discover = supplied === void 0;
4055
- (0, import_react22.useEffect)(() => {
4132
+ (0, import_react23.useEffect)(() => {
4056
4133
  let cancelled = false;
4057
4134
  client.billing.plans().then((result) => {
4058
4135
  if (!cancelled) {
@@ -4068,7 +4145,7 @@ function usePlans(options = {}) {
4068
4145
  cancelled = true;
4069
4146
  };
4070
4147
  }, [client, reloadCount]);
4071
- (0, import_react22.useEffect)(() => {
4148
+ (0, import_react23.useEffect)(() => {
4072
4149
  if (!token) {
4073
4150
  return;
4074
4151
  }
@@ -4085,11 +4162,11 @@ function usePlans(options = {}) {
4085
4162
  cancelled = true;
4086
4163
  };
4087
4164
  }, [client, token, discover, reloadCount]);
4088
- const reload = (0, import_react22.useCallback)(() => {
4165
+ const reload = (0, import_react23.useCallback)(() => {
4089
4166
  setError(false);
4090
4167
  setReloadCount((count) => count + 1);
4091
4168
  }, []);
4092
- const selectPlan = (0, import_react22.useCallback)(
4169
+ const selectPlan = (0, import_react23.useCallback)(
4093
4170
  async (plan) => {
4094
4171
  setLastError(null);
4095
4172
  if (managedBy) {
@@ -4157,7 +4234,7 @@ function usePlans(options = {}) {
4157
4234
  }
4158
4235
 
4159
4236
  // src/PricingTable.tsx
4160
- var import_jsx_runtime23 = require("react/jsx-runtime");
4237
+ var import_jsx_runtime24 = require("react/jsx-runtime");
4161
4238
  function formatAmount(amount, currency) {
4162
4239
  if (amount === null) return "Free";
4163
4240
  const value = Number(amount);
@@ -4206,7 +4283,7 @@ function PricingTable({
4206
4283
  managedBy,
4207
4284
  selectPlan
4208
4285
  } = usePlans({ currentPlanVersionId });
4209
- const [scheduled, setScheduled] = (0, import_react23.useState)(null);
4286
+ const [scheduled, setScheduled] = (0, import_react24.useState)(null);
4210
4287
  async function choose(plan) {
4211
4288
  if (onSelectPlan) {
4212
4289
  await onSelectPlan(plan.planVersionId, plan);
@@ -4223,50 +4300,50 @@ function PricingTable({
4223
4300
  }
4224
4301
  }
4225
4302
  if (error) {
4226
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4303
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Plans are unavailable right now." });
4227
4304
  }
4228
4305
  if (!plans) {
4229
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4306
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "Loading plans\u2026" });
4230
4307
  }
4231
4308
  if (plans.length === 0) {
4232
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4309
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: cls("b316-card", className), style, children: "No plans are published yet." });
4233
4310
  }
4234
4311
  const anyTrial = plans.some((plan) => Boolean(plan.trialDays));
4235
4312
  const anyDescription = plans.some((plan) => Boolean(plan.description));
4236
4313
  const anyFeatured = plans.some((plan) => plan.key === featuredPlanKey);
4237
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4314
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cls("b316-plans", className), style, children: [
4238
4315
  managedBy ? (
4239
4316
  // A client company's plan comes from the firm that runs it. The table
4240
4317
  // still shows what is on offer, with the current plan marked, but
4241
4318
  // nothing here can be bought: it would grant this account nothing.
4242
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4319
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plans-managed b316-muted", children: [
4243
4320
  "Your plan is provided by ",
4244
4321
  managedBy.name ?? "the organization that manages your account",
4245
4322
  ". Ask them to change it."
4246
4323
  ] })
4247
- ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4324
+ ) : lastError ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plans-error", role: "alert", children: lastError }) : scheduled ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plans-managed b316-muted", role: "status", children: scheduled }) : null,
4248
4325
  plans.map((plan) => {
4249
4326
  const base = plan.prices.find((price) => price.featureId === null) ?? plan.prices[0];
4250
4327
  const isCurrent = current === plan.planVersionId;
4251
4328
  const featured = featuredPlanKey === plan.key;
4252
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4329
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4253
4330
  "div",
4254
4331
  {
4255
4332
  className: featured ? "b316-card b316-plan b316-plan-featured" : "b316-card b316-plan",
4256
4333
  children: [
4257
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-plan-head", children: [
4258
- anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4259
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4260
- anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4334
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-head", children: [
4335
+ anyFeatured ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: featured ? "b316-plan-badge" : "b316-plan-badge-spacer", children: featured ? "Recommended" : "\xA0" }) : null,
4336
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-name", children: plan.name }),
4337
+ anyDescription ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-desc", children: plan.description ?? "\xA0" }) : null
4261
4338
  ] }),
4262
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "b316-plan-pricing", children: [
4263
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4264
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4265
- anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4339
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-plan-pricing", children: [
4340
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-price", children: formatAmount(base?.amount ?? null, plan.currency) }),
4341
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-cadence", children: cadence(plan, base?.amount ?? null) }),
4342
+ anyTrial ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-trial", children: describeTrial(plan, plans) ?? "\xA0" }) : null
4266
4343
  ] }),
4267
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { className: "b316-plan-feature", children: [
4268
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: entitlement.featureName }),
4269
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4344
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("ul", { className: "b316-plan-features", children: plan.entitlements.filter((entitlement) => entitlement.enabled).map((entitlement) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("li", { className: "b316-plan-feature", children: [
4345
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { children: entitlement.featureName }),
4346
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-plan-feature-value", children: entitlement.limit === null ? "Unlimited" : (
4270
4347
  // A usage price on the feature makes the limit an
4271
4348
  // allowance billed past, not a ceiling — the same
4272
4349
  // rule `check()` applies (any non-FLAT price).
@@ -4275,7 +4352,7 @@ function PricingTable({
4275
4352
  ) ? `${entitlement.limit} included` : entitlement.limit
4276
4353
  ) })
4277
4354
  ] }, entitlement.featureId)) }),
4278
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4355
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-plan-action", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4279
4356
  "button",
4280
4357
  {
4281
4358
  type: "button",
@@ -4297,11 +4374,11 @@ function PricingTable({
4297
4374
 
4298
4375
  // src/DataTable.tsx
4299
4376
  var import_sdk8 = require("@base316/sdk");
4300
- var import_react27 = require("react");
4377
+ var import_react28 = require("react");
4301
4378
 
4302
4379
  // src/fields.tsx
4303
4380
  var import_sdk6 = require("@base316/sdk");
4304
- var import_jsx_runtime24 = require("react/jsx-runtime");
4381
+ var import_jsx_runtime25 = require("react/jsx-runtime");
4305
4382
  function formatNumber(value, fraction = 0) {
4306
4383
  const number = Number(value);
4307
4384
  return Number.isFinite(number) ? new Intl.NumberFormat(void 0, {
@@ -4323,10 +4400,10 @@ function formatDuration(value) {
4323
4400
  }
4324
4401
  function FieldCell({ value, field, related }) {
4325
4402
  if (field.type === "RELATION") {
4326
- return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4403
+ return related?.title ?? (related?.id ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("code", { className: "b316-muted", children: related.id }) : "\u2014");
4327
4404
  }
4328
4405
  if (value === null || value === void 0 || value === "") {
4329
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-muted", children: "\u2014" });
4406
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "\u2014" });
4330
4407
  }
4331
4408
  switch (field.type) {
4332
4409
  case "BOOLEAN":
@@ -4339,9 +4416,9 @@ function FieldCell({ value, field, related }) {
4339
4416
  return formatDuration(value);
4340
4417
  case "RATING": {
4341
4418
  const stars = Math.round(Number(value));
4342
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4419
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { "aria-label": `${stars} out of 5`, children: [
4343
4420
  "\u2605".repeat(stars),
4344
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4421
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "\u2605".repeat(Math.max(0, 5 - stars)) })
4345
4422
  ] });
4346
4423
  }
4347
4424
  case "DATE":
@@ -4349,15 +4426,15 @@ function FieldCell({ value, field, related }) {
4349
4426
  case "DATETIME":
4350
4427
  return new Date(String(value)).toLocaleString();
4351
4428
  case "SELECT":
4352
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-chip", children: String(value) });
4429
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chip", children: String(value) });
4353
4430
  case "MULTISELECT":
4354
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4431
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chips", children: (Array.isArray(value) ? value : [value]).map((item) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-chip", children: String(item) }, String(item))) });
4355
4432
  case "URL":
4356
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4433
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: String(value), target: "_blank", rel: "noreferrer noopener", children: String(value) });
4357
4434
  case "EMAIL":
4358
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4435
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: `mailto:${String(value)}`, children: String(value) });
4359
4436
  case "PHONE":
4360
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4437
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("a", { href: `tel:${String(value)}`, children: String(value) });
4361
4438
  case "ADDRESS":
4362
4439
  return (0, import_sdk6.formatAddress)(value);
4363
4440
  case "ATTACHMENT": {
@@ -4369,7 +4446,7 @@ function FieldCell({ value, field, related }) {
4369
4446
  return text.length > 80 ? `${text.slice(0, 80)}\u2026` : text;
4370
4447
  }
4371
4448
  case "JSON":
4372
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4449
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("code", { className: "b316-muted", children: JSON.stringify(value).slice(0, 60) });
4373
4450
  default:
4374
4451
  return String(value);
4375
4452
  }
@@ -4390,7 +4467,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4390
4467
  function control() {
4391
4468
  switch (field.type) {
4392
4469
  case "LONGTEXT":
4393
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4470
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4394
4471
  "textarea",
4395
4472
  {
4396
4473
  ...common,
@@ -4400,7 +4477,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4400
4477
  }
4401
4478
  );
4402
4479
  case "BOOLEAN":
4403
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4480
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4404
4481
  "input",
4405
4482
  {
4406
4483
  ...common,
@@ -4411,22 +4488,22 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4411
4488
  }
4412
4489
  );
4413
4490
  case "SELECT":
4414
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
4491
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
4415
4492
  "select",
4416
4493
  {
4417
4494
  ...common,
4418
4495
  value: value === null || value === void 0 ? "" : String(value),
4419
4496
  onChange: (event) => onChange(event.target.value === "" ? null : event.target.value),
4420
4497
  children: [
4421
- field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: "", children: "\u2014" }),
4422
- (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("option", { value: option, children: option }, option))
4498
+ field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: "", children: "\u2014" }),
4499
+ (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("option", { value: option, children: option }, option))
4423
4500
  ]
4424
4501
  }
4425
4502
  );
4426
4503
  case "MULTISELECT": {
4427
4504
  const selected = new Set(Array.isArray(value) ? value.map(String) : []);
4428
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "b316-choice", children: [
4429
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4505
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-choices", children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "b316-choice", children: [
4506
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4430
4507
  "input",
4431
4508
  {
4432
4509
  type: "checkbox",
@@ -4449,7 +4526,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4449
4526
  case "NUMBER":
4450
4527
  case "MONEY":
4451
4528
  case "PERCENT":
4452
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4529
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4453
4530
  "input",
4454
4531
  {
4455
4532
  ...common,
@@ -4460,7 +4537,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4460
4537
  }
4461
4538
  );
4462
4539
  case "RATING":
4463
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4540
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4464
4541
  "input",
4465
4542
  {
4466
4543
  ...common,
@@ -4474,8 +4551,8 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4474
4551
  );
4475
4552
  case "DURATION": {
4476
4553
  const minutes = value === null || value === void 0 ? "" : String(Number(value) / 60);
4477
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-suffixed", children: [
4478
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4554
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-suffixed", children: [
4555
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4479
4556
  "input",
4480
4557
  {
4481
4558
  ...common,
@@ -4485,11 +4562,11 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4485
4562
  onChange: (event) => onChange(event.target.value === "" ? null : Number(event.target.value) * 60)
4486
4563
  }
4487
4564
  ),
4488
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "b316-muted", children: "minutes" })
4565
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "b316-muted", children: "minutes" })
4489
4566
  ] });
4490
4567
  }
4491
4568
  case "DATE":
4492
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4569
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4493
4570
  "input",
4494
4571
  {
4495
4572
  ...common,
@@ -4499,7 +4576,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4499
4576
  }
4500
4577
  );
4501
4578
  case "DATETIME":
4502
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4579
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4503
4580
  "input",
4504
4581
  {
4505
4582
  ...common,
@@ -4512,7 +4589,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4512
4589
  );
4513
4590
  case "ADDRESS": {
4514
4591
  const address = value ?? {};
4515
- const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4592
+ const part = (key, label) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4516
4593
  "input",
4517
4594
  {
4518
4595
  className: "b316-input",
@@ -4524,7 +4601,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4524
4601
  },
4525
4602
  key
4526
4603
  );
4527
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-address", children: [
4604
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-address", children: [
4528
4605
  part("line1", "Address line 1"),
4529
4606
  part("line2", "Address line 2"),
4530
4607
  part("city", "City"),
@@ -4534,7 +4611,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4534
4611
  ] });
4535
4612
  }
4536
4613
  case "EMAIL":
4537
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4614
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4538
4615
  "input",
4539
4616
  {
4540
4617
  ...common,
@@ -4544,7 +4621,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4544
4621
  }
4545
4622
  );
4546
4623
  case "URL":
4547
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4624
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4548
4625
  "input",
4549
4626
  {
4550
4627
  ...common,
@@ -4554,7 +4631,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4554
4631
  }
4555
4632
  );
4556
4633
  case "PHONE":
4557
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4634
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4558
4635
  "input",
4559
4636
  {
4560
4637
  ...common,
@@ -4564,7 +4641,7 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4564
4641
  }
4565
4642
  );
4566
4643
  default:
4567
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
4644
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4568
4645
  "input",
4569
4646
  {
4570
4647
  ...common,
@@ -4575,24 +4652,24 @@ function FieldInput({ value, field, onChange, error, disabled }) {
4575
4652
  );
4576
4653
  }
4577
4654
  }
4578
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "b316-field", children: [
4579
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4655
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-field", children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4580
4657
  field.label,
4581
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4658
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4582
4659
  ] }),
4583
4660
  control(),
4584
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4585
- error ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4661
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4662
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-error", id: described, role: "alert", children: error }) : null
4586
4663
  ] });
4587
4664
  }
4588
4665
 
4589
4666
  // src/RecordForm.tsx
4590
4667
  var import_sdk7 = require("@base316/sdk");
4591
- var import_react26 = require("react");
4668
+ var import_react27 = require("react");
4592
4669
 
4593
4670
  // src/RelationPicker.tsx
4594
- var import_react24 = require("react");
4595
- var import_jsx_runtime25 = require("react/jsx-runtime");
4671
+ var import_react25 = require("react");
4672
+ var import_jsx_runtime26 = require("react/jsx-runtime");
4596
4673
  function RelationPicker({
4597
4674
  field,
4598
4675
  value,
@@ -4602,13 +4679,13 @@ function RelationPicker({
4602
4679
  tenant
4603
4680
  }) {
4604
4681
  const { client, token } = useBase316();
4605
- const [query, setQuery] = (0, import_react24.useState)("");
4606
- const [results, setResults] = (0, import_react24.useState)([]);
4607
- const [chosenTitle, setChosenTitle] = (0, import_react24.useState)(null);
4608
- const [open, setOpen] = (0, import_react24.useState)(false);
4682
+ const [query, setQuery] = (0, import_react25.useState)("");
4683
+ const [results, setResults] = (0, import_react25.useState)([]);
4684
+ const [chosenTitle, setChosenTitle] = (0, import_react25.useState)(null);
4685
+ const [open, setOpen] = (0, import_react25.useState)(false);
4609
4686
  const id = `b316-field-${field.key}`;
4610
- const box = (0, import_react24.useRef)(null);
4611
- (0, import_react24.useEffect)(() => {
4687
+ const box = (0, import_react25.useRef)(null);
4688
+ (0, import_react25.useEffect)(() => {
4612
4689
  if (!token || !value || !field.relationTo) {
4613
4690
  setChosenTitle(null);
4614
4691
  return;
@@ -4623,7 +4700,7 @@ function RelationPicker({
4623
4700
  cancelled = true;
4624
4701
  };
4625
4702
  }, [client, token, value, field.relationTo, tenant]);
4626
- (0, import_react24.useEffect)(() => {
4703
+ (0, import_react25.useEffect)(() => {
4627
4704
  if (!token || !field.relationTo || !open) {
4628
4705
  return;
4629
4706
  }
@@ -4649,7 +4726,7 @@ function RelationPicker({
4649
4726
  clearTimeout(timer);
4650
4727
  };
4651
4728
  }, [client, token, field.relationTo, query, open, tenant]);
4652
- (0, import_react24.useEffect)(() => {
4729
+ (0, import_react25.useEffect)(() => {
4653
4730
  if (!open || typeof document === "undefined") {
4654
4731
  return;
4655
4732
  }
@@ -4663,14 +4740,14 @@ function RelationPicker({
4663
4740
  document.removeEventListener("mousedown", onDocumentClick);
4664
4741
  };
4665
4742
  }, [open]);
4666
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-field", ref: box, children: [
4667
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4743
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-field", ref: box, children: [
4744
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("label", { className: "b316-label", htmlFor: id, children: [
4668
4745
  field.label,
4669
- field.required ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4746
+ field.required ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { "aria-hidden": "true", children: " *" }) : null
4670
4747
  ] }),
4671
- value && !open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "b316-relation-chosen", children: [
4672
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: chosenTitle ?? value }),
4673
- disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4748
+ value && !open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-relation-chosen", children: [
4749
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: chosenTitle ?? value }),
4750
+ disabled ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4674
4751
  "button",
4675
4752
  {
4676
4753
  type: "button",
@@ -4682,7 +4759,7 @@ function RelationPicker({
4682
4759
  children: "Change"
4683
4760
  }
4684
4761
  ),
4685
- disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4762
+ disabled || field.required ? null : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4686
4763
  "button",
4687
4764
  {
4688
4765
  type: "button",
@@ -4692,8 +4769,8 @@ function RelationPicker({
4692
4769
  children: "Clear"
4693
4770
  }
4694
4771
  )
4695
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
4696
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4772
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
4773
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4697
4774
  "input",
4698
4775
  {
4699
4776
  id,
@@ -4714,7 +4791,7 @@ function RelationPicker({
4714
4791
  }
4715
4792
  }
4716
4793
  ),
4717
- open ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
4794
+ open ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "b316-relation-results", id: `${id}-results`, role: "listbox", children: results.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { className: "b316-muted b316-relation-empty", children: "No matches" }) : results.map((result) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4718
4795
  "button",
4719
4796
  {
4720
4797
  type: "button",
@@ -4730,13 +4807,13 @@ function RelationPicker({
4730
4807
  }
4731
4808
  ) }, result.id)) }) : null
4732
4809
  ] }),
4733
- field.description ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4734
- error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
4810
+ field.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-hint", children: field.description }) : null,
4811
+ error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null
4735
4812
  ] });
4736
4813
  }
4737
4814
 
4738
4815
  // src/useCollection.ts
4739
- var import_react25 = require("react");
4816
+ var import_react26 = require("react");
4740
4817
  function fieldErrorFrom(cause) {
4741
4818
  const param = cause?.param;
4742
4819
  const message = cause instanceof Error ? cause.message : "That value was not accepted.";
@@ -4744,24 +4821,24 @@ function fieldErrorFrom(cause) {
4744
4821
  }
4745
4822
  function useCollection(collection, options = {}) {
4746
4823
  const { client, token } = useBase316();
4747
- const [schema, setSchema] = (0, import_react25.useState)(null);
4748
- const [records, setRecords] = (0, import_react25.useState)([]);
4749
- const [error, setError] = (0, import_react25.useState)(null);
4750
- const [loading, setLoading] = (0, import_react25.useState)(true);
4751
- const [total, setTotal] = (0, import_react25.useState)(0);
4752
- const [cursor, setCursor] = (0, import_react25.useState)(null);
4753
- const [reloadCount, setReloadCount] = (0, import_react25.useState)(0);
4754
- const [search, setSearch] = (0, import_react25.useState)("");
4755
- const [filters, setFilters] = (0, import_react25.useState)([]);
4756
- const [sort, setSort] = (0, import_react25.useState)(
4824
+ const [schema, setSchema] = (0, import_react26.useState)(null);
4825
+ const [records, setRecords] = (0, import_react26.useState)([]);
4826
+ const [error, setError] = (0, import_react26.useState)(null);
4827
+ const [loading, setLoading] = (0, import_react26.useState)(true);
4828
+ const [total, setTotal] = (0, import_react26.useState)(0);
4829
+ const [cursor, setCursor] = (0, import_react26.useState)(null);
4830
+ const [reloadCount, setReloadCount] = (0, import_react26.useState)(0);
4831
+ const [search, setSearch] = (0, import_react26.useState)("");
4832
+ const [filters, setFilters] = (0, import_react26.useState)([]);
4833
+ const [sort, setSort] = (0, import_react26.useState)(
4757
4834
  options.sort ?? null
4758
4835
  );
4759
- const [fieldErrors, setFieldErrors] = (0, import_react25.useState)({});
4760
- const [saving, setSaving] = (0, import_react25.useState)(false);
4836
+ const [fieldErrors, setFieldErrors] = (0, import_react26.useState)({});
4837
+ const [saving, setSaving] = (0, import_react26.useState)(false);
4761
4838
  const { tenant, limit, recordId } = options;
4762
4839
  const fixedFilters = JSON.stringify(options.filters ?? []);
4763
- const scope = (0, import_react25.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
4764
- (0, import_react25.useEffect)(() => {
4840
+ const scope = (0, import_react26.useMemo)(() => tenant ? { tenant } : void 0, [tenant]);
4841
+ (0, import_react26.useEffect)(() => {
4765
4842
  if (!token) {
4766
4843
  return;
4767
4844
  }
@@ -4780,7 +4857,7 @@ function useCollection(collection, options = {}) {
4780
4857
  cancelled = true;
4781
4858
  };
4782
4859
  }, [client, token, collection, scope]);
4783
- (0, import_react25.useEffect)(() => {
4860
+ (0, import_react26.useEffect)(() => {
4784
4861
  if (!token || !schema) {
4785
4862
  return;
4786
4863
  }
@@ -4850,10 +4927,10 @@ function useCollection(collection, options = {}) {
4850
4927
  scope,
4851
4928
  reloadCount
4852
4929
  ]);
4853
- const reload = (0, import_react25.useCallback)(() => {
4930
+ const reload = (0, import_react26.useCallback)(() => {
4854
4931
  setReloadCount((count) => count + 1);
4855
4932
  }, []);
4856
- const loadMore = (0, import_react25.useCallback)(() => {
4933
+ const loadMore = (0, import_react26.useCallback)(() => {
4857
4934
  if (!token || !cursor) {
4858
4935
  return;
4859
4936
  }
@@ -4877,7 +4954,7 @@ function useCollection(collection, options = {}) {
4877
4954
  setLoading(false);
4878
4955
  });
4879
4956
  }, [client, token, collection, cursor, fixedFilters, filters, search, sort, limit, scope]);
4880
- const toggleSort = (0, import_react25.useCallback)((field) => {
4957
+ const toggleSort = (0, import_react26.useCallback)((field) => {
4881
4958
  setSort((current) => {
4882
4959
  if (current?.field !== field) {
4883
4960
  return { field, direction: "asc" };
@@ -4885,7 +4962,7 @@ function useCollection(collection, options = {}) {
4885
4962
  return current.direction === "asc" ? { field, direction: "desc" } : null;
4886
4963
  });
4887
4964
  }, []);
4888
- const create = (0, import_react25.useCallback)(
4965
+ const create = (0, import_react26.useCallback)(
4889
4966
  async (fields) => {
4890
4967
  if (!token) {
4891
4968
  return null;
@@ -4905,7 +4982,7 @@ function useCollection(collection, options = {}) {
4905
4982
  },
4906
4983
  [client, token, collection, scope, reload]
4907
4984
  );
4908
- const update = (0, import_react25.useCallback)(
4985
+ const update = (0, import_react26.useCallback)(
4909
4986
  async (id, fields) => {
4910
4987
  if (!token) {
4911
4988
  return null;
@@ -4927,7 +5004,7 @@ function useCollection(collection, options = {}) {
4927
5004
  },
4928
5005
  [client, token, collection, scope]
4929
5006
  );
4930
- const remove = (0, import_react25.useCallback)(
5007
+ const remove = (0, import_react26.useCallback)(
4931
5008
  async (id) => {
4932
5009
  if (!token) {
4933
5010
  return false;
@@ -4972,7 +5049,7 @@ function useCollection(collection, options = {}) {
4972
5049
  }
4973
5050
 
4974
5051
  // src/RecordForm.tsx
4975
- var import_jsx_runtime26 = require("react/jsx-runtime");
5052
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4976
5053
  function RecordForm({
4977
5054
  collection,
4978
5055
  recordId,
@@ -4993,20 +5070,20 @@ function RecordForm({
4993
5070
  recordId
4994
5071
  }
4995
5072
  );
4996
- const [values, setValues] = (0, import_react26.useState)(defaults ?? {});
4997
- const [loaded, setLoaded] = (0, import_react26.useState)(!recordId);
5073
+ const [values, setValues] = (0, import_react27.useState)(defaults ?? {});
5074
+ const [loaded, setLoaded] = (0, import_react27.useState)(!recordId);
4998
5075
  const existing = recordId ? records.find((record) => record.id === recordId) : void 0;
4999
- (0, import_react26.useEffect)(() => {
5076
+ (0, import_react27.useEffect)(() => {
5000
5077
  if (existing && !loaded) {
5001
5078
  setValues(existing.fields);
5002
5079
  setLoaded(true);
5003
5080
  }
5004
5081
  }, [existing, loaded]);
5005
5082
  if (error) {
5006
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5083
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5007
5084
  }
5008
5085
  if (!schema || !loaded) {
5009
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5086
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5010
5087
  }
5011
5088
  const editable = schema.fields.filter((field) => !(0, import_sdk7.specFor)(field).computed);
5012
5089
  async function submit(event) {
@@ -5016,11 +5093,11 @@ function RecordForm({
5016
5093
  onSaved?.(saved.id);
5017
5094
  }
5018
5095
  }
5019
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5020
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5021
- fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5096
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("form", { className: cls("b316-card b316-form", className), style, onSubmit: submit, children: [
5097
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h3", { className: "b316-form-title", children: recordId ? `Edit ${schema.name.toLowerCase()}` : `New ${schema.name.toLowerCase()}` }),
5098
+ fieldErrors._ ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: fieldErrors._ }) : null,
5022
5099
  editable.map(
5023
- (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5100
+ (field) => field.type === "RELATION" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5024
5101
  RelationPicker,
5025
5102
  {
5026
5103
  field,
@@ -5031,7 +5108,7 @@ function RecordForm({
5031
5108
  onChange: (next) => setValues((current) => ({ ...current, [field.key]: next }))
5032
5109
  },
5033
5110
  field.key
5034
- ) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5111
+ ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5035
5112
  FieldInput,
5036
5113
  {
5037
5114
  field,
@@ -5043,15 +5120,15 @@ function RecordForm({
5043
5120
  field.key
5044
5121
  )
5045
5122
  ),
5046
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "b316-form-actions", children: [
5047
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5048
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5123
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-form-actions", children: [
5124
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onCancel, disabled: saving, children: "Cancel" }) : null,
5125
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "submit", className: "b316-button", disabled: saving, children: saving ? "Saving\u2026" : "Save" })
5049
5126
  ] })
5050
5127
  ] });
5051
5128
  }
5052
5129
 
5053
5130
  // src/DataTable.tsx
5054
- var import_jsx_runtime27 = require("react/jsx-runtime");
5131
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5055
5132
  function DataTable({
5056
5133
  collection,
5057
5134
  columns,
@@ -5080,13 +5157,13 @@ function DataTable({
5080
5157
  loadMore,
5081
5158
  remove
5082
5159
  } = useCollection(collection, options);
5083
- const [editing, setEditing] = (0, import_react27.useState)(null);
5084
- const [removeFailed, setRemoveFailed] = (0, import_react27.useState)(null);
5160
+ const [editing, setEditing] = (0, import_react28.useState)(null);
5161
+ const [removeFailed, setRemoveFailed] = (0, import_react28.useState)(null);
5085
5162
  if (error) {
5086
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5163
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5087
5164
  }
5088
5165
  if (!schema) {
5089
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5166
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5090
5167
  }
5091
5168
  const shown = columns ? (
5092
5169
  // Ordered by what was asked for, not by the schema: a caller naming
@@ -5095,10 +5172,10 @@ function DataTable({
5095
5172
  ) : schema.fields;
5096
5173
  const searchable = schema.fields.some((field) => (0, import_sdk8.specFor)(field).capabilities.searchable);
5097
5174
  const writable = canWrite && !readOnly;
5098
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5099
- removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5100
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-table-bar", children: [
5101
- searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5175
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cls("b316-table-wrap", className), style, children: [
5176
+ removeFailed ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: removeFailed }) : null,
5177
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-bar", children: [
5178
+ searchable && !hideSearch ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5102
5179
  "input",
5103
5180
  {
5104
5181
  type: "search",
@@ -5108,25 +5185,25 @@ function DataTable({
5108
5185
  value: search,
5109
5186
  onChange: (event) => setSearch(event.target.value)
5110
5187
  }
5111
- ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", {}),
5112
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "b316-table-actions", children: [
5113
- /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "b316-muted", children: [
5188
+ ) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", {}),
5189
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-table-actions", children: [
5190
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "b316-muted", children: [
5114
5191
  total,
5115
5192
  " ",
5116
5193
  total === 1 ? schema.name.toLowerCase() : schema.namePlural.toLowerCase()
5117
5194
  ] }),
5118
- writable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5195
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "b316-button", onClick: () => setEditing("new"), children: [
5119
5196
  "New ",
5120
5197
  schema.name.toLowerCase()
5121
5198
  ] }) : null
5122
5199
  ] })
5123
5200
  ] }),
5124
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("table", { className: "b316-table", children: [
5125
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("tr", { children: [
5201
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("table", { className: "b316-table", children: [
5202
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("tr", { children: [
5126
5203
  shown.map((field) => {
5127
5204
  const sortable = (0, import_sdk8.specFor)(field).capabilities.sortable;
5128
5205
  const active = sort?.field === field.key;
5129
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5206
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "col", "aria-sort": ariaSort(active, sort?.direction), children: sortable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5130
5207
  "button",
5131
5208
  {
5132
5209
  type: "button",
@@ -5134,20 +5211,20 @@ function DataTable({
5134
5211
  onClick: () => toggleSort(field.key),
5135
5212
  children: [
5136
5213
  field.label,
5137
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5214
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { "aria-hidden": "true", children: active ? sort?.direction === "desc" ? " \u2193" : " \u2191" : " \u2195" })
5138
5215
  ]
5139
5216
  }
5140
5217
  ) : field.label }, field.key);
5141
5218
  }),
5142
- writable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5219
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "col", className: "b316-table-rowactions" }) : null
5143
5220
  ] }) }),
5144
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5221
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tbody", { children: records.map((record) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5145
5222
  "tr",
5146
5223
  {
5147
5224
  className: onSelect ? "b316-row-clickable" : void 0,
5148
5225
  onClick: onSelect ? () => onSelect(record) : void 0,
5149
5226
  children: [
5150
- shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5227
+ shown.map((field) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("td", { children: renderCell?.(record, field) ?? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5151
5228
  FieldCell,
5152
5229
  {
5153
5230
  value: record.fields[field.key] ?? null,
@@ -5155,8 +5232,8 @@ function DataTable({
5155
5232
  related: record.related[field.key]
5156
5233
  }
5157
5234
  ) }, field.key)),
5158
- writable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("td", { className: "b316-table-rowactions", children: [
5159
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5235
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("td", { className: "b316-table-rowactions", children: [
5236
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5160
5237
  "button",
5161
5238
  {
5162
5239
  type: "button",
@@ -5168,7 +5245,7 @@ function DataTable({
5168
5245
  children: "Edit"
5169
5246
  }
5170
5247
  ),
5171
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5248
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5172
5249
  ConfirmButton,
5173
5250
  {
5174
5251
  className: "b316-button-quiet b316-danger",
@@ -5192,10 +5269,10 @@ function DataTable({
5192
5269
  record.id
5193
5270
  )) })
5194
5271
  ] }) }),
5195
- records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5196
- loading ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5197
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5198
- editing ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5272
+ records.length === 0 && !loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: emptyState ?? `No ${schema.namePlural.toLowerCase()} yet.` }) : null,
5273
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-empty", children: "Loading\u2026" }) : null,
5274
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: "Load more" }) }) : null,
5275
+ editing ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5199
5276
  RecordForm,
5200
5277
  {
5201
5278
  collection,
@@ -5219,8 +5296,8 @@ function ariaSort(active, direction) {
5219
5296
 
5220
5297
  // src/Kanban.tsx
5221
5298
  var import_sdk9 = require("@base316/sdk");
5222
- var import_react28 = require("react");
5223
- var import_jsx_runtime28 = require("react/jsx-runtime");
5299
+ var import_react29 = require("react");
5300
+ var import_jsx_runtime29 = require("react/jsx-runtime");
5224
5301
  function Kanban({
5225
5302
  collection,
5226
5303
  groupBy,
@@ -5237,17 +5314,17 @@ function Kanban({
5237
5314
  limit: options.limit ?? 100,
5238
5315
  ...options
5239
5316
  });
5240
- const [dragging, setDragging] = (0, import_react28.useState)(null);
5241
- const [over, setOver] = (0, import_react28.useState)(null);
5317
+ const [dragging, setDragging] = (0, import_react29.useState)(null);
5318
+ const [over, setOver] = (0, import_react29.useState)(null);
5242
5319
  if (error) {
5243
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5320
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5244
5321
  }
5245
5322
  if (!schema) {
5246
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5323
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5247
5324
  }
5248
5325
  const field = groupBy ? schema.fields.find((candidate) => candidate.key === groupBy) ?? null : (0, import_sdk9.defaultGroupFieldOf)(schema.fields);
5249
5326
  if (!field || !(0, import_sdk9.specFor)(field).capabilities.groupable) {
5250
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5327
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: groupBy ? `"${groupBy}" cannot make columns. A board groups by a choice, a yes/no or a date.` : `${schema.namePlural} have no field to group by. Add a choice field \u2014 a status or a stage \u2014 and this board will use it.` });
5251
5328
  }
5252
5329
  const columns = columnsFor(field);
5253
5330
  const shown = cardFields ? cardFields.map((key) => schema.fields.find((candidate) => candidate.key === key)).filter((candidate) => Boolean(candidate)) : (
@@ -5264,12 +5341,12 @@ function Kanban({
5264
5341
  }
5265
5342
  await update(record.id, { [field.key]: value });
5266
5343
  }
5267
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5268
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5344
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cls("b316-board-wrap", className), style, children: [
5345
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board", role: "list", children: columns.map((column) => {
5269
5346
  const inColumn = records.filter(
5270
5347
  (record) => String(record.fields[field.key] ?? "") === String(column.value ?? "")
5271
5348
  );
5272
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5349
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5273
5350
  "section",
5274
5351
  {
5275
5352
  className: over === String(column.value) ? "b316-board-column b316-board-over" : "b316-board-column",
@@ -5293,12 +5370,12 @@ function Kanban({
5293
5370
  setDragging(null);
5294
5371
  },
5295
5372
  children: [
5296
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("header", { className: "b316-board-head", children: [
5297
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-board-title", children: column.label }),
5298
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: inColumn.length })
5373
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "b316-board-head", children: [
5374
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-board-title", children: column.label }),
5375
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: inColumn.length })
5299
5376
  ] }),
5300
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-board-cards", children: [
5301
- inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
5377
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-cards", children: [
5378
+ inColumn.map((record) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5302
5379
  "article",
5303
5380
  {
5304
5381
  className: "b316-board-card",
@@ -5310,10 +5387,10 @@ function Kanban({
5310
5387
  },
5311
5388
  onClick: onSelect ? () => onSelect(record) : void 0,
5312
5389
  children: [
5313
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5314
- shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "b316-board-card-field", children: [
5315
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: candidate.label }),
5316
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5390
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board-card-title", children: record.title ?? "Untitled" }),
5391
+ shown.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-board-card-field", children: [
5392
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: candidate.label }),
5393
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5317
5394
  FieldCell,
5318
5395
  {
5319
5396
  value: record.fields[candidate.key] ?? null,
@@ -5326,9 +5403,9 @@ function Kanban({
5326
5403
  // Dragging is not reachable by keyboard and is awkward on a
5327
5404
  // phone. This is the same action by other means, not a
5328
5405
  // lesser fallback.
5329
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("label", { className: "b316-board-move", children: [
5330
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "b316-muted", children: "Move to" }),
5331
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
5406
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("label", { className: "b316-board-move", children: [
5407
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-muted", children: "Move to" }),
5408
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5332
5409
  "select",
5333
5410
  {
5334
5411
  className: "b316-input",
@@ -5340,7 +5417,7 @@ function Kanban({
5340
5417
  );
5341
5418
  void move(record, chosen?.value ?? null);
5342
5419
  },
5343
- children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5420
+ children: columns.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("option", { value: String(candidate.value), children: candidate.label }, String(candidate.value)))
5344
5421
  }
5345
5422
  )
5346
5423
  ] })
@@ -5349,14 +5426,14 @@ function Kanban({
5349
5426
  },
5350
5427
  record.id
5351
5428
  )),
5352
- inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5429
+ inColumn.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-board-empty", children: emptyState ?? "Nothing here" }) : null
5353
5430
  ] })
5354
5431
  ]
5355
5432
  },
5356
5433
  String(column.value)
5357
5434
  );
5358
5435
  }) }),
5359
- hasMore ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5436
+ hasMore ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-table-more", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("button", { type: "button", className: "b316-button-quiet", onClick: loadMore, disabled: loading, children: [
5360
5437
  "Showing ",
5361
5438
  records.length,
5362
5439
  " of ",
@@ -5378,8 +5455,8 @@ function columnsFor(field) {
5378
5455
 
5379
5456
  // src/Chart.tsx
5380
5457
  var import_sdk10 = require("@base316/sdk");
5381
- var import_react29 = require("react");
5382
- var import_jsx_runtime29 = require("react/jsx-runtime");
5458
+ var import_react30 = require("react");
5459
+ var import_jsx_runtime30 = require("react/jsx-runtime");
5383
5460
  function Chart({
5384
5461
  collection,
5385
5462
  x,
@@ -5398,7 +5475,7 @@ function Chart({
5398
5475
  limit: options.limit ?? 200,
5399
5476
  ...options
5400
5477
  });
5401
- const axis = (0, import_react29.useMemo)(() => {
5478
+ const axis = (0, import_react30.useMemo)(() => {
5402
5479
  if (!schema) {
5403
5480
  return null;
5404
5481
  }
@@ -5406,35 +5483,35 @@ function Chart({
5406
5483
  const chosen = x ? schema.fields.find((field) => field.key === x) ?? null : timeFields[0] ?? null;
5407
5484
  return chosen && (0, import_sdk10.specFor)(chosen).capabilities.timeAxis ? chosen : null;
5408
5485
  }, [schema, x]);
5409
- const measure = (0, import_react29.useMemo)(() => {
5486
+ const measure = (0, import_react30.useMemo)(() => {
5410
5487
  if (!schema || !y) {
5411
5488
  return null;
5412
5489
  }
5413
5490
  const candidates = (0, import_sdk10.fieldsAggregatableBy)(schema.fields, aggregate);
5414
5491
  return candidates.find((field) => field.key === y) ?? null;
5415
5492
  }, [schema, y, aggregate]);
5416
- const buckets = (0, import_react29.useMemo)(
5493
+ const buckets = (0, import_react30.useMemo)(
5417
5494
  () => axis ? bucketise(records, axis, measure, y ? aggregate : "count", bucket) : [],
5418
5495
  [records, axis, measure, aggregate, bucket, y]
5419
5496
  );
5420
5497
  if (error) {
5421
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5498
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5422
5499
  }
5423
5500
  if (!schema || loading) {
5424
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5501
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5425
5502
  }
5426
5503
  if (!axis) {
5427
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5504
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: x ? `"${x}" is not a date, so it cannot be a time axis.` : `${schema.namePlural} have no date field to chart against. Add one and this chart will use it.` });
5428
5505
  }
5429
5506
  if (y && !measure) {
5430
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5507
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: `"${y}" cannot be ${aggregate === "avg" ? "averaged" : `combined with ${aggregate}`}.` });
5431
5508
  }
5432
5509
  const peak = Math.max(...buckets.map((entry) => entry.value), 0);
5433
5510
  const heading = title ?? `${measure ? `${aggregate} of ${measure.label}` : schema.namePlural} by ${axis.label}`;
5434
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5435
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5436
- buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "b316-chart-col", children: [
5437
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5511
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("figure", { className: cls("b316-card b316-chart", className), style, children: [
5512
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("figcaption", { className: "b316-chart-title", children: heading }),
5513
+ buckets.length === 0 || peak === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-empty", children: "Nothing to chart yet." }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-chart-plot", style: { height }, children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-chart-col", children: [
5514
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5438
5515
  "div",
5439
5516
  {
5440
5517
  className: "b316-chart-bar",
@@ -5442,18 +5519,18 @@ function Chart({
5442
5519
  title: `${entry.label}: ${format(entry.value)}`
5443
5520
  }
5444
5521
  ),
5445
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "b316-chart-label", children: entry.label })
5522
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "b316-chart-label", children: entry.label })
5446
5523
  ] }, entry.key)) }),
5447
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("details", { className: "b316-chart-data", children: [
5448
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("summary", { children: "Values" }),
5449
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("table", { className: "b316-table", children: [
5450
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("tr", { children: [
5451
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("th", { scope: "col", children: axis.label }),
5452
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
5524
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("details", { className: "b316-chart-data", children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("summary", { children: "Values" }),
5526
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "b316-table", children: [
5527
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5528
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", children: axis.label }),
5529
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("th", { scope: "col", children: measure ? measure.label : "Count" })
5453
5530
  ] }) }),
5454
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("tr", { children: [
5455
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("td", { children: entry.label }),
5456
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("td", { children: format(entry.value) })
5531
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: buckets.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
5532
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: entry.label }),
5533
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { children: format(entry.value) })
5457
5534
  ] }, entry.key)) })
5458
5535
  ] })
5459
5536
  ] })
@@ -5512,8 +5589,8 @@ function combine(values, aggregate) {
5512
5589
 
5513
5590
  // src/RecordDetail.tsx
5514
5591
  var import_sdk11 = require("@base316/sdk");
5515
- var import_react30 = require("react");
5516
- var import_jsx_runtime30 = require("react/jsx-runtime");
5592
+ var import_react31 = require("react");
5593
+ var import_jsx_runtime31 = require("react/jsx-runtime");
5517
5594
  function RecordDetail({
5518
5595
  collection,
5519
5596
  recordId,
@@ -5529,23 +5606,23 @@ function RecordDetail({
5529
5606
  tenant,
5530
5607
  recordId
5531
5608
  });
5532
- const [editing, setEditing] = (0, import_react30.useState)(false);
5609
+ const [editing, setEditing] = (0, import_react31.useState)(false);
5533
5610
  const record = records.find((candidate) => candidate.id === recordId);
5534
5611
  if (error) {
5535
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5612
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5536
5613
  }
5537
5614
  if (!schema || loading) {
5538
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5615
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5539
5616
  }
5540
5617
  if (!record) {
5541
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cls("b316-card", className), style, children: [
5618
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card", className), style, children: [
5542
5619
  "That ",
5543
5620
  schema.name.toLowerCase(),
5544
5621
  " is not available."
5545
5622
  ] });
5546
5623
  }
5547
5624
  if (editing) {
5548
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5625
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5549
5626
  RecordForm,
5550
5627
  {
5551
5628
  collection,
@@ -5559,12 +5636,12 @@ function RecordDetail({
5559
5636
  );
5560
5637
  }
5561
5638
  const writable = canWrite && !readOnly;
5562
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5563
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-detail-head", children: [
5564
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5565
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-detail-actions", children: [
5566
- writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5567
- writable ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5639
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card b316-detail", className), style, children: [
5640
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-head", children: [
5641
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("h3", { className: "b316-detail-title", children: record.title ?? schema.name }),
5642
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-actions", children: [
5643
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: () => setEditing(true), children: "Edit" }) : null,
5644
+ writable ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5568
5645
  ConfirmButton,
5569
5646
  {
5570
5647
  className: "b316-button-quiet b316-danger",
@@ -5577,15 +5654,15 @@ function RecordDetail({
5577
5654
  children: "Delete"
5578
5655
  }
5579
5656
  ) : null,
5580
- onClose ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5657
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("button", { type: "button", className: "b316-button-quiet", onClick: onClose, children: "Close" }) : null
5581
5658
  ] })
5582
5659
  ] }),
5583
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "b316-detail-row", children: [
5584
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("dt", { className: "b316-label", children: [
5660
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("dl", { className: "b316-detail-fields", children: schema.fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-detail-row", children: [
5661
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("dt", { className: "b316-label", children: [
5585
5662
  field.label,
5586
- (0, import_sdk11.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
5663
+ (0, import_sdk11.specFor)(field).computed ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "b316-muted", children: " (calculated)" }) : null
5587
5664
  ] }),
5588
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
5665
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5589
5666
  FieldCell,
5590
5667
  {
5591
5668
  value: record.fields[field.key] ?? null,
@@ -5599,25 +5676,57 @@ function RecordDetail({
5599
5676
  }
5600
5677
 
5601
5678
  // src/SubscriptionManager.tsx
5602
- var import_react31 = require("react");
5603
- var import_jsx_runtime31 = require("react/jsx-runtime");
5679
+ var import_react32 = require("react");
5680
+ var import_jsx_runtime32 = require("react/jsx-runtime");
5604
5681
  function statusLabel(status2) {
5605
5682
  const words = status2.toLowerCase().split("_");
5606
5683
  return words.map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
5607
5684
  }
5685
+ var REASONS = [
5686
+ { value: "TOO_EXPENSIVE", label: "It costs too much" },
5687
+ { value: "NOT_USING", label: "I am not using it enough" },
5688
+ { value: "MISSING_FEATURES", label: "It is missing something I need" },
5689
+ { value: "SWITCHING", label: "I am switching to something else" },
5690
+ { value: "TECHNICAL_ISSUES", label: "It did not work well for me" },
5691
+ { value: "TEMPORARY", label: "I only needed it for a while" },
5692
+ { value: "OTHER", label: "Something else" }
5693
+ ];
5694
+ function describeRetentionOffer(offer, currency) {
5695
+ let amount;
5696
+ if (offer.type === "PERCENTAGE") {
5697
+ amount = `${Number(offer.percentOff ?? "0")}% off`;
5698
+ } else {
5699
+ try {
5700
+ amount = `${new Intl.NumberFormat(void 0, {
5701
+ style: "currency",
5702
+ currency: offer.currency ?? currency
5703
+ }).format(Number(offer.amountOff ?? "0"))} off`;
5704
+ } catch {
5705
+ amount = `${offer.amountOff} ${offer.currency ?? currency} off`;
5706
+ }
5707
+ }
5708
+ if (offer.duration === "FOREVER") {
5709
+ return `${amount} for as long as you stay subscribed`;
5710
+ }
5711
+ const periods = offer.duration === "ONCE" ? 1 : offer.durationInPeriods ?? 1;
5712
+ return periods === 1 ? `${amount} your next invoice` : `${amount} your next ${periods} invoices`;
5713
+ }
5608
5714
  function SubscriptionManager({
5609
5715
  onChange,
5610
5716
  className,
5611
5717
  style
5612
5718
  }) {
5613
5719
  const { client, token, loading: sessionLoading } = useBase316();
5614
- const [subscription, setSubscription] = (0, import_react31.useState)(null);
5615
- const [loading, setLoading] = (0, import_react31.useState)(true);
5616
- const [managedBy, setManagedBy] = (0, import_react31.useState)(null);
5617
- const [schedule, setSchedule] = (0, import_react31.useState)([]);
5618
- const [busy, setBusy] = (0, import_react31.useState)(false);
5619
- const [error, setError] = (0, import_react31.useState)(null);
5620
- const load = (0, import_react31.useCallback)(async () => {
5720
+ const [subscription, setSubscription] = (0, import_react32.useState)(null);
5721
+ const [loading, setLoading] = (0, import_react32.useState)(true);
5722
+ const [managedBy, setManagedBy] = (0, import_react32.useState)(null);
5723
+ const [schedule, setSchedule] = (0, import_react32.useState)([]);
5724
+ const [busy, setBusy] = (0, import_react32.useState)(false);
5725
+ const [error, setError] = (0, import_react32.useState)(null);
5726
+ const [step, setStep] = (0, import_react32.useState)({ kind: "idle" });
5727
+ const [reason, setReason] = (0, import_react32.useState)(null);
5728
+ const [comment, setComment] = (0, import_react32.useState)("");
5729
+ const load = (0, import_react32.useCallback)(async () => {
5621
5730
  if (!token) {
5622
5731
  setSubscription(null);
5623
5732
  setLoading(false);
@@ -5635,7 +5744,7 @@ function SubscriptionManager({
5635
5744
  setLoading(false);
5636
5745
  }
5637
5746
  }, [client, token]);
5638
- (0, import_react31.useEffect)(() => {
5747
+ (0, import_react32.useEffect)(() => {
5639
5748
  void load();
5640
5749
  }, [load]);
5641
5750
  const act = async (change, failure) => {
@@ -5653,29 +5762,29 @@ function SubscriptionManager({
5653
5762
  }
5654
5763
  };
5655
5764
  if (sessionLoading || loading) {
5656
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5765
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
5657
5766
  }
5658
5767
  if (!token) {
5659
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
5768
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your subscription." });
5660
5769
  }
5661
5770
  if (error) {
5662
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5771
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
5663
5772
  }
5664
5773
  if (!subscription) {
5665
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
5774
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-card", className), style, children: "You are not subscribed to a plan." });
5666
5775
  }
5667
5776
  const renews = new Date(subscription.currentPeriodEnd).toLocaleDateString();
5668
5777
  const next = schedule[0] ?? null;
5669
5778
  const nextOn = next?.effectiveAt ? new Date(next.effectiveAt).toLocaleDateString() : renews;
5670
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cls("b316-card", className), style, children: [
5671
- error ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
5672
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5673
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-muted", children: [
5779
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: cls("b316-card", className), style, children: [
5780
+ error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
5781
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: subscription.planVersion.plan.name }),
5782
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-muted", children: [
5674
5783
  statusLabel(subscription.status),
5675
5784
  " \xB7 ",
5676
5785
  subscription.cancelAtPeriodEnd ? `Ends ${renews}` : `Renews ${renews}`
5677
5786
  ] }),
5678
- next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
5787
+ next && !managedBy ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-muted", role: "status", style: { marginTop: 10 }, children: [
5679
5788
  "Moves to ",
5680
5789
  next.plan.name,
5681
5790
  " on ",
@@ -5683,7 +5792,7 @@ function SubscriptionManager({
5683
5792
  ". You keep ",
5684
5793
  subscription.planVersion.plan.name,
5685
5794
  " until then.",
5686
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5795
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5687
5796
  "button",
5688
5797
  {
5689
5798
  type: "button",
@@ -5708,17 +5817,17 @@ function SubscriptionManager({
5708
5817
  }
5709
5818
  ) })
5710
5819
  ] }) : null,
5711
- managedBy ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "b316-muted", children: [
5820
+ managedBy ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
5712
5821
  "Provided by ",
5713
5822
  managedBy.name ?? "the organization that manages your account",
5714
5823
  ". Ask them to change or cancel it."
5715
- ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { children: [
5716
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("p", { className: "b316-muted", children: [
5824
+ ] }) : subscription.cancelAtPeriodEnd ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
5825
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
5717
5826
  "This subscription will not renew. You keep access until ",
5718
5827
  renews,
5719
5828
  "."
5720
5829
  ] }),
5721
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5830
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5722
5831
  "button",
5723
5832
  {
5724
5833
  type: "button",
@@ -5728,29 +5837,140 @@ function SubscriptionManager({
5728
5837
  children: busy ? "Working\u2026" : "Resume subscription"
5729
5838
  }
5730
5839
  )
5731
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
5732
- ConfirmButton,
5840
+ ] }) : step.kind === "offer" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("section", { style: { marginTop: 14 }, "aria-label": "Retention offer", children: [
5841
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-plan-name", children: step.cancellation.offer.headline ?? "Before you go" }),
5842
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "b316-muted", children: step.cancellation.offer.message ?? `Stay on ${subscription.planVersion.plan.name} and get ${describeRetentionOffer(
5843
+ step.cancellation.offer,
5844
+ step.cancellation.currency
5845
+ )}.` }),
5846
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5847
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5848
+ "button",
5849
+ {
5850
+ type: "button",
5851
+ className: "b316-button",
5852
+ disabled: busy,
5853
+ onClick: () => void act(async () => {
5854
+ await client.billing.acceptRetentionOffer(token, step.cancellation.id);
5855
+ setStep({ kind: "idle" });
5856
+ }, "Could not apply the offer. Try again."),
5857
+ children: busy ? "Working\u2026" : "Accept offer and stay"
5858
+ }
5859
+ ),
5860
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5861
+ "button",
5862
+ {
5863
+ type: "button",
5864
+ className: "b316-button b316-button-secondary",
5865
+ disabled: busy,
5866
+ onClick: () => void act(async () => {
5867
+ await client.billing.confirmCancellation(token, step.cancellation.id);
5868
+ setStep({ kind: "idle" });
5869
+ }, "Could not cancel. Try again."),
5870
+ children: "No thanks, cancel"
5871
+ }
5872
+ )
5873
+ ] }),
5874
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
5875
+ "If you cancel, you keep access until ",
5876
+ renews,
5877
+ "."
5878
+ ] })
5879
+ ] }) : step.kind === "survey" ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5880
+ "form",
5881
+ {
5882
+ style: { marginTop: 14 },
5883
+ onSubmit: (event) => {
5884
+ event.preventDefault();
5885
+ void act(async () => {
5886
+ const started = await client.billing.startCancellation(token, {
5887
+ reason,
5888
+ comment: comment.trim() || null
5889
+ });
5890
+ if (started.offer) {
5891
+ setStep({ kind: "offer", cancellation: { ...started, offer: started.offer } });
5892
+ return;
5893
+ }
5894
+ await client.billing.confirmCancellation(token, started.id);
5895
+ setStep({ kind: "idle" });
5896
+ }, "Could not cancel. Try again.");
5897
+ },
5898
+ children: [
5899
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
5900
+ "You keep access until ",
5901
+ renews,
5902
+ ". It will not renew after that."
5903
+ ] }),
5904
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("fieldset", { className: "b316-fieldset", children: [
5905
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("legend", { className: "b316-label", children: "Why are you leaving? (optional)" }),
5906
+ REASONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
5907
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5908
+ "input",
5909
+ {
5910
+ type: "radio",
5911
+ name: "b316-cancel-reason",
5912
+ value: option.value,
5913
+ checked: reason === option.value,
5914
+ onChange: () => setReason(option.value)
5915
+ }
5916
+ ),
5917
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: option.label })
5918
+ ] }, option.value))
5919
+ ] }),
5920
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5921
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-label", children: "Anything else? (optional)" }),
5922
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5923
+ "textarea",
5924
+ {
5925
+ className: "b316-input",
5926
+ rows: 3,
5927
+ maxLength: 2e3,
5928
+ value: comment,
5929
+ onChange: (event) => setComment(event.target.value)
5930
+ }
5931
+ )
5932
+ ] }),
5933
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5934
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "submit", className: "b316-button b316-button-secondary", disabled: busy, children: busy ? "Working\u2026" : "Cancel subscription" }),
5935
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5936
+ "button",
5937
+ {
5938
+ type: "button",
5939
+ className: "b316-button",
5940
+ disabled: busy,
5941
+ onClick: () => setStep({ kind: "idle" }),
5942
+ children: [
5943
+ "Keep ",
5944
+ subscription.planVersion.plan.name
5945
+ ]
5946
+ }
5947
+ )
5948
+ ] })
5949
+ ]
5950
+ }
5951
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5952
+ "button",
5733
5953
  {
5954
+ type: "button",
5734
5955
  className: "b316-button b316-button-secondary",
5735
- confirmLabel: `Cancel at the end of the period (${renews})`,
5736
5956
  disabled: busy,
5737
- onConfirm: () => (
5738
- // Cancels at period end: the user paid for the period they
5739
- // are in, and ending it now would forfeit it.
5740
- act(() => client.billing.cancel(token), "Could not cancel. Try again.")
5741
- ),
5742
- children: busy ? "Working\u2026" : "Cancel subscription"
5957
+ onClick: () => {
5958
+ setReason(null);
5959
+ setComment("");
5960
+ setStep({ kind: "survey" });
5961
+ },
5962
+ children: "Cancel subscription"
5743
5963
  }
5744
5964
  ) })
5745
5965
  ] });
5746
5966
  }
5747
5967
 
5748
5968
  // src/BillingPortal.tsx
5749
- var import_react35 = require("react");
5969
+ var import_react36 = require("react");
5750
5970
 
5751
5971
  // src/CreditBalances.tsx
5752
- var import_react32 = require("react");
5753
- var import_jsx_runtime32 = require("react/jsx-runtime");
5972
+ var import_react33 = require("react");
5973
+ var import_jsx_runtime33 = require("react/jsx-runtime");
5754
5974
  function units(value) {
5755
5975
  return value === null ? "Unlimited" : Number(value).toLocaleString("en");
5756
5976
  }
@@ -5785,10 +6005,10 @@ function Feature({
5785
6005
  }) {
5786
6006
  const { client, token } = useBase316();
5787
6007
  const setting = feature.autoRecharge;
5788
- const [busy, setBusy] = (0, import_react32.useState)(false);
5789
- const [error, setError] = (0, import_react32.useState)(null);
5790
- const [saved, setSaved] = (0, import_react32.useState)(null);
5791
- const [pack, setPack] = (0, import_react32.useState)(feature.packs[0]?.id ?? "");
6008
+ const [busy, setBusy] = (0, import_react33.useState)(false);
6009
+ const [error, setError] = (0, import_react33.useState)(null);
6010
+ const [saved, setSaved] = (0, import_react33.useState)(null);
6011
+ const [pack, setPack] = (0, import_react33.useState)(feature.packs[0]?.id ?? "");
5792
6012
  const unit = feature.unit ? ` ${feature.unit}` : "";
5793
6013
  const warning = status(feature);
5794
6014
  const buy = async () => {
@@ -5842,33 +6062,33 @@ function Feature({
5842
6062
  setBusy(false);
5843
6063
  }
5844
6064
  };
5845
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
5846
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-label", children: feature.featureName }),
5847
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { children: [
5848
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("strong", { children: units(feature.remaining) }),
6065
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-card b316-credit-balance", children: [
6066
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-label", children: feature.featureName }),
6067
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
6068
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("strong", { children: units(feature.remaining) }),
5849
6069
  unit,
5850
6070
  " left"
5851
6071
  ] }),
5852
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-muted", children: [
6072
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-muted", children: [
5853
6073
  feature.allowance === null ? "Unlimited allowance" : `${units(feature.allowanceRemaining)} of ${units(feature.allowance)} included this period`,
5854
6074
  " ",
5855
6075
  "\xB7 ",
5856
6076
  units(feature.purchasedRemaining),
5857
6077
  " purchased"
5858
6078
  ] }),
5859
- warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
5860
- error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
5861
- saved ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
5862
- managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
5863
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
5864
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6079
+ warning && !managed ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: warning }) : null,
6080
+ error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6081
+ saved ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-notice", role: "status", children: saved }) : null,
6082
+ managed || feature.packs.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6083
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-row", style: { marginTop: 12 }, children: [
6084
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5865
6085
  "select",
5866
6086
  {
5867
6087
  className: "b316-input",
5868
6088
  "aria-label": "Pack to buy",
5869
6089
  value: pack,
5870
6090
  onChange: (event) => setPack(event.target.value),
5871
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("option", { value: option.id, children: [
6091
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("option", { value: option.id, children: [
5872
6092
  option.name,
5873
6093
  " \u2014 ",
5874
6094
  units(option.units),
@@ -5877,7 +6097,7 @@ function Feature({
5877
6097
  ] }, option.id))
5878
6098
  }
5879
6099
  ),
5880
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6100
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5881
6101
  "button",
5882
6102
  {
5883
6103
  type: "button",
@@ -5888,19 +6108,19 @@ function Feature({
5888
6108
  }
5889
6109
  )
5890
6110
  ] }),
5891
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
5892
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-checkbox", children: [
5893
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
6111
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("form", { onSubmit: save, style: { marginTop: 16 }, children: [
6112
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-checkbox", children: [
6113
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("input", { type: "checkbox", name: "enabled", defaultChecked: setting?.enabled ?? false }),
5894
6114
  " ",
5895
6115
  "Buy credits automatically when my balance runs low"
5896
6116
  ] }),
5897
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5898
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "b316-label", children: [
6117
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6118
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "b316-label", children: [
5899
6119
  "When fewer than this many",
5900
6120
  unit,
5901
6121
  " are left"
5902
6122
  ] }),
5903
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6123
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5904
6124
  "input",
5905
6125
  {
5906
6126
  className: "b316-input",
@@ -5911,21 +6131,21 @@ function Feature({
5911
6131
  }
5912
6132
  )
5913
6133
  ] }),
5914
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5915
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-label", children: "Buy" }),
5916
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6134
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6135
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "Buy" }),
6136
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5917
6137
  "select",
5918
6138
  {
5919
6139
  className: "b316-input",
5920
6140
  name: "creditPackId",
5921
6141
  defaultValue: setting?.creditPackId ?? feature.packs[0]?.id,
5922
- children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("option", { value: option.id, children: option.name }, option.id))
6142
+ children: feature.packs.map((option) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("option", { value: option.id, children: option.name }, option.id))
5923
6143
  }
5924
6144
  )
5925
6145
  ] }),
5926
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5927
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
5928
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6146
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6147
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "b316-label", children: "At most this many times a month" }),
6148
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5929
6149
  "input",
5930
6150
  {
5931
6151
  className: "b316-input",
@@ -5935,13 +6155,13 @@ function Feature({
5935
6155
  }
5936
6156
  )
5937
6157
  ] }),
5938
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("label", { className: "b316-field", children: [
5939
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "b316-label", children: [
6158
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("label", { className: "b316-field", children: [
6159
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { className: "b316-label", children: [
5940
6160
  "Spending at most (",
5941
6161
  setting?.currency ?? feature.packs[0]?.currency ?? "USD",
5942
6162
  ") a month"
5943
6163
  ] }),
5944
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6164
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5945
6165
  "input",
5946
6166
  {
5947
6167
  className: "b316-input",
@@ -5951,16 +6171,16 @@ function Feature({
5951
6171
  }
5952
6172
  )
5953
6173
  ] }),
5954
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
6174
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("button", { type: "submit", className: "b316-button", disabled: busy, children: "Save auto-recharge" })
5955
6175
  ] })
5956
6176
  ] })
5957
6177
  ] });
5958
6178
  }
5959
6179
  function CreditBalances({ onChange, className, style }) {
5960
6180
  const { client, token, loading: sessionLoading } = useBase316();
5961
- const [state, setState] = (0, import_react32.useState)({ kind: "loading" });
5962
- const [version, setVersion] = (0, import_react32.useState)(0);
5963
- (0, import_react32.useEffect)(() => {
6181
+ const [state, setState] = (0, import_react33.useState)({ kind: "loading" });
6182
+ const [version, setVersion] = (0, import_react33.useState)(0);
6183
+ (0, import_react33.useEffect)(() => {
5964
6184
  if (!token) return;
5965
6185
  let cancelled = false;
5966
6186
  client.billing.credits(token).then((credits2) => {
@@ -5973,24 +6193,24 @@ function CreditBalances({ onChange, className, style }) {
5973
6193
  cancelled = true;
5974
6194
  };
5975
6195
  }, [client, token, version]);
5976
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
6196
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-credit-balances", className), style, children: content });
5977
6197
  if (sessionLoading || !token || state.kind === "loading") return null;
5978
6198
  if (state.kind === "error") {
5979
6199
  return wrap(
5980
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
6200
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your credits." }) })
5981
6201
  );
5982
6202
  }
5983
6203
  const { credits } = state;
5984
6204
  if (credits.features.length === 0) return null;
5985
6205
  return wrap(
5986
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
5987
- credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("p", { className: "b316-muted", children: [
6206
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6207
+ credits.managedBy ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("p", { className: "b316-muted", children: [
5988
6208
  "Credits for this account come from",
5989
6209
  " ",
5990
6210
  credits.managedBy.name ?? "the organization that manages it",
5991
6211
  ", which manages them."
5992
6212
  ] }) : null,
5993
- credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6213
+ credits.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5994
6214
  Feature,
5995
6215
  {
5996
6216
  feature,
@@ -6007,19 +6227,19 @@ function CreditBalances({ onChange, className, style }) {
6007
6227
  }
6008
6228
 
6009
6229
  // src/PaymentMethod.tsx
6010
- var import_react33 = require("react");
6011
- var import_jsx_runtime33 = require("react/jsx-runtime");
6230
+ var import_react34 = require("react");
6231
+ var import_jsx_runtime34 = require("react/jsx-runtime");
6012
6232
  function brandName(brand) {
6013
6233
  if (!brand) return "Card";
6014
6234
  return brand.charAt(0).toUpperCase() + brand.slice(1);
6015
6235
  }
6016
6236
  function PaymentMethod({ returnUrl, className, style }) {
6017
6237
  const { client, token, loading: sessionLoading } = useBase316();
6018
- const [state, setState] = (0, import_react33.useState)({ kind: "loading" });
6019
- const [busy, setBusy] = (0, import_react33.useState)(false);
6020
- const [error, setError] = (0, import_react33.useState)(null);
6021
- const [version, setVersion] = (0, import_react33.useState)(0);
6022
- (0, import_react33.useEffect)(() => {
6238
+ const [state, setState] = (0, import_react34.useState)({ kind: "loading" });
6239
+ const [busy, setBusy] = (0, import_react34.useState)(false);
6240
+ const [error, setError] = (0, import_react34.useState)(null);
6241
+ const [version, setVersion] = (0, import_react34.useState)(0);
6242
+ (0, import_react34.useEffect)(() => {
6023
6243
  if (!token) return;
6024
6244
  let cancelled = false;
6025
6245
  client.billing.paymentMethods(token).then((result) => {
@@ -6035,7 +6255,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6035
6255
  cancelled = true;
6036
6256
  };
6037
6257
  }, [client, token, version]);
6038
- const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6258
+ const wrap = (content) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card b316-payment-method", className), style, children: content });
6039
6259
  if (sessionLoading) return wrap("Loading\u2026");
6040
6260
  if (!token) return wrap("Sign in to manage your payment method.");
6041
6261
  switch (state.kind) {
@@ -6043,11 +6263,11 @@ function PaymentMethod({ returnUrl, className, style }) {
6043
6263
  return wrap("Loading\u2026");
6044
6264
  case "error":
6045
6265
  return wrap(
6046
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6266
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your payment method." })
6047
6267
  );
6048
6268
  case "managed":
6049
6269
  return wrap(
6050
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6270
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "Your plan is paid for by the organization that manages it." })
6051
6271
  );
6052
6272
  }
6053
6273
  const card = state.cards.find((saved) => saved.isDefault) ?? null;
@@ -6066,31 +6286,31 @@ function PaymentMethod({ returnUrl, className, style }) {
6066
6286
  }
6067
6287
  };
6068
6288
  return wrap(
6069
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
6070
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-label", children: "Payment method" }),
6071
- card ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
6072
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { children: [
6289
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
6290
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Payment method" }),
6291
+ card ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6292
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6073
6293
  brandName(card.brand),
6074
6294
  " ending ",
6075
6295
  card.last4 ?? "????"
6076
6296
  ] }),
6077
- card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-muted", children: [
6297
+ card.expMonth && card.expYear ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
6078
6298
  "Expires ",
6079
6299
  String(card.expMonth).padStart(2, "0"),
6080
6300
  "/",
6081
6301
  card.expYear
6082
6302
  ] }) : null
6083
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6084
- others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { style: { marginTop: 12 }, children: [
6085
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6086
- others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6087
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { children: [
6303
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "No card on file." }),
6304
+ others.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: { marginTop: 12 }, children: [
6305
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-label", children: "Other saved cards" }),
6306
+ others.map((saved) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", style: { marginTop: 6 }, children: [
6307
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { children: [
6088
6308
  brandName(saved.brand),
6089
6309
  " ending ",
6090
6310
  saved.last4 ?? "????"
6091
6311
  ] }),
6092
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("span", { children: [
6093
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6312
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { children: [
6313
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6094
6314
  "button",
6095
6315
  {
6096
6316
  type: "button",
@@ -6104,7 +6324,7 @@ function PaymentMethod({ returnUrl, className, style }) {
6104
6324
  }
6105
6325
  ),
6106
6326
  " ",
6107
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6327
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6108
6328
  "button",
6109
6329
  {
6110
6330
  type: "button",
@@ -6120,8 +6340,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6120
6340
  ] })
6121
6341
  ] }, saved.id))
6122
6342
  ] }) : null,
6123
- error ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6124
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6343
+ error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6344
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6125
6345
  "button",
6126
6346
  {
6127
6347
  type: "button",
@@ -6150,8 +6370,8 @@ function PaymentMethod({ returnUrl, className, style }) {
6150
6370
  }
6151
6371
 
6152
6372
  // src/PlanChangeReview.tsx
6153
- var import_react34 = require("react");
6154
- var import_jsx_runtime34 = require("react/jsx-runtime");
6373
+ var import_react35 = require("react");
6374
+ var import_jsx_runtime35 = require("react/jsx-runtime");
6155
6375
  function money5(amount, currency) {
6156
6376
  if (amount === null) return "\u2014";
6157
6377
  const value = Number(amount);
@@ -6184,12 +6404,12 @@ function PlanChangeReview({
6184
6404
  style
6185
6405
  }) {
6186
6406
  const { client, token } = useBase316();
6187
- const [timing, setTiming] = (0, import_react34.useState)(void 0);
6188
- const [preview, setPreview] = (0, import_react34.useState)(null);
6189
- const [error, setError] = (0, import_react34.useState)(null);
6190
- const [needsCard, setNeedsCard] = (0, import_react34.useState)(false);
6191
- const [busy, setBusy] = (0, import_react34.useState)(false);
6192
- (0, import_react34.useEffect)(() => {
6407
+ const [timing, setTiming] = (0, import_react35.useState)(void 0);
6408
+ const [preview, setPreview] = (0, import_react35.useState)(null);
6409
+ const [error, setError] = (0, import_react35.useState)(null);
6410
+ const [needsCard, setNeedsCard] = (0, import_react35.useState)(false);
6411
+ const [busy, setBusy] = (0, import_react35.useState)(false);
6412
+ (0, import_react35.useEffect)(() => {
6193
6413
  if (!token) return;
6194
6414
  let cancelled = false;
6195
6415
  client.billing.previewPlanChange(token, planVersionId, timing).then((result) => {
@@ -6206,7 +6426,7 @@ function PlanChangeReview({
6206
6426
  cancelled = true;
6207
6427
  };
6208
6428
  }, [client, token, planVersionId, timing]);
6209
- const confirm = (0, import_react34.useCallback)(async () => {
6429
+ const confirm = (0, import_react35.useCallback)(async () => {
6210
6430
  if (!token || !preview) return;
6211
6431
  setBusy(true);
6212
6432
  setError(null);
@@ -6227,7 +6447,7 @@ function PlanChangeReview({
6227
6447
  setBusy(false);
6228
6448
  }
6229
6449
  }, [client, token, preview, planVersionId, onDone]);
6230
- const addCard = (0, import_react34.useCallback)(async () => {
6450
+ const addCard = (0, import_react35.useCallback)(async () => {
6231
6451
  if (onNeedsCard) {
6232
6452
  onNeedsCard();
6233
6453
  return;
@@ -6241,12 +6461,12 @@ function PlanChangeReview({
6241
6461
  setError("Cards cannot be added here right now.");
6242
6462
  }
6243
6463
  }, [client, token, onNeedsCard]);
6244
- const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6464
+ const card = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-card b316-plan-review", className), style, children: content });
6245
6465
  if (error && !preview) {
6246
6466
  return card(
6247
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
6248
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6249
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6467
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6468
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }),
6469
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: "Back" }) : null
6250
6470
  ] })
6251
6471
  );
6252
6472
  }
@@ -6259,26 +6479,26 @@ function PlanChangeReview({
6259
6479
  const otherReason = preview.timings[other]?.reason ?? null;
6260
6480
  const changes = preview.entitlements.filter((change) => change.change !== "UNCHANGED");
6261
6481
  return card(
6262
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
6263
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-plan-name", children: [
6482
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6483
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-plan-name", children: [
6264
6484
  "Change to ",
6265
6485
  to.planName
6266
6486
  ] }),
6267
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-muted", children: [
6487
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-muted", children: [
6268
6488
  "From ",
6269
6489
  from.planName
6270
6490
  ] }),
6271
- error ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6272
- changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("table", { className: "b316-review-table", children: [
6273
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("tr", { children: [
6274
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("th", { children: "Feature" }),
6275
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("th", { children: from.planName }),
6276
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("th", { children: to.planName })
6491
+ error ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6492
+ changes.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: "Every feature stays the same." }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("table", { className: "b316-review-table", children: [
6493
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6494
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: "Feature" }),
6495
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: from.planName }),
6496
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("th", { children: to.planName })
6277
6497
  ] }) }),
6278
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("tr", { children: [
6279
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { children: change.featureName }),
6280
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("td", { children: limitText(change.before, change.type) }),
6281
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6498
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("tbody", { children: changes.map((change) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("tr", { children: [
6499
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: change.featureName }),
6500
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("td", { children: limitText(change.before, change.type) }),
6501
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6282
6502
  "td",
6283
6503
  {
6284
6504
  className: change.change === "GAINED" || change.change === "INCREASED" ? "b316-review-gain" : "b316-review-loss",
@@ -6287,40 +6507,40 @@ function PlanChangeReview({
6287
6507
  )
6288
6508
  ] }, change.featureId)) })
6289
6509
  ] }),
6290
- preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { children: [
6510
+ preview.timing === "NOW" ? now.trialing ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
6291
6511
  "The change happens now. Your trial carries on until ",
6292
6512
  day4(now.trialEndsAt),
6293
6513
  ", and nothing is charged before then."
6294
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
6295
- Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", children: [
6296
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "b316-muted", children: [
6514
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
6515
+ Number(now.credit) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6516
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-muted", children: [
6297
6517
  "Credit for the unused part of ",
6298
6518
  from.planName
6299
6519
  ] }),
6300
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "b316-num", children: [
6520
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-num", children: [
6301
6521
  "\u2212",
6302
6522
  money5(now.credit, from.currency)
6303
6523
  ] })
6304
6524
  ] }) : null,
6305
- Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", children: [
6306
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6307
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6525
+ Number(now.closingUsage) > 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6526
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-muted", children: "Usage so far this period" }),
6527
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.closingUsage, from.currency) })
6308
6528
  ] }) : null,
6309
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row", children: [
6310
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("span", { className: "b316-muted", children: [
6529
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row", children: [
6530
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "b316-muted", children: [
6311
6531
  to.planName,
6312
6532
  ", ",
6313
6533
  day4(now.newPeriod.start),
6314
6534
  " \u2013 ",
6315
6535
  day4(now.newPeriod.end)
6316
6536
  ] }),
6317
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6537
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.newPeriodCharge, to.currency) })
6318
6538
  ] }),
6319
- now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6320
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { children: "Due now" }),
6321
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
6539
+ now.net !== null ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-row b316-invoice-total", children: [
6540
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { children: "Due now" }),
6541
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "b316-num", children: money5(now.net, to.currency) })
6322
6542
  ] }) : null
6323
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { children: [
6543
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("p", { children: [
6324
6544
  "You keep ",
6325
6545
  from.planName,
6326
6546
  " until ",
@@ -6333,7 +6553,7 @@ function PlanChangeReview({
6333
6553
  preview.atPeriodEnd.nextInvoice.currency
6334
6554
  )}.` : ""
6335
6555
  ] }),
6336
- otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6556
+ otherOpen ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6337
6557
  "button",
6338
6558
  {
6339
6559
  type: "button",
@@ -6344,12 +6564,12 @@ function PlanChangeReview({
6344
6564
  },
6345
6565
  children: other === "NOW" ? "Change now instead" : "Wait until the end of the period instead"
6346
6566
  }
6347
- ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6348
- needsCard ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-notice", role: "status", children: [
6567
+ ) : otherReason && TIMING_CLOSED[otherReason] ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "b316-muted", children: TIMING_CLOSED[otherReason] }) : null,
6568
+ needsCard ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-notice", role: "status", children: [
6349
6569
  "A card is needed for a change that is charged now.",
6350
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6351
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "b316-review-actions", children: [
6352
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6570
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-review-actions", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("button", { type: "button", className: "b316-button", onClick: () => void addCard(), children: "Add a card" }) })
6571
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "b316-review-actions", children: [
6572
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6353
6573
  "button",
6354
6574
  {
6355
6575
  type: "button",
@@ -6359,7 +6579,7 @@ function PlanChangeReview({
6359
6579
  children: busy ? "Working\u2026" : preview.timing === "NOW" ? `Change to ${to.planName} now` : `Schedule ${to.planName}`
6360
6580
  }
6361
6581
  ),
6362
- onCancel ? /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6582
+ onCancel ? /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("button", { type: "button", className: "b316-button b316-button-secondary", onClick: onCancel, children: [
6363
6583
  "Keep ",
6364
6584
  from.planName
6365
6585
  ] }) : null
@@ -6369,7 +6589,7 @@ function PlanChangeReview({
6369
6589
  }
6370
6590
 
6371
6591
  // src/BillingPortal.tsx
6372
- var import_jsx_runtime35 = require("react/jsx-runtime");
6592
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6373
6593
  function BillingPortal({
6374
6594
  returnUrl,
6375
6595
  featuredPlanKey,
@@ -6379,12 +6599,12 @@ function BillingPortal({
6379
6599
  style
6380
6600
  }) {
6381
6601
  const { client, token, loading: sessionLoading } = useBase316();
6382
- const [overview, setOverview] = (0, import_react35.useState)(null);
6383
- const [failed, setFailed] = (0, import_react35.useState)(false);
6384
- const [version, setVersion] = (0, import_react35.useState)(0);
6385
- const [reviewing, setReviewing] = (0, import_react35.useState)(null);
6386
- const [notice, setNotice] = (0, import_react35.useState)(null);
6387
- (0, import_react35.useEffect)(() => {
6602
+ const [overview, setOverview] = (0, import_react36.useState)(null);
6603
+ const [failed, setFailed] = (0, import_react36.useState)(false);
6604
+ const [version, setVersion] = (0, import_react36.useState)(0);
6605
+ const [reviewing, setReviewing] = (0, import_react36.useState)(null);
6606
+ const [notice, setNotice] = (0, import_react36.useState)(null);
6607
+ (0, import_react36.useEffect)(() => {
6388
6608
  if (!token) return;
6389
6609
  let cancelled = false;
6390
6610
  client.billing.subscription(token).then((result) => {
@@ -6403,28 +6623,28 @@ function BillingPortal({
6403
6623
  cancelled = true;
6404
6624
  };
6405
6625
  }, [client, token, version]);
6406
- const refresh = (0, import_react35.useCallback)(() => {
6626
+ const refresh = (0, import_react36.useCallback)(() => {
6407
6627
  setNotice(null);
6408
6628
  setVersion((value) => value + 1);
6409
6629
  }, []);
6410
- const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6411
- if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6412
- if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6630
+ const shell = (content) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-billing-portal", className), style, children: content });
6631
+ if (sessionLoading) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6632
+ if (!token) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Sign in to manage your billing." }));
6413
6633
  if (failed) {
6414
6634
  return shell(
6415
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6635
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: "Could not load your billing." }) })
6416
6636
  );
6417
6637
  }
6418
- if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6638
+ if (!overview) return shell(/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card", children: "Loading\u2026" }));
6419
6639
  const { subscription, managedBy, quantityPriced } = overview;
6420
6640
  const canChange = Boolean(subscription) && !managedBy;
6421
6641
  return shell(
6422
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
6423
- notice ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6424
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6425
- canChange ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6426
- canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6427
- reviewing ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6642
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
6643
+ notice ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-card b316-notice", role: "status", children: notice }) : null,
6644
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SubscriptionManager, { onChange: refresh }, `plan-${version}`),
6645
+ canChange ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(UpcomingInvoice, {}, `next-${version}`) : null,
6646
+ canChange && quantityPriced ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SeatManager, { unitLabel, onChange: refresh }, `seats-${version}`) : null,
6647
+ reviewing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6428
6648
  PlanChangeReview,
6429
6649
  {
6430
6650
  planVersionId: reviewing,
@@ -6437,9 +6657,9 @@ function BillingPortal({
6437
6657
  );
6438
6658
  }
6439
6659
  }
6440
- ) : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("section", { children: [
6441
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6442
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6660
+ ) : /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("section", { children: [
6661
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h2", { className: "b316-billing-portal-section-title", children: subscription ? "Change plan" : "Choose a plan" }),
6662
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6443
6663
  PricingTable,
6444
6664
  {
6445
6665
  featuredPlanKey,
@@ -6451,17 +6671,17 @@ function BillingPortal({
6451
6671
  `plans-${version}`
6452
6672
  )
6453
6673
  ] }),
6454
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CreditBalances, {}, `credits-${version}`),
6455
- managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
6456
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Invoices, {}, `invoices-${version}`),
6457
- billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6674
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CreditBalances, {}, `credits-${version}`),
6675
+ managedBy ? null : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PaymentMethod, { returnUrl }, `card-${version}`),
6676
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Invoices, {}, `invoices-${version}`),
6677
+ billingDetails === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(BillingDetailsForm, {}, `details-${version}`) : billingDetails
6458
6678
  ] })
6459
6679
  );
6460
6680
  }
6461
6681
 
6462
6682
  // src/ApiKeyManager.tsx
6463
- var import_react36 = require("react");
6464
- var import_jsx_runtime36 = require("react/jsx-runtime");
6683
+ var import_react37 = require("react");
6684
+ var import_jsx_runtime37 = require("react/jsx-runtime");
6465
6685
  function duration(seconds) {
6466
6686
  if (seconds % 3600 === 0) {
6467
6687
  return `${seconds / 3600}h`;
@@ -6478,17 +6698,17 @@ function ApiKeyManager({
6478
6698
  audience
6479
6699
  }) {
6480
6700
  const { client, token, loading: sessionLoading } = useBase316();
6481
- const [resources, setResources] = (0, import_react36.useState)([]);
6482
- const [credentials, setCredentials] = (0, import_react36.useState)([]);
6483
- const [loading, setLoading] = (0, import_react36.useState)(true);
6484
- const [busy, setBusy] = (0, import_react36.useState)(false);
6485
- const [error, setError] = (0, import_react36.useState)(null);
6486
- const [creating, setCreating] = (0, import_react36.useState)(false);
6487
- const [name, setName] = (0, import_react36.useState)("");
6488
- const [chosen, setChosen] = (0, import_react36.useState)([]);
6489
- const [resourceId, setResourceId] = (0, import_react36.useState)(null);
6490
- const [issued, setIssued] = (0, import_react36.useState)(null);
6491
- const load = (0, import_react36.useCallback)(async () => {
6701
+ const [resources, setResources] = (0, import_react37.useState)([]);
6702
+ const [credentials, setCredentials] = (0, import_react37.useState)([]);
6703
+ const [loading, setLoading] = (0, import_react37.useState)(true);
6704
+ const [busy, setBusy] = (0, import_react37.useState)(false);
6705
+ const [error, setError] = (0, import_react37.useState)(null);
6706
+ const [creating, setCreating] = (0, import_react37.useState)(false);
6707
+ const [name, setName] = (0, import_react37.useState)("");
6708
+ const [chosen, setChosen] = (0, import_react37.useState)([]);
6709
+ const [resourceId, setResourceId] = (0, import_react37.useState)(null);
6710
+ const [issued, setIssued] = (0, import_react37.useState)(null);
6711
+ const load = (0, import_react37.useCallback)(async () => {
6492
6712
  if (!token) {
6493
6713
  setLoading(false);
6494
6714
  return;
@@ -6509,20 +6729,20 @@ function ApiKeyManager({
6509
6729
  setLoading(false);
6510
6730
  }
6511
6731
  }, [client, token, audience]);
6512
- (0, import_react36.useEffect)(() => {
6732
+ (0, import_react37.useEffect)(() => {
6513
6733
  void load();
6514
6734
  }, [load]);
6515
6735
  if (sessionLoading || loading) {
6516
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6736
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "Loading\u2026" });
6517
6737
  }
6518
6738
  if (!token) {
6519
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
6739
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "Sign in to manage your API keys." });
6520
6740
  }
6521
6741
  if (error) {
6522
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6742
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) });
6523
6743
  }
6524
6744
  if (resources.length === 0) {
6525
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
6745
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cls("b316-card", className), style, children: "There are no APIs available to your account." });
6526
6746
  }
6527
6747
  const resource = resources.find((item) => item.id === resourceId) ?? resources[0];
6528
6748
  const reset = () => {
@@ -6531,37 +6751,37 @@ function ApiKeyManager({
6531
6751
  setChosen([]);
6532
6752
  setIssued(null);
6533
6753
  };
6534
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cls("b316-card", className), style, children: [
6535
- error ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6536
- resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6754
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cls("b316-card", className), style, children: [
6755
+ error ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-error", role: "alert", children: error }) : null,
6756
+ resources.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6537
6757
  "select",
6538
6758
  {
6539
6759
  className: "b316-input",
6540
6760
  value: resource.id,
6541
6761
  onChange: (event) => setResourceId(event.target.value),
6542
6762
  style: { marginBottom: 14 },
6543
- children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: item.id, children: item.name }, item.id))
6763
+ children: resources.map((item) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: item.id, children: item.name }, item.id))
6544
6764
  }
6545
- ) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-plan-name", children: resource.name }),
6546
- resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
6765
+ ) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: resource.name }),
6766
+ resource.rateLimit ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6547
6767
  resource.rateLimit.requestsPerWindow,
6548
6768
  " requests per",
6549
6769
  " ",
6550
6770
  duration(resource.rateLimit.windowSeconds),
6551
6771
  resource.rateLimit.burst > resource.rateLimit.requestsPerWindow ? `, bursting to ${resource.rateLimit.burst}` : null
6552
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
6553
- credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("li", { className: "b316-list-item", children: [
6554
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
6555
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-plan-name", children: credential.name }),
6556
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-muted", children: [
6557
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { children: credential.clientId }),
6772
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-muted", children: "No rate limit." }),
6773
+ credentials.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "b316-muted", style: { marginTop: 14 }, children: "You have no API keys yet." }) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("ul", { className: "b316-list", style: { marginTop: 14 }, children: credentials.map((credential) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("li", { className: "b316-list-item", children: [
6774
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { children: [
6775
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-plan-name", children: credential.name }),
6776
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-muted", children: [
6777
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: credential.clientId }),
6558
6778
  credential.secretLastFour ? ` \xB7 \u2026${credential.secretLastFour}` : null,
6559
6779
  credential.disabled ? " \xB7 Disabled" : null
6560
6780
  ] }),
6561
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
6781
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "b316-muted", children: credential.scopes.join(", ") })
6562
6782
  ] }),
6563
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
6564
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6783
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { display: "flex", gap: 8 }, children: [
6784
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6565
6785
  "button",
6566
6786
  {
6567
6787
  type: "button",
@@ -6590,7 +6810,7 @@ function ApiKeyManager({
6590
6810
  children: "Rotate"
6591
6811
  }
6592
6812
  ),
6593
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6813
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6594
6814
  ConfirmButton,
6595
6815
  {
6596
6816
  className: "b316-button b316-button-secondary",
@@ -6614,11 +6834,11 @@ function ApiKeyManager({
6614
6834
  )
6615
6835
  ] })
6616
6836
  ] }, credential.clientId)) }),
6617
- issued ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6618
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("strong", { children: "Copy this now." }),
6837
+ issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "b316-notice", style: { marginTop: 14 }, children: [
6838
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("strong", { children: "Copy this now." }),
6619
6839
  " It is shown once and cannot be retrieved again.",
6620
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
6621
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6840
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { style: { marginTop: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { style: { wordBreak: "break-all" }, children: issued.secret }) }),
6841
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6622
6842
  "button",
6623
6843
  {
6624
6844
  type: "button",
@@ -6631,7 +6851,7 @@ function ApiKeyManager({
6631
6851
  children: "Copy"
6632
6852
  }
6633
6853
  ),
6634
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6854
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6635
6855
  "button",
6636
6856
  {
6637
6857
  type: "button",
@@ -6642,8 +6862,8 @@ function ApiKeyManager({
6642
6862
  }
6643
6863
  )
6644
6864
  ] }) : null,
6645
- creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { marginTop: 14 }, children: [
6646
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6865
+ creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 14 }, children: [
6866
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6647
6867
  "input",
6648
6868
  {
6649
6869
  className: "b316-input",
@@ -6652,9 +6872,9 @@ function ApiKeyManager({
6652
6872
  onChange: (event) => setName(event.target.value)
6653
6873
  }
6654
6874
  ),
6655
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { marginTop: 10 }, children: [
6656
- resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-checkbox", children: [
6657
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6875
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { style: { marginTop: 10 }, children: [
6876
+ resource.availableScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox", children: [
6877
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6658
6878
  "input",
6659
6879
  {
6660
6880
  type: "checkbox",
@@ -6664,19 +6884,19 @@ function ApiKeyManager({
6664
6884
  )
6665
6885
  }
6666
6886
  ),
6667
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { children: scope.key }),
6668
- scope.description ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "b316-muted", children: [
6887
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6888
+ scope.description ? /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "b316-muted", children: [
6669
6889
  " \u2014 ",
6670
6890
  scope.description
6671
6891
  ] }) : null
6672
6892
  ] }, scope.key)),
6673
- resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
6674
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("input", { type: "checkbox", disabled: true }),
6675
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("code", { children: scope.key }),
6676
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: " \u2014 not included in your plan" })
6893
+ resource.lockedScopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "b316-checkbox b316-muted", children: [
6894
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("input", { type: "checkbox", disabled: true }),
6895
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("code", { children: scope.key }),
6896
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: " \u2014 not included in your plan" })
6677
6897
  ] }, scope.key))
6678
6898
  ] }),
6679
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6899
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6680
6900
  "button",
6681
6901
  {
6682
6902
  type: "button",
@@ -6710,7 +6930,7 @@ function ApiKeyManager({
6710
6930
  children: "Create key"
6711
6931
  }
6712
6932
  ),
6713
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6933
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6714
6934
  "button",
6715
6935
  {
6716
6936
  type: "button",
@@ -6721,7 +6941,7 @@ function ApiKeyManager({
6721
6941
  }
6722
6942
  )
6723
6943
  ] }) : null,
6724
- !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6944
+ !creating && !issued ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
6725
6945
  "button",
6726
6946
  {
6727
6947
  type: "button",
@@ -7005,7 +7225,7 @@ var MANIFEST = [
7005
7225
  {
7006
7226
  name: "TwoFactorManager",
7007
7227
  kind: "component",
7008
- summary: "Turn two-factor authentication on or off, by authenticator app, a code to the inbox or a code by text message.",
7228
+ summary: "Turn two-factor authentication on or off, by authenticator app (QR code and key), a code to the inbox or a code by text message.",
7009
7229
  useWhen: "A security settings page. The app is strongest; the emailed or texted code is the one people who will not install an app actually use.",
7010
7230
  requires: ["session"],
7011
7231
  props: [
@@ -7149,7 +7369,7 @@ var MANIFEST = [
7149
7369
  {
7150
7370
  name: "SubscriptionManager",
7151
7371
  kind: "component",
7152
- summary: "The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end (confirmed in the page) and resuming a cancelled one.",
7372
+ summary: "The current plan, its renewal date, a scheduled plan change with its undo, cancelling at the period end \u2014 asking why, and showing the environment's retention offer when it makes one \u2014 and resuming a cancelled one.",
7153
7373
  useWhen: "A billing settings page.",
7154
7374
  requires: ["session"],
7155
7375
  props: [