@fonderie/react-admin-screens 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -307,10 +307,74 @@ function RoutesScreen({ client }) {
307
307
  ] });
308
308
  }
309
309
 
310
+ // src/screens/MigrationsScreen.tsx
311
+ import { useAdminMigrations } from "@fonderie/react-admin";
312
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
313
+ function why(m, everApplied) {
314
+ if (m.pending.length === 0) return null;
315
+ if (m.blockedBy) return `Apply "${m.blockedBy}" first \u2014 it runs before this one and is behind.`;
316
+ if (everApplied && m.pending.some((p) => p.impact === "destructive"))
317
+ return "Contains a migration that deletes data. No down-migration brings it back \u2014 apply this one through CI or `npm run migrate`.";
318
+ return null;
319
+ }
320
+ function MigrationsScreen({ client }) {
321
+ const { report, isLoading, error, refresh, apply } = useAdminMigrations(client);
322
+ const behind = report?.modules.filter((m) => m.pending.length > 0) ?? [];
323
+ return /* @__PURE__ */ jsxs7("div", { style: styles.container, children: [
324
+ /* @__PURE__ */ jsx7("h1", { style: styles.title, children: "Migrations" }),
325
+ error ? /* @__PURE__ */ jsx7("p", { style: styles.error, role: "alert", children: error.status === 403 ? "Applying migrations needs a token with the write scope." : error.explanation }) : null,
326
+ /* @__PURE__ */ jsxs7("p", { children: [
327
+ /* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => void refresh(), disabled: isLoading, children: isLoading ? "Checking\u2026" : "Refresh" }),
328
+ " ",
329
+ report && !report.everApplied ? /* @__PURE__ */ jsx7("span", { style: styles.advice, children: "This database has never been migrated \u2014 treating it as a first install, so nothing is held back." }) : null
330
+ ] }),
331
+ report && behind.length === 0 ? /* @__PURE__ */ jsx7("p", { style: styles.ok, children: "Every module is up to date." }) : null,
332
+ behind.map((m) => {
333
+ const blocked = why(m, report?.everApplied ?? false);
334
+ const files = m.pending.map((p) => p.file);
335
+ return /* @__PURE__ */ jsxs7("section", { style: { marginBottom: 24 }, children: [
336
+ /* @__PURE__ */ jsxs7("h2", { style: styles.subtitle, children: [
337
+ m.name,
338
+ " \u2014 ",
339
+ m.pending.length,
340
+ " pending"
341
+ ] }),
342
+ /* @__PURE__ */ jsx7("ul", { children: m.pending.map((p) => /* @__PURE__ */ jsxs7("li", { children: [
343
+ /* @__PURE__ */ jsx7("code", { children: p.file }),
344
+ " ",
345
+ p.impact === "destructive" ? /* @__PURE__ */ jsx7("span", { style: styles.bad, children: "destructive" }) : /* @__PURE__ */ jsx7("span", { style: styles.advice, children: "additive" }),
346
+ p.destructive.length > 0 ? /* @__PURE__ */ jsx7("ul", { children: p.destructive.map((s) => /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsx7("code", { children: s.slice(0, 120) }) }, s)) }) : null
347
+ ] }, p.file)) }),
348
+ blocked ? /* @__PURE__ */ jsx7("p", { style: styles.advice, children: blocked }) : /* @__PURE__ */ jsxs7(
349
+ "button",
350
+ {
351
+ type: "button",
352
+ style: styles.button,
353
+ disabled: isLoading || !m.appliable,
354
+ onClick: () => {
355
+ if (window.confirm(
356
+ `Apply ${m.pending.length} migration(s) to "${m.name}"? This changes the database schema.`
357
+ ))
358
+ void apply(m.name, files).catch(() => {
359
+ });
360
+ },
361
+ children: [
362
+ "Apply ",
363
+ m.pending.length,
364
+ " migration",
365
+ m.pending.length === 1 ? "" : "s"
366
+ ]
367
+ }
368
+ )
369
+ ] }, m.name);
370
+ })
371
+ ] });
372
+ }
373
+
310
374
  // src/screens/TokensScreen.tsx
311
375
  import { useAdminTokens } from "@fonderie/react-admin";
312
376
  import { useState } from "react";
313
- import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
377
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
314
378
  var ALL = ["read", "write", "secrets"];
315
379
  function TokensScreen({ client }) {
316
380
  const { report, isLoading, error, issue, revoke } = useAdminTokens(client);
@@ -319,25 +383,25 @@ function TokensScreen({ client }) {
319
383
  const [days, setDays] = useState("");
320
384
  const [minted, setMinted] = useState(null);
321
385
  const toggle = (s) => setScopes((prev) => prev.includes(s) ? prev.filter((x) => x !== s) : [...prev, s]);
322
- return /* @__PURE__ */ jsxs7("div", { style: styles.container, children: [
323
- /* @__PURE__ */ jsx7("h1", { style: styles.title, children: "Access" }),
324
- error ? /* @__PURE__ */ jsx7("p", { style: styles.error, role: "alert", children: error.status === 401 ? "Issuing and revoking need the root token (the one in your deployment config)." : error.explanation }) : null,
325
- /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Root token" }),
326
- report ? /* @__PURE__ */ jsxs7("p", { children: [
327
- report.admin.ok ? /* @__PURE__ */ jsx7("span", { style: styles.ok, children: "strong" }) : /* @__PURE__ */ jsx7("span", { style: styles.bad, children: "weak" }),
328
- report.admin.problems.map((p) => /* @__PURE__ */ jsx7("div", { style: styles.bad, children: p.message }, p.message))
386
+ return /* @__PURE__ */ jsxs8("div", { style: styles.container, children: [
387
+ /* @__PURE__ */ jsx8("h1", { style: styles.title, children: "Access" }),
388
+ error ? /* @__PURE__ */ jsx8("p", { style: styles.error, role: "alert", children: error.status === 401 ? "Issuing and revoking need the root token (the one in your deployment config)." : error.explanation }) : null,
389
+ /* @__PURE__ */ jsx8("h2", { style: styles.subtitle, children: "Root token" }),
390
+ report ? /* @__PURE__ */ jsxs8("p", { children: [
391
+ report.admin.ok ? /* @__PURE__ */ jsx8("span", { style: styles.ok, children: "strong" }) : /* @__PURE__ */ jsx8("span", { style: styles.bad, children: "weak" }),
392
+ report.admin.problems.map((p) => /* @__PURE__ */ jsx8("div", { style: styles.bad, children: p.message }, p.message))
329
393
  ] }) : null,
330
- /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Issued tokens" }),
331
- report?.issued === null ? /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "Issuing is off \u2014 give AdminModule a store and run its migrations." }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
332
- minted ? /* @__PURE__ */ jsxs7("p", { style: styles.ok, children: [
394
+ /* @__PURE__ */ jsx8("h2", { style: styles.subtitle, children: "Issued tokens" }),
395
+ report?.issued === null ? /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "Issuing is off \u2014 give AdminModule a store and run its migrations." }) : /* @__PURE__ */ jsxs8(Fragment4, { children: [
396
+ minted ? /* @__PURE__ */ jsxs8("p", { style: styles.ok, children: [
333
397
  "Copy this now \u2014 it is never shown again.",
334
398
  " ",
335
- /* @__PURE__ */ jsx7("span", { style: styles.mono, children: minted.token }),
399
+ /* @__PURE__ */ jsx8("span", { style: styles.mono, children: minted.token }),
336
400
  " (",
337
401
  minted.name,
338
402
  ")"
339
403
  ] }) : null,
340
- /* @__PURE__ */ jsxs7(
404
+ /* @__PURE__ */ jsxs8(
341
405
  "form",
342
406
  {
343
407
  style: styles.toolbar,
@@ -356,7 +420,7 @@ function TokensScreen({ client }) {
356
420
  });
357
421
  },
358
422
  children: [
359
- /* @__PURE__ */ jsx7(
423
+ /* @__PURE__ */ jsx8(
360
424
  "input",
361
425
  {
362
426
  value: name,
@@ -366,12 +430,12 @@ function TokensScreen({ client }) {
366
430
  "aria-label": "Name"
367
431
  }
368
432
  ),
369
- ALL.map((s) => /* @__PURE__ */ jsxs7("label", { style: { ...styles.badge, cursor: "pointer" }, children: [
370
- /* @__PURE__ */ jsx7("input", { type: "checkbox", checked: scopes.includes(s), onChange: () => toggle(s) }),
433
+ ALL.map((s) => /* @__PURE__ */ jsxs8("label", { style: { ...styles.badge, cursor: "pointer" }, children: [
434
+ /* @__PURE__ */ jsx8("input", { type: "checkbox", checked: scopes.includes(s), onChange: () => toggle(s) }),
371
435
  " ",
372
436
  s
373
437
  ] }, s)),
374
- /* @__PURE__ */ jsx7(
438
+ /* @__PURE__ */ jsx8(
375
439
  "input",
376
440
  {
377
441
  value: days,
@@ -381,7 +445,7 @@ function TokensScreen({ client }) {
381
445
  "aria-label": "Days"
382
446
  }
383
447
  ),
384
- /* @__PURE__ */ jsx7(
448
+ /* @__PURE__ */ jsx8(
385
449
  "button",
386
450
  {
387
451
  type: "submit",
@@ -393,29 +457,29 @@ function TokensScreen({ client }) {
393
457
  ]
394
458
  }
395
459
  ),
396
- report?.issued && report.issued.length > 0 ? /* @__PURE__ */ jsxs7("table", { style: styles.table, children: [
397
- /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsxs7("tr", { children: [
398
- /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Name" }),
399
- /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Scopes" }),
400
- /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Created" }),
401
- /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Expires" }),
402
- /* @__PURE__ */ jsx7("th", { style: styles.th, children: "Last used" }),
403
- /* @__PURE__ */ jsx7("th", { style: styles.th })
460
+ report?.issued && report.issued.length > 0 ? /* @__PURE__ */ jsxs8("table", { style: styles.table, children: [
461
+ /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs8("tr", { children: [
462
+ /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Name" }),
463
+ /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Scopes" }),
464
+ /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Created" }),
465
+ /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Expires" }),
466
+ /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Last used" }),
467
+ /* @__PURE__ */ jsx8("th", { style: styles.th })
404
468
  ] }) }),
405
- /* @__PURE__ */ jsx7("tbody", { children: report.issued.map((t) => /* @__PURE__ */ jsxs7("tr", { children: [
406
- /* @__PURE__ */ jsxs7("td", { style: styles.td, children: [
469
+ /* @__PURE__ */ jsx8("tbody", { children: report.issued.map((t) => /* @__PURE__ */ jsxs8("tr", { children: [
470
+ /* @__PURE__ */ jsxs8("td", { style: styles.td, children: [
407
471
  t.name,
408
- t.revokedAt ? /* @__PURE__ */ jsx7("span", { style: styles.badge, children: " revoked" }) : null
472
+ t.revokedAt ? /* @__PURE__ */ jsx8("span", { style: styles.badge, children: " revoked" }) : null
409
473
  ] }),
410
- /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.mono }, children: t.scopes.join(", ") }),
411
- /* @__PURE__ */ jsxs7("td", { style: { ...styles.td, ...styles.muted }, children: [
474
+ /* @__PURE__ */ jsx8("td", { style: { ...styles.td, ...styles.mono }, children: t.scopes.join(", ") }),
475
+ /* @__PURE__ */ jsxs8("td", { style: { ...styles.td, ...styles.muted }, children: [
412
476
  new Date(t.createdAt).toLocaleDateString(),
413
477
  " \xB7 ",
414
478
  t.createdBy
415
479
  ] }),
416
- /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.muted }, children: t.expiresAt ? new Date(t.expiresAt).toLocaleDateString() : "never" }),
417
- /* @__PURE__ */ jsx7("td", { style: { ...styles.td, ...styles.muted }, children: t.lastUsedAt ? new Date(t.lastUsedAt).toLocaleString() : "never" }),
418
- /* @__PURE__ */ jsx7("td", { style: styles.td, children: t.revokedAt ? null : /* @__PURE__ */ jsx7(
480
+ /* @__PURE__ */ jsx8("td", { style: { ...styles.td, ...styles.muted }, children: t.expiresAt ? new Date(t.expiresAt).toLocaleDateString() : "never" }),
481
+ /* @__PURE__ */ jsx8("td", { style: { ...styles.td, ...styles.muted }, children: t.lastUsedAt ? new Date(t.lastUsedAt).toLocaleString() : "never" }),
482
+ /* @__PURE__ */ jsx8("td", { style: styles.td, children: t.revokedAt ? null : /* @__PURE__ */ jsx8(
419
483
  "button",
420
484
  {
421
485
  type: "button",
@@ -431,13 +495,13 @@ function TokensScreen({ client }) {
431
495
  }
432
496
  ) })
433
497
  ] }, t.id)) })
434
- ] }) : /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "None issued." })
498
+ ] }) : /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "None issued." })
435
499
  ] }),
436
- /* @__PURE__ */ jsx7("h2", { style: styles.subtitle, children: "Legacy per-brick tokens" }),
437
- report && report.legacy.length === 0 ? /* @__PURE__ */ jsx7("p", { style: styles.muted, children: "None \u2014 every brick's admin surface goes through this token." }) : /* @__PURE__ */ jsx7("ul", { style: styles.list, children: report?.legacy.map((l) => /* @__PURE__ */ jsxs7("li", { style: styles.row, children: [
438
- /* @__PURE__ */ jsx7("span", { style: styles.mono, children: l.module }),
500
+ /* @__PURE__ */ jsx8("h2", { style: styles.subtitle, children: "Legacy per-brick tokens" }),
501
+ report && report.legacy.length === 0 ? /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "None \u2014 every brick's admin surface goes through this token." }) : /* @__PURE__ */ jsx8("ul", { style: styles.list, children: report?.legacy.map((l) => /* @__PURE__ */ jsxs8("li", { style: styles.row, children: [
502
+ /* @__PURE__ */ jsx8("span", { style: styles.mono, children: l.module }),
439
503
  " ",
440
- /* @__PURE__ */ jsx7("span", { style: styles.muted, children: "still registers its standalone routes with its own token (deprecated)" })
504
+ /* @__PURE__ */ jsx8("span", { style: styles.muted, children: "still registers its standalone routes with its own token (deprecated)" })
441
505
  ] }, l.module)) })
442
506
  ] });
443
507
  }
@@ -450,7 +514,7 @@ import {
450
514
  useAdminUsers
451
515
  } from "@fonderie/react-admin";
452
516
  import { useState as useState2 } from "react";
453
- import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
517
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
454
518
  function UsersScreen({ client, pageSize = 50 }) {
455
519
  const [input, setInput] = useState2("");
456
520
  const [selected, setSelected] = useState2(null);
@@ -462,14 +526,14 @@ function UsersScreen({ client, pageSize = 50 }) {
462
526
  const userId = user?.id ?? null;
463
527
  const sessions = useAdminUserSessions(client, userId);
464
528
  const history = useAdminLoginHistory(client, userId, { limit: 20 });
465
- const yesNo = (v) => v ? /* @__PURE__ */ jsx8("span", { style: styles.ok, children: "yes" }) : /* @__PURE__ */ jsx8("span", { style: styles.muted, children: "no" });
529
+ const yesNo = (v) => v ? /* @__PURE__ */ jsx9("span", { style: styles.ok, children: "yes" }) : /* @__PURE__ */ jsx9("span", { style: styles.muted, children: "no" });
466
530
  const clear = () => {
467
531
  setSelected(null);
468
532
  setInput("");
469
533
  };
470
- return /* @__PURE__ */ jsxs8("div", { style: styles.container, children: [
471
- /* @__PURE__ */ jsx8("h1", { style: styles.title, children: "Users" }),
472
- /* @__PURE__ */ jsxs8(
534
+ return /* @__PURE__ */ jsxs9("div", { style: styles.container, children: [
535
+ /* @__PURE__ */ jsx9("h1", { style: styles.title, children: "Users" }),
536
+ /* @__PURE__ */ jsxs9(
473
537
  "form",
474
538
  {
475
539
  style: styles.toolbar,
@@ -479,7 +543,7 @@ function UsersScreen({ client, pageSize = 50 }) {
479
543
  setSelected(email ? { email } : null);
480
544
  },
481
545
  children: [
482
- /* @__PURE__ */ jsx8(
546
+ /* @__PURE__ */ jsx9(
483
547
  "input",
484
548
  {
485
549
  type: "email",
@@ -490,8 +554,8 @@ function UsersScreen({ client, pageSize = 50 }) {
490
554
  "aria-label": "Email"
491
555
  }
492
556
  ),
493
- /* @__PURE__ */ jsx8("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Look up" }),
494
- selected ? /* @__PURE__ */ jsx8("button", { type: "button", style: styles.button, onClick: clear, children: "\u2190 All users" }) : /* @__PURE__ */ jsx8(
557
+ /* @__PURE__ */ jsx9("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Look up" }),
558
+ selected ? /* @__PURE__ */ jsx9("button", { type: "button", style: styles.button, onClick: clear, children: "\u2190 All users" }) : /* @__PURE__ */ jsx9(
495
559
  "button",
496
560
  {
497
561
  type: "button",
@@ -504,18 +568,18 @@ function UsersScreen({ client, pageSize = 50 }) {
504
568
  ]
505
569
  }
506
570
  ),
507
- error ? /* @__PURE__ */ jsx8("p", { style: styles.error, role: "alert", children: error.status === 404 ? "No user with that email." : error.explanation }) : null,
508
- !selected ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
509
- list.error ? /* @__PURE__ */ jsx8("p", { style: styles.error, role: "alert", children: list.error.explanation }) : null,
510
- list.users.length === 0 && !list.isLoading ? /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "No users yet." }) : /* @__PURE__ */ jsxs8("table", { style: styles.table, children: [
511
- /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs8("tr", { children: [
512
- /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Email" }),
513
- /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Name" }),
514
- /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Created" }),
515
- /* @__PURE__ */ jsx8("th", { style: styles.th, children: "Status" })
571
+ error ? /* @__PURE__ */ jsx9("p", { style: styles.error, role: "alert", children: error.status === 404 ? "No user with that email." : error.explanation }) : null,
572
+ !selected ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
573
+ list.error ? /* @__PURE__ */ jsx9("p", { style: styles.error, role: "alert", children: list.error.explanation }) : null,
574
+ list.users.length === 0 && !list.isLoading ? /* @__PURE__ */ jsx9("p", { style: styles.muted, children: "No users yet." }) : /* @__PURE__ */ jsxs9("table", { style: styles.table, children: [
575
+ /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { children: [
576
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Email" }),
577
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Name" }),
578
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Created" }),
579
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Status" })
516
580
  ] }) }),
517
- /* @__PURE__ */ jsx8("tbody", { children: list.users.map((u) => /* @__PURE__ */ jsxs8("tr", { children: [
518
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: /* @__PURE__ */ jsx8(
581
+ /* @__PURE__ */ jsx9("tbody", { children: list.users.map((u) => /* @__PURE__ */ jsxs9("tr", { children: [
582
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: /* @__PURE__ */ jsx9(
519
583
  "button",
520
584
  {
521
585
  type: "button",
@@ -524,17 +588,17 @@ function UsersScreen({ client, pageSize = 50 }) {
524
588
  children: u.email
525
589
  }
526
590
  ) }),
527
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: `${u.firstName ?? ""} ${u.lastName ?? ""}`.trim() || /* @__PURE__ */ jsx8("span", { style: styles.muted, children: "\u2014" }) }),
528
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: new Date(u.createdAt).toLocaleDateString() }),
529
- /* @__PURE__ */ jsxs8("td", { style: styles.td, children: [
530
- u.suspended ? /* @__PURE__ */ jsx8("span", { style: styles.badge, children: "suspended" }) : null,
531
- u.deletedAt ? /* @__PURE__ */ jsx8("span", { style: styles.badge, children: "deleted" }) : null,
532
- !u.suspended && !u.deletedAt ? /* @__PURE__ */ jsx8("span", { style: styles.muted, children: "active" }) : null
591
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: `${u.firstName ?? ""} ${u.lastName ?? ""}`.trim() || /* @__PURE__ */ jsx9("span", { style: styles.muted, children: "\u2014" }) }),
592
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: new Date(u.createdAt).toLocaleDateString() }),
593
+ /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
594
+ u.suspended ? /* @__PURE__ */ jsx9("span", { style: styles.badge, children: "suspended" }) : null,
595
+ u.deletedAt ? /* @__PURE__ */ jsx9("span", { style: styles.badge, children: "deleted" }) : null,
596
+ !u.suspended && !u.deletedAt ? /* @__PURE__ */ jsx9("span", { style: styles.muted, children: "active" }) : null
533
597
  ] })
534
598
  ] }, u.id)) })
535
599
  ] }),
536
- list.isLoading ? /* @__PURE__ */ jsx8("p", { style: styles.status, children: "Loading\u2026" }) : null,
537
- list.hasMore && !list.isLoading ? /* @__PURE__ */ jsx8(
600
+ list.isLoading ? /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Loading\u2026" }) : null,
601
+ list.hasMore && !list.isLoading ? /* @__PURE__ */ jsx9(
538
602
  "button",
539
603
  {
540
604
  type: "button",
@@ -544,48 +608,48 @@ function UsersScreen({ client, pageSize = 50 }) {
544
608
  }
545
609
  ) : null
546
610
  ] }) : null,
547
- user ? /* @__PURE__ */ jsxs8(Fragment5, { children: [
548
- /* @__PURE__ */ jsxs8("h2", { style: styles.subtitle, children: [
611
+ user ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
612
+ /* @__PURE__ */ jsxs9("h2", { style: styles.subtitle, children: [
549
613
  user.firstName || user.lastName ? `${user.firstName} ${user.lastName}`.trim() : user.email,
550
614
  " ",
551
- user.suspended ? /* @__PURE__ */ jsx8("span", { style: styles.badge, children: "suspended" }) : null,
552
- user.deletedAt ? /* @__PURE__ */ jsx8("span", { style: styles.badge, children: "deleted" }) : null
615
+ user.suspended ? /* @__PURE__ */ jsx9("span", { style: styles.badge, children: "suspended" }) : null,
616
+ user.deletedAt ? /* @__PURE__ */ jsx9("span", { style: styles.badge, children: "deleted" }) : null
553
617
  ] }),
554
- /* @__PURE__ */ jsx8("table", { style: styles.table, children: /* @__PURE__ */ jsxs8("tbody", { children: [
555
- /* @__PURE__ */ jsxs8("tr", { children: [
556
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "id" }),
557
- /* @__PURE__ */ jsx8("td", { style: { ...styles.td, ...styles.mono }, children: user.id })
618
+ /* @__PURE__ */ jsx9("table", { style: styles.table, children: /* @__PURE__ */ jsxs9("tbody", { children: [
619
+ /* @__PURE__ */ jsxs9("tr", { children: [
620
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "id" }),
621
+ /* @__PURE__ */ jsx9("td", { style: { ...styles.td, ...styles.mono }, children: user.id })
558
622
  ] }),
559
- /* @__PURE__ */ jsxs8("tr", { children: [
560
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "email" }),
561
- /* @__PURE__ */ jsxs8("td", { style: styles.td, children: [
623
+ /* @__PURE__ */ jsxs9("tr", { children: [
624
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "email" }),
625
+ /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
562
626
  user.email,
563
627
  " \xB7 verified ",
564
628
  yesNo(user.isEmailVerified)
565
629
  ] })
566
630
  ] }),
567
- /* @__PURE__ */ jsxs8("tr", { children: [
568
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "MFA" }),
569
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: yesNo(user.mfaEnabled) })
631
+ /* @__PURE__ */ jsxs9("tr", { children: [
632
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "MFA" }),
633
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: yesNo(user.mfaEnabled) })
570
634
  ] }),
571
- /* @__PURE__ */ jsxs8("tr", { children: [
572
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "provider" }),
573
- /* @__PURE__ */ jsxs8("td", { style: styles.td, children: [
635
+ /* @__PURE__ */ jsxs9("tr", { children: [
636
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "provider" }),
637
+ /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
574
638
  user.provider || "password",
575
639
  user.hasPassword ? "" : " \xB7 no password set"
576
640
  ] })
577
641
  ] }),
578
- /* @__PURE__ */ jsxs8("tr", { children: [
579
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "last login" }),
580
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: user.lastLogin ? new Date(user.lastLogin).toLocaleString() : /* @__PURE__ */ jsx8("span", { style: styles.muted, children: "never" }) })
642
+ /* @__PURE__ */ jsxs9("tr", { children: [
643
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "last login" }),
644
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: user.lastLogin ? new Date(user.lastLogin).toLocaleString() : /* @__PURE__ */ jsx9("span", { style: styles.muted, children: "never" }) })
581
645
  ] }),
582
- /* @__PURE__ */ jsxs8("tr", { children: [
583
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: "created" }),
584
- /* @__PURE__ */ jsx8("td", { style: styles.td, children: new Date(user.createdAt).toLocaleString() })
646
+ /* @__PURE__ */ jsxs9("tr", { children: [
647
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: "created" }),
648
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: new Date(user.createdAt).toLocaleString() })
585
649
  ] })
586
650
  ] }) }),
587
- /* @__PURE__ */ jsxs8("div", { style: { ...styles.toolbar, marginTop: 12 }, children: [
588
- user.suspended ? /* @__PURE__ */ jsx8(
651
+ /* @__PURE__ */ jsxs9("div", { style: { ...styles.toolbar, marginTop: 12 }, children: [
652
+ user.suspended ? /* @__PURE__ */ jsx9(
589
653
  "button",
590
654
  {
591
655
  type: "button",
@@ -594,7 +658,7 @@ function UsersScreen({ client, pageSize = 50 }) {
594
658
  disabled: isLoading,
595
659
  children: "Unsuspend"
596
660
  }
597
- ) : /* @__PURE__ */ jsx8(
661
+ ) : /* @__PURE__ */ jsx9(
598
662
  "button",
599
663
  {
600
664
  type: "button",
@@ -604,7 +668,7 @@ function UsersScreen({ client, pageSize = 50 }) {
604
668
  children: "Suspend"
605
669
  }
606
670
  ),
607
- /* @__PURE__ */ jsx8(
671
+ /* @__PURE__ */ jsx9(
608
672
  "button",
609
673
  {
610
674
  type: "button",
@@ -615,26 +679,26 @@ function UsersScreen({ client, pageSize = 50 }) {
615
679
  }
616
680
  )
617
681
  ] }),
618
- /* @__PURE__ */ jsx8("h2", { style: styles.subtitle, children: "Live sessions" }),
619
- sessions.sessions.length === 0 ? /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "None." }) : /* @__PURE__ */ jsx8("ul", { style: styles.list, children: sessions.sessions.map((s) => /* @__PURE__ */ jsxs8("li", { style: styles.row, children: [
620
- /* @__PURE__ */ jsx8("span", { style: styles.mono, children: s.ipAddress ?? "\u2014" }),
682
+ /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Live sessions" }),
683
+ sessions.sessions.length === 0 ? /* @__PURE__ */ jsx9("p", { style: styles.muted, children: "None." }) : /* @__PURE__ */ jsx9("ul", { style: styles.list, children: sessions.sessions.map((s) => /* @__PURE__ */ jsxs9("li", { style: styles.row, children: [
684
+ /* @__PURE__ */ jsx9("span", { style: styles.mono, children: s.ipAddress ?? "\u2014" }),
621
685
  " ",
622
- /* @__PURE__ */ jsx8("span", { style: styles.muted, children: s.userAgent ?? "" }),
686
+ /* @__PURE__ */ jsx9("span", { style: styles.muted, children: s.userAgent ?? "" }),
623
687
  " ",
624
- /* @__PURE__ */ jsxs8("span", { style: styles.muted, children: [
688
+ /* @__PURE__ */ jsxs9("span", { style: styles.muted, children: [
625
689
  "since ",
626
690
  new Date(s.createdAt).toLocaleString()
627
691
  ] })
628
692
  ] }, s.id)) }),
629
- /* @__PURE__ */ jsx8("h2", { style: styles.subtitle, children: "Recent sign-ins" }),
630
- history.events.length === 0 && !history.isLoading ? /* @__PURE__ */ jsx8("p", { style: styles.muted, children: "None recorded." }) : /* @__PURE__ */ jsx8("ul", { style: styles.list, children: history.events.map((e) => /* @__PURE__ */ jsxs8("li", { style: styles.row, children: [
631
- /* @__PURE__ */ jsx8("span", { style: e.outcome === "success" ? styles.ok : styles.bad, children: e.outcome }),
693
+ /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Recent sign-ins" }),
694
+ history.events.length === 0 && !history.isLoading ? /* @__PURE__ */ jsx9("p", { style: styles.muted, children: "None recorded." }) : /* @__PURE__ */ jsx9("ul", { style: styles.list, children: history.events.map((e) => /* @__PURE__ */ jsxs9("li", { style: styles.row, children: [
695
+ /* @__PURE__ */ jsx9("span", { style: e.outcome === "success" ? styles.ok : styles.bad, children: e.outcome }),
632
696
  " ",
633
- /* @__PURE__ */ jsx8("span", { style: styles.muted, children: e.method }),
697
+ /* @__PURE__ */ jsx9("span", { style: styles.muted, children: e.method }),
634
698
  " ",
635
- /* @__PURE__ */ jsx8("span", { style: styles.muted, children: new Date(e.createdAt).toLocaleString() })
699
+ /* @__PURE__ */ jsx9("span", { style: styles.muted, children: new Date(e.createdAt).toLocaleString() })
636
700
  ] }, e.id)) }),
637
- history.hasMore && !history.isLoading ? /* @__PURE__ */ jsx8(
701
+ history.hasMore && !history.isLoading ? /* @__PURE__ */ jsx9(
638
702
  "button",
639
703
  {
640
704
  type: "button",
@@ -649,14 +713,14 @@ function UsersScreen({ client, pageSize = 50 }) {
649
713
 
650
714
  // src/screens/CatalogScreen.tsx
651
715
  import { useAdminCatalog } from "@fonderie/react-admin";
652
- import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
716
+ import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
653
717
  function CatalogScreen({ client }) {
654
718
  const { catalog, isLoading, error, refresh, deletePlan } = useAdminCatalog(client);
655
719
  const money = (v) => v == null ? "\u2014" : (v / 100).toFixed(2);
656
- return /* @__PURE__ */ jsxs9("div", { style: styles.container, children: [
657
- /* @__PURE__ */ jsxs9("div", { style: styles.toolbar, children: [
658
- /* @__PURE__ */ jsx9("h1", { style: { ...styles.title, marginBottom: 0 }, children: "Catalog" }),
659
- /* @__PURE__ */ jsx9(
720
+ return /* @__PURE__ */ jsxs10("div", { style: styles.container, children: [
721
+ /* @__PURE__ */ jsxs10("div", { style: styles.toolbar, children: [
722
+ /* @__PURE__ */ jsx10("h1", { style: { ...styles.title, marginBottom: 0 }, children: "Catalog" }),
723
+ /* @__PURE__ */ jsx10(
660
724
  "button",
661
725
  {
662
726
  type: "button",
@@ -667,37 +731,37 @@ function CatalogScreen({ client }) {
667
731
  }
668
732
  )
669
733
  ] }),
670
- error ? /* @__PURE__ */ jsx9("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
671
- isLoading && !catalog ? /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Loading\u2026" }) : null,
672
- catalog ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
673
- /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Configured (code)" }),
674
- /* @__PURE__ */ jsx9("pre", { style: { ...styles.mono, background: "#f9fafb", padding: 12, overflowX: "auto" }, children: JSON.stringify(catalog.configured, null, 2) }),
675
- /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Stored (database)" }),
676
- catalog.stored.length === 0 ? /* @__PURE__ */ jsx9("p", { style: styles.muted, children: "No stored plans." }) : /* @__PURE__ */ jsxs9("table", { style: styles.table, children: [
677
- /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { children: [
678
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Plan" }),
679
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Tier" }),
680
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Seats" }),
681
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Monthly" }),
682
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Yearly" }),
683
- /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Trial" }),
684
- /* @__PURE__ */ jsx9("th", { style: styles.th })
734
+ error ? /* @__PURE__ */ jsx10("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
735
+ isLoading && !catalog ? /* @__PURE__ */ jsx10("p", { style: styles.status, children: "Loading\u2026" }) : null,
736
+ catalog ? /* @__PURE__ */ jsxs10(Fragment6, { children: [
737
+ /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Configured (code)" }),
738
+ /* @__PURE__ */ jsx10("pre", { style: { ...styles.mono, background: "#f9fafb", padding: 12, overflowX: "auto" }, children: JSON.stringify(catalog.configured, null, 2) }),
739
+ /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Stored (database)" }),
740
+ catalog.stored.length === 0 ? /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No stored plans." }) : /* @__PURE__ */ jsxs10("table", { style: styles.table, children: [
741
+ /* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
742
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Plan" }),
743
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Tier" }),
744
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Seats" }),
745
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Monthly" }),
746
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Yearly" }),
747
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Trial" }),
748
+ /* @__PURE__ */ jsx10("th", { style: styles.th })
685
749
  ] }) }),
686
- /* @__PURE__ */ jsx9("tbody", { children: catalog.stored.map((p) => /* @__PURE__ */ jsxs9("tr", { children: [
687
- /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
688
- /* @__PURE__ */ jsx9("strong", { children: p.name }),
689
- p.description ? /* @__PURE__ */ jsx9("div", { style: styles.muted, children: p.description }) : null
750
+ /* @__PURE__ */ jsx10("tbody", { children: catalog.stored.map((p) => /* @__PURE__ */ jsxs10("tr", { children: [
751
+ /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
752
+ /* @__PURE__ */ jsx10("strong", { children: p.name }),
753
+ p.description ? /* @__PURE__ */ jsx10("div", { style: styles.muted, children: p.description }) : null
690
754
  ] }),
691
- /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.tier }),
692
- /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.seats ?? "\u221E" }),
693
- /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
755
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: p.tier }),
756
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: p.seats ?? "\u221E" }),
757
+ /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
694
758
  money(p.pricing?.monthly),
695
759
  " ",
696
760
  p.pricing?.currency ?? ""
697
761
  ] }),
698
- /* @__PURE__ */ jsx9("td", { style: styles.td, children: money(p.pricing?.yearly) }),
699
- /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.trialDays ? `${p.trialDays} d` : "\u2014" }),
700
- /* @__PURE__ */ jsx9("td", { style: styles.td, children: /* @__PURE__ */ jsx9(
762
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: money(p.pricing?.yearly) }),
763
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: p.trialDays ? `${p.trialDays} d` : "\u2014" }),
764
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: /* @__PURE__ */ jsx10(
701
765
  "button",
702
766
  {
703
767
  type: "button",
@@ -719,7 +783,7 @@ function CatalogScreen({ client }) {
719
783
  // src/screens/SubscriberScreen.tsx
720
784
  import { useAdminSubscriber, useAdminSubscribers } from "@fonderie/react-admin";
721
785
  import { useState as useState3 } from "react";
722
- import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
786
+ import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
723
787
  function SubscriberScreen({ client, pageSize = 50 }) {
724
788
  const [type, setType] = useState3("user");
725
789
  const [idInput, setIdInput] = useState3("");
@@ -735,9 +799,9 @@ function SubscriberScreen({ client, pageSize = 50 }) {
735
799
  setIdInput(id);
736
800
  setSubscriber({ type: t, id });
737
801
  };
738
- return /* @__PURE__ */ jsxs10("div", { style: styles.container, children: [
739
- /* @__PURE__ */ jsx10("h1", { style: styles.title, children: "Subscriber" }),
740
- /* @__PURE__ */ jsxs10(
802
+ return /* @__PURE__ */ jsxs11("div", { style: styles.container, children: [
803
+ /* @__PURE__ */ jsx11("h1", { style: styles.title, children: "Subscriber" }),
804
+ /* @__PURE__ */ jsxs11(
741
805
  "form",
742
806
  {
743
807
  style: styles.toolbar,
@@ -747,7 +811,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
747
811
  setSubscriber(idInput.trim() ? { type, id: idInput.trim() } : null);
748
812
  },
749
813
  children: [
750
- /* @__PURE__ */ jsxs10(
814
+ /* @__PURE__ */ jsxs11(
751
815
  "select",
752
816
  {
753
817
  value: type,
@@ -755,12 +819,12 @@ function SubscriberScreen({ client, pageSize = 50 }) {
755
819
  style: styles.button,
756
820
  "aria-label": "Type",
757
821
  children: [
758
- /* @__PURE__ */ jsx10("option", { value: "user", children: "user" }),
759
- /* @__PURE__ */ jsx10("option", { value: "workspace", children: "workspace" })
822
+ /* @__PURE__ */ jsx11("option", { value: "user", children: "user" }),
823
+ /* @__PURE__ */ jsx11("option", { value: "workspace", children: "workspace" })
760
824
  ]
761
825
  }
762
826
  ),
763
- /* @__PURE__ */ jsx10(
827
+ /* @__PURE__ */ jsx11(
764
828
  "input",
765
829
  {
766
830
  value: idInput,
@@ -770,8 +834,8 @@ function SubscriberScreen({ client, pageSize = 50 }) {
770
834
  "aria-label": "Subscriber id"
771
835
  }
772
836
  ),
773
- /* @__PURE__ */ jsx10("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Look up" }),
774
- subscriber ? /* @__PURE__ */ jsx10(
837
+ /* @__PURE__ */ jsx11("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Look up" }),
838
+ subscriber ? /* @__PURE__ */ jsx11(
775
839
  "button",
776
840
  {
777
841
  type: "button",
@@ -783,7 +847,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
783
847
  },
784
848
  children: "\u2190 All subscribers"
785
849
  }
786
- ) : /* @__PURE__ */ jsx10(
850
+ ) : /* @__PURE__ */ jsx11(
787
851
  "button",
788
852
  {
789
853
  type: "button",
@@ -796,18 +860,18 @@ function SubscriberScreen({ client, pageSize = 50 }) {
796
860
  ]
797
861
  }
798
862
  ),
799
- error ? /* @__PURE__ */ jsx10("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
800
- !subscriber ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
801
- list.error ? /* @__PURE__ */ jsx10("p", { style: styles.error, role: "alert", children: list.error.explanation }) : null,
802
- list.subscriptions.length === 0 && !list.isLoading ? /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No subscribers yet." }) : /* @__PURE__ */ jsxs10("table", { style: styles.table, children: [
803
- /* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
804
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Subscriber" }),
805
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Plan" }),
806
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Status" }),
807
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Renews" })
863
+ error ? /* @__PURE__ */ jsx11("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
864
+ !subscriber ? /* @__PURE__ */ jsxs11(Fragment7, { children: [
865
+ list.error ? /* @__PURE__ */ jsx11("p", { style: styles.error, role: "alert", children: list.error.explanation }) : null,
866
+ list.subscriptions.length === 0 && !list.isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "No subscribers yet." }) : /* @__PURE__ */ jsxs11("table", { style: styles.table, children: [
867
+ /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
868
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Subscriber" }),
869
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Plan" }),
870
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Status" }),
871
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Renews" })
808
872
  ] }) }),
809
- /* @__PURE__ */ jsx10("tbody", { children: list.subscriptions.map((s) => /* @__PURE__ */ jsxs10("tr", { children: [
810
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: /* @__PURE__ */ jsxs10(
873
+ /* @__PURE__ */ jsx11("tbody", { children: list.subscriptions.map((s) => /* @__PURE__ */ jsxs11("tr", { children: [
874
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: /* @__PURE__ */ jsxs11(
811
875
  "button",
812
876
  {
813
877
  type: "button",
@@ -820,20 +884,20 @@ function SubscriberScreen({ client, pageSize = 50 }) {
820
884
  ]
821
885
  }
822
886
  ) }),
823
- /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
824
- /* @__PURE__ */ jsx10("strong", { children: s.plan }),
887
+ /* @__PURE__ */ jsxs11("td", { style: styles.td, children: [
888
+ /* @__PURE__ */ jsx11("strong", { children: s.plan }),
825
889
  " \xB7 ",
826
890
  s.interval
827
891
  ] }),
828
- /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
892
+ /* @__PURE__ */ jsxs11("td", { style: styles.td, children: [
829
893
  s.status,
830
- s.cancelAtPeriodEnd ? /* @__PURE__ */ jsx10("span", { style: styles.badge, children: "cancels" }) : null
894
+ s.cancelAtPeriodEnd ? /* @__PURE__ */ jsx11("span", { style: styles.badge, children: "cancels" }) : null
831
895
  ] }),
832
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: s.currentPeriodEnd ? new Date(s.currentPeriodEnd).toLocaleDateString() : /* @__PURE__ */ jsx10("span", { style: styles.muted, children: "\u2014" }) })
896
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: s.currentPeriodEnd ? new Date(s.currentPeriodEnd).toLocaleDateString() : /* @__PURE__ */ jsx11("span", { style: styles.muted, children: "\u2014" }) })
833
897
  ] }, s.id)) })
834
898
  ] }),
835
- list.isLoading ? /* @__PURE__ */ jsx10("p", { style: styles.status, children: "Loading\u2026" }) : null,
836
- list.hasMore && !list.isLoading ? /* @__PURE__ */ jsx10(
899
+ list.isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.status, children: "Loading\u2026" }) : null,
900
+ list.hasMore && !list.isLoading ? /* @__PURE__ */ jsx11(
837
901
  "button",
838
902
  {
839
903
  type: "button",
@@ -843,27 +907,27 @@ function SubscriberScreen({ client, pageSize = 50 }) {
843
907
  }
844
908
  ) : null
845
909
  ] }) : null,
846
- subscriber && !isLoading ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
847
- /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Subscription" }),
848
- subscription ? /* @__PURE__ */ jsx10("table", { style: styles.table, children: /* @__PURE__ */ jsxs10("tbody", { children: [
849
- /* @__PURE__ */ jsxs10("tr", { children: [
850
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: "plan" }),
851
- /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
852
- /* @__PURE__ */ jsx10("strong", { children: subscription.plan }),
910
+ subscriber && !isLoading ? /* @__PURE__ */ jsxs11(Fragment7, { children: [
911
+ /* @__PURE__ */ jsx11("h2", { style: styles.subtitle, children: "Subscription" }),
912
+ subscription ? /* @__PURE__ */ jsx11("table", { style: styles.table, children: /* @__PURE__ */ jsxs11("tbody", { children: [
913
+ /* @__PURE__ */ jsxs11("tr", { children: [
914
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: "plan" }),
915
+ /* @__PURE__ */ jsxs11("td", { style: styles.td, children: [
916
+ /* @__PURE__ */ jsx11("strong", { children: subscription.plan }),
853
917
  " \xB7 ",
854
918
  subscription.interval
855
919
  ] })
856
920
  ] }),
857
- /* @__PURE__ */ jsxs10("tr", { children: [
858
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: "status" }),
859
- /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
921
+ /* @__PURE__ */ jsxs11("tr", { children: [
922
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: "status" }),
923
+ /* @__PURE__ */ jsxs11("td", { style: styles.td, children: [
860
924
  subscription.status,
861
925
  subscription.cancelAtPeriodEnd ? " \xB7 cancels at period end" : ""
862
926
  ] })
863
927
  ] }),
864
- /* @__PURE__ */ jsxs10("tr", { children: [
865
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: "period" }),
866
- /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
928
+ /* @__PURE__ */ jsxs11("tr", { children: [
929
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: "period" }),
930
+ /* @__PURE__ */ jsxs11("td", { style: styles.td, children: [
867
931
  subscription.currentPeriodStart ? new Date(subscription.currentPeriodStart).toLocaleDateString() : "\u2014",
868
932
  " ",
869
933
  "\u2192",
@@ -871,19 +935,19 @@ function SubscriberScreen({ client, pageSize = 50 }) {
871
935
  subscription.currentPeriodEnd ? new Date(subscription.currentPeriodEnd).toLocaleDateString() : "\u2014"
872
936
  ] })
873
937
  ] }),
874
- /* @__PURE__ */ jsxs10("tr", { children: [
875
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: "provider" }),
876
- /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.mono }, children: subscription.providerSubscriptionId ?? "\u2014" })
938
+ /* @__PURE__ */ jsxs11("tr", { children: [
939
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: "provider" }),
940
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: subscription.providerSubscriptionId ?? "\u2014" })
877
941
  ] })
878
- ] }) }) : /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No subscription." }),
879
- /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Wallet" }),
880
- wallet ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
881
- /* @__PURE__ */ jsxs10("p", { children: [
882
- /* @__PURE__ */ jsx10("strong", { children: wallet.balance }),
942
+ ] }) }) : /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "No subscription." }),
943
+ /* @__PURE__ */ jsx11("h2", { style: styles.subtitle, children: "Wallet" }),
944
+ wallet ? /* @__PURE__ */ jsxs11(Fragment7, { children: [
945
+ /* @__PURE__ */ jsxs11("p", { children: [
946
+ /* @__PURE__ */ jsx11("strong", { children: wallet.balance }),
883
947
  " ",
884
948
  wallet.currency,
885
949
  " ",
886
- /* @__PURE__ */ jsxs10("span", { style: styles.muted, children: [
950
+ /* @__PURE__ */ jsxs11("span", { style: styles.muted, children: [
887
951
  "(granted ",
888
952
  wallet.granted ?? "0",
889
953
  " \xB7 purchased ",
@@ -892,7 +956,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
892
956
  wallet.precision
893
957
  ] })
894
958
  ] }),
895
- /* @__PURE__ */ jsxs10(
959
+ /* @__PURE__ */ jsxs11(
896
960
  "form",
897
961
  {
898
962
  style: styles.toolbar,
@@ -911,7 +975,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
911
975
  });
912
976
  },
913
977
  children: [
914
- /* @__PURE__ */ jsx10(
978
+ /* @__PURE__ */ jsx11(
915
979
  "input",
916
980
  {
917
981
  value: amount,
@@ -921,7 +985,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
921
985
  "aria-label": "Amount"
922
986
  }
923
987
  ),
924
- /* @__PURE__ */ jsx10(
988
+ /* @__PURE__ */ jsx11(
925
989
  "input",
926
990
  {
927
991
  value: note,
@@ -931,27 +995,27 @@ function SubscriberScreen({ client, pageSize = 50 }) {
931
995
  "aria-label": "Reason"
932
996
  }
933
997
  ),
934
- /* @__PURE__ */ jsx10("button", { type: "submit", style: styles.button, disabled: !/^\d+$/.test(amount.trim()), children: "Grant" }),
935
- granted ? /* @__PURE__ */ jsx10("span", { style: styles.ok, children: granted }) : null
998
+ /* @__PURE__ */ jsx11("button", { type: "submit", style: styles.button, disabled: !/^\d+$/.test(amount.trim()), children: "Grant" }),
999
+ granted ? /* @__PURE__ */ jsx11("span", { style: styles.ok, children: granted }) : null
936
1000
  ]
937
1001
  }
938
1002
  ),
939
- /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Ledger" }),
940
- ledger.length === 0 ? /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "Nothing moved yet." }) : /* @__PURE__ */ jsxs10("table", { style: styles.table, children: [
941
- /* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
942
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "When" }),
943
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Kind" }),
944
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Amount" }),
945
- /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Note" })
1003
+ /* @__PURE__ */ jsx11("h2", { style: styles.subtitle, children: "Ledger" }),
1004
+ ledger.length === 0 ? /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "Nothing moved yet." }) : /* @__PURE__ */ jsxs11("table", { style: styles.table, children: [
1005
+ /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
1006
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "When" }),
1007
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Kind" }),
1008
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Amount" }),
1009
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Note" })
946
1010
  ] }) }),
947
- /* @__PURE__ */ jsx10("tbody", { children: ledger.map((t) => /* @__PURE__ */ jsxs10("tr", { children: [
948
- /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.muted }, children: new Date(t.createdAt).toLocaleString() }),
949
- /* @__PURE__ */ jsx10("td", { style: styles.td, children: t.type }),
950
- /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.mono }, children: t.amount }),
951
- /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.muted }, children: t.description ?? "" })
1011
+ /* @__PURE__ */ jsx11("tbody", { children: ledger.map((t) => /* @__PURE__ */ jsxs11("tr", { children: [
1012
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: new Date(t.createdAt).toLocaleString() }),
1013
+ /* @__PURE__ */ jsx11("td", { style: styles.td, children: t.type }),
1014
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: t.amount }),
1015
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: t.description ?? "" })
952
1016
  ] }, t.id)) })
953
1017
  ] }),
954
- hasMoreLedger ? /* @__PURE__ */ jsx10(
1018
+ hasMoreLedger ? /* @__PURE__ */ jsx11(
955
1019
  "button",
956
1020
  {
957
1021
  type: "button",
@@ -960,7 +1024,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
960
1024
  children: "Load more"
961
1025
  }
962
1026
  ) : null
963
- ] }) : /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No wallet \u2014 billing has no wallet configuration." })
1027
+ ] }) : /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "No wallet \u2014 billing has no wallet configuration." })
964
1028
  ] }) : null
965
1029
  ] });
966
1030
  }
@@ -968,7 +1032,7 @@ function SubscriberScreen({ client, pageSize = 50 }) {
968
1032
  // src/screens/AuditScreen.tsx
969
1033
  import { useAdminAudit } from "@fonderie/react-admin";
970
1034
  import { useState as useState4 } from "react";
971
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1035
+ import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
972
1036
  function AuditScreen({ client, pageSize = 50 }) {
973
1037
  const [draft, setDraft] = useState4({ workspaceId: "", type: "", actorId: "" });
974
1038
  const [filter, setFilter] = useState4(
@@ -978,7 +1042,7 @@ function AuditScreen({ client, pageSize = 50 }) {
978
1042
  ...filter,
979
1043
  limit: pageSize
980
1044
  });
981
- const field = (key, placeholder) => /* @__PURE__ */ jsx11(
1045
+ const field = (key, placeholder) => /* @__PURE__ */ jsx12(
982
1046
  "input",
983
1047
  {
984
1048
  value: draft[key],
@@ -988,9 +1052,9 @@ function AuditScreen({ client, pageSize = 50 }) {
988
1052
  "aria-label": placeholder
989
1053
  }
990
1054
  );
991
- return /* @__PURE__ */ jsxs11("div", { style: styles.container, children: [
992
- /* @__PURE__ */ jsx11("h1", { style: styles.title, children: "Audit" }),
993
- /* @__PURE__ */ jsxs11(
1055
+ return /* @__PURE__ */ jsxs12("div", { style: styles.container, children: [
1056
+ /* @__PURE__ */ jsx12("h1", { style: styles.title, children: "Audit" }),
1057
+ /* @__PURE__ */ jsxs12(
994
1058
  "form",
995
1059
  {
996
1060
  style: styles.toolbar,
@@ -1006,8 +1070,8 @@ function AuditScreen({ client, pageSize = 50 }) {
1006
1070
  field("workspaceId", "workspace id (all if empty)"),
1007
1071
  field("type", "event type"),
1008
1072
  field("actorId", "actor id"),
1009
- /* @__PURE__ */ jsx11("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Filter" }),
1010
- /* @__PURE__ */ jsx11(
1073
+ /* @__PURE__ */ jsx12("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Filter" }),
1074
+ /* @__PURE__ */ jsx12(
1011
1075
  "button",
1012
1076
  {
1013
1077
  type: "button",
@@ -1020,25 +1084,25 @@ function AuditScreen({ client, pageSize = 50 }) {
1020
1084
  ]
1021
1085
  }
1022
1086
  ),
1023
- error ? /* @__PURE__ */ jsx11("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
1024
- events.length === 0 && !isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "Nothing recorded for this filter." }) : /* @__PURE__ */ jsxs11("table", { style: styles.table, children: [
1025
- /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
1026
- /* @__PURE__ */ jsx11("th", { style: styles.th, children: "When" }),
1027
- /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Type" }),
1028
- /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Workspace" }),
1029
- /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Actor" }),
1030
- /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Request" })
1087
+ error ? /* @__PURE__ */ jsx12("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
1088
+ events.length === 0 && !isLoading ? /* @__PURE__ */ jsx12("p", { style: styles.muted, children: "Nothing recorded for this filter." }) : /* @__PURE__ */ jsxs12("table", { style: styles.table, children: [
1089
+ /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs12("tr", { children: [
1090
+ /* @__PURE__ */ jsx12("th", { style: styles.th, children: "When" }),
1091
+ /* @__PURE__ */ jsx12("th", { style: styles.th, children: "Type" }),
1092
+ /* @__PURE__ */ jsx12("th", { style: styles.th, children: "Workspace" }),
1093
+ /* @__PURE__ */ jsx12("th", { style: styles.th, children: "Actor" }),
1094
+ /* @__PURE__ */ jsx12("th", { style: styles.th, children: "Request" })
1031
1095
  ] }) }),
1032
- /* @__PURE__ */ jsx11("tbody", { children: events.map((e) => /* @__PURE__ */ jsxs11("tr", { children: [
1033
- /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: new Date(e.createdAt).toLocaleString() }),
1034
- /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: e.type }),
1035
- /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: String(e.payload["workspaceId"] ?? "\u2014") }),
1036
- /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: e.actorId ?? "\u2014" }),
1037
- /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: e.requestId ?? "" })
1096
+ /* @__PURE__ */ jsx12("tbody", { children: events.map((e) => /* @__PURE__ */ jsxs12("tr", { children: [
1097
+ /* @__PURE__ */ jsx12("td", { style: { ...styles.td, ...styles.muted }, children: new Date(e.createdAt).toLocaleString() }),
1098
+ /* @__PURE__ */ jsx12("td", { style: { ...styles.td, ...styles.mono }, children: e.type }),
1099
+ /* @__PURE__ */ jsx12("td", { style: { ...styles.td, ...styles.mono }, children: String(e.payload["workspaceId"] ?? "\u2014") }),
1100
+ /* @__PURE__ */ jsx12("td", { style: { ...styles.td, ...styles.mono }, children: e.actorId ?? "\u2014" }),
1101
+ /* @__PURE__ */ jsx12("td", { style: { ...styles.td, ...styles.muted }, children: e.requestId ?? "" })
1038
1102
  ] }, e.id)) })
1039
1103
  ] }),
1040
- isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.status, children: "Loading\u2026" }) : null,
1041
- hasMore && !isLoading ? /* @__PURE__ */ jsx11(
1104
+ isLoading ? /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Loading\u2026" }) : null,
1105
+ hasMore && !isLoading ? /* @__PURE__ */ jsx12(
1042
1106
  "button",
1043
1107
  {
1044
1108
  type: "button",
@@ -1051,7 +1115,7 @@ function AuditScreen({ client, pageSize = 50 }) {
1051
1115
  }
1052
1116
 
1053
1117
  // src/screens/AdminShell.tsx
1054
- import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1118
+ import { Fragment as Fragment8, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
1055
1119
  var NAV = [
1056
1120
  { group: "Today", items: [{ page: "attention", label: "Attention" }] },
1057
1121
  {
@@ -1078,7 +1142,8 @@ var NAV = [
1078
1142
  items: [
1079
1143
  { page: "audit", label: "Audit", needs: "audit" },
1080
1144
  { page: "log", label: "Admin log" },
1081
- { page: "tokens", label: "Access" }
1145
+ { page: "tokens", label: "Access" },
1146
+ { page: "migrations", label: "Migrations" }
1082
1147
  ]
1083
1148
  }
1084
1149
  ];
@@ -1110,42 +1175,45 @@ function AdminShell({
1110
1175
  let body;
1111
1176
  switch (current) {
1112
1177
  case "attention":
1113
- body = /* @__PURE__ */ jsx12(AttentionScreen, { client });
1178
+ body = /* @__PURE__ */ jsx13(AttentionScreen, { client });
1114
1179
  break;
1115
1180
  case "modules":
1116
- body = /* @__PURE__ */ jsx12(ModulesScreen, { client });
1181
+ body = /* @__PURE__ */ jsx13(ModulesScreen, { client });
1117
1182
  break;
1118
1183
  case "doctor":
1119
- body = /* @__PURE__ */ jsx12(DoctorScreen, { client });
1184
+ body = /* @__PURE__ */ jsx13(DoctorScreen, { client });
1120
1185
  break;
1121
1186
  case "config":
1122
- body = /* @__PURE__ */ jsx12(ConfigScreen, { client });
1187
+ body = /* @__PURE__ */ jsx13(ConfigScreen, { client });
1123
1188
  break;
1124
1189
  case "routes":
1125
- body = /* @__PURE__ */ jsx12(RoutesScreen, { client });
1190
+ body = /* @__PURE__ */ jsx13(RoutesScreen, { client });
1126
1191
  break;
1127
1192
  case "tokens":
1128
- body = /* @__PURE__ */ jsx12(TokensScreen, { client });
1193
+ body = /* @__PURE__ */ jsx13(TokensScreen, { client });
1194
+ break;
1195
+ case "migrations":
1196
+ body = /* @__PURE__ */ jsx13(MigrationsScreen, { client });
1129
1197
  break;
1130
1198
  case "log":
1131
- body = /* @__PURE__ */ jsx12(AdminLogScreen, { client });
1199
+ body = /* @__PURE__ */ jsx13(AdminLogScreen, { client });
1132
1200
  break;
1133
1201
  case "catalog":
1134
- body = billingClient ? /* @__PURE__ */ jsx12(CatalogScreen, { client: billingClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a BillingAdminClient to see the catalog here." });
1202
+ body = billingClient ? /* @__PURE__ */ jsx13(CatalogScreen, { client: billingClient }) : /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass a BillingAdminClient to see the catalog here." });
1135
1203
  break;
1136
1204
  case "subscriber":
1137
- body = billingClient ? /* @__PURE__ */ jsx12(SubscriberScreen, { client: billingClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a BillingAdminClient to look up subscribers here." });
1205
+ body = billingClient ? /* @__PURE__ */ jsx13(SubscriberScreen, { client: billingClient }) : /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass a BillingAdminClient to look up subscribers here." });
1138
1206
  break;
1139
1207
  case "audit":
1140
- body = auditClient ? /* @__PURE__ */ jsx12(AuditScreen, { client: auditClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass an AuditAdminClient to see the audit trail here." });
1208
+ body = auditClient ? /* @__PURE__ */ jsx13(AuditScreen, { client: auditClient }) : /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass an AuditAdminClient to see the audit trail here." });
1141
1209
  break;
1142
1210
  case "users":
1143
- body = authClient ? /* @__PURE__ */ jsx12(UsersScreen, { client: authClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass an AuthAdminClient to look up users here." });
1211
+ body = authClient ? /* @__PURE__ */ jsx13(UsersScreen, { client: authClient }) : /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass an AuthAdminClient to look up users here." });
1144
1212
  break;
1145
1213
  case "settings":
1146
- body = !configClient ? /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a ConfigAdminClient to manage config and secrets here." }) : editing && editing.kind !== "template" ? /* @__PURE__ */ jsxs12(Fragment8, { children: [
1147
- /* @__PURE__ */ jsx12("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
1148
- /* @__PURE__ */ jsx12(
1214
+ body = !configClient ? /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass a ConfigAdminClient to manage config and secrets here." }) : editing && editing.kind !== "template" ? /* @__PURE__ */ jsxs13(Fragment8, { children: [
1215
+ /* @__PURE__ */ jsx13("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
1216
+ /* @__PURE__ */ jsx13(
1149
1217
  ConfigEditorScreen,
1150
1218
  {
1151
1219
  client: configClient,
@@ -1155,7 +1223,7 @@ function AdminShell({
1155
1223
  onSaved: () => setEditing(null)
1156
1224
  }
1157
1225
  )
1158
- ] }) : /* @__PURE__ */ jsx12(
1226
+ ] }) : /* @__PURE__ */ jsx13(
1159
1227
  ConfigListScreen,
1160
1228
  {
1161
1229
  client: configClient,
@@ -1166,9 +1234,9 @@ function AdminShell({
1166
1234
  );
1167
1235
  break;
1168
1236
  case "templates":
1169
- body = !courierClient ? /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs12(Fragment8, { children: [
1170
- /* @__PURE__ */ jsx12("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
1171
- /* @__PURE__ */ jsx12(
1237
+ body = !courierClient ? /* @__PURE__ */ jsx13("p", { style: styles.status, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs13(Fragment8, { children: [
1238
+ /* @__PURE__ */ jsx13("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
1239
+ /* @__PURE__ */ jsx13(
1172
1240
  TemplateEditorScreen,
1173
1241
  {
1174
1242
  client: courierClient,
@@ -1176,7 +1244,7 @@ function AdminShell({
1176
1244
  onSaved: () => setEditing(null)
1177
1245
  }
1178
1246
  )
1179
- ] }) : /* @__PURE__ */ jsx12(
1247
+ ] }) : /* @__PURE__ */ jsx13(
1180
1248
  TemplateListScreen,
1181
1249
  {
1182
1250
  client: courierClient,
@@ -1185,13 +1253,13 @@ function AdminShell({
1185
1253
  );
1186
1254
  break;
1187
1255
  }
1188
- return /* @__PURE__ */ jsxs12("div", { style: styles.shell, children: [
1189
- /* @__PURE__ */ jsx12("nav", { style: styles.nav, "aria-label": "Admin", children: NAV.map((g) => {
1256
+ return /* @__PURE__ */ jsxs13("div", { style: styles.shell, children: [
1257
+ /* @__PURE__ */ jsx13("nav", { style: styles.nav, "aria-label": "Admin", children: NAV.map((g) => {
1190
1258
  const items = g.items.filter((i) => !i.needs || has[i.needs]);
1191
1259
  if (items.length === 0) return null;
1192
- return /* @__PURE__ */ jsxs12("div", { children: [
1193
- /* @__PURE__ */ jsx12("div", { style: styles.navGroup, children: g.group }),
1194
- items.map((i) => /* @__PURE__ */ jsx12(
1260
+ return /* @__PURE__ */ jsxs13("div", { children: [
1261
+ /* @__PURE__ */ jsx13("div", { style: styles.navGroup, children: g.group }),
1262
+ items.map((i) => /* @__PURE__ */ jsx13(
1195
1263
  "button",
1196
1264
  {
1197
1265
  type: "button",
@@ -1207,7 +1275,7 @@ function AdminShell({
1207
1275
  ))
1208
1276
  ] }, g.group);
1209
1277
  }) }),
1210
- /* @__PURE__ */ jsx12("main", { style: styles.main, children: body })
1278
+ /* @__PURE__ */ jsx13("main", { style: styles.main, children: body })
1211
1279
  ] });
1212
1280
  }
1213
1281
  export {
@@ -1218,6 +1286,7 @@ export {
1218
1286
  CatalogScreen,
1219
1287
  ConfigScreen,
1220
1288
  DoctorScreen,
1289
+ MigrationsScreen,
1221
1290
  ModulesScreen,
1222
1291
  RoutesScreen,
1223
1292
  SubscriberScreen,