@fonderie/react-admin-screens 0.2.0 → 0.4.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
@@ -1,7 +1,7 @@
1
1
  // src/screens/AdminShell.tsx
2
2
  import { ConfigEditorScreen, ConfigListScreen } from "@fonderie/react-config-admin-screens";
3
3
  import { TemplateEditorScreen, TemplateListScreen } from "@fonderie/react-courier-admin-screens";
4
- import { useState as useState2 } from "react";
4
+ import { useState as useState4 } from "react";
5
5
 
6
6
  // src/styles.ts
7
7
  var styles = {
@@ -475,8 +475,336 @@ function UsersScreen({ client }) {
475
475
  ] });
476
476
  }
477
477
 
478
- // src/screens/AdminShell.tsx
478
+ // src/screens/CatalogScreen.tsx
479
+ import { useAdminCatalog } from "@fonderie/react-admin";
479
480
  import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
481
+ function CatalogScreen({ client }) {
482
+ const { catalog, isLoading, error, refresh, deletePlan } = useAdminCatalog(client);
483
+ const money = (v) => v == null ? "\u2014" : (v / 100).toFixed(2);
484
+ return /* @__PURE__ */ jsxs9("div", { style: styles.container, children: [
485
+ /* @__PURE__ */ jsxs9("div", { style: styles.toolbar, children: [
486
+ /* @__PURE__ */ jsx9("h1", { style: { ...styles.title, marginBottom: 0 }, children: "Catalog" }),
487
+ /* @__PURE__ */ jsx9(
488
+ "button",
489
+ {
490
+ type: "button",
491
+ style: styles.button,
492
+ onClick: () => void refresh(),
493
+ disabled: isLoading,
494
+ children: "Refresh"
495
+ }
496
+ )
497
+ ] }),
498
+ error ? /* @__PURE__ */ jsx9("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
499
+ isLoading && !catalog ? /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Loading\u2026" }) : null,
500
+ catalog ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
501
+ /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Configured (code)" }),
502
+ /* @__PURE__ */ jsx9("pre", { style: { ...styles.mono, background: "#f9fafb", padding: 12, overflowX: "auto" }, children: JSON.stringify(catalog.configured, null, 2) }),
503
+ /* @__PURE__ */ jsx9("h2", { style: styles.subtitle, children: "Stored (database)" }),
504
+ catalog.stored.length === 0 ? /* @__PURE__ */ jsx9("p", { style: styles.muted, children: "No stored plans." }) : /* @__PURE__ */ jsxs9("table", { style: styles.table, children: [
505
+ /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs9("tr", { children: [
506
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Plan" }),
507
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Tier" }),
508
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Seats" }),
509
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Monthly" }),
510
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Yearly" }),
511
+ /* @__PURE__ */ jsx9("th", { style: styles.th, children: "Trial" }),
512
+ /* @__PURE__ */ jsx9("th", { style: styles.th })
513
+ ] }) }),
514
+ /* @__PURE__ */ jsx9("tbody", { children: catalog.stored.map((p) => /* @__PURE__ */ jsxs9("tr", { children: [
515
+ /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
516
+ /* @__PURE__ */ jsx9("strong", { children: p.name }),
517
+ p.description ? /* @__PURE__ */ jsx9("div", { style: styles.muted, children: p.description }) : null
518
+ ] }),
519
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.tier }),
520
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.seats ?? "\u221E" }),
521
+ /* @__PURE__ */ jsxs9("td", { style: styles.td, children: [
522
+ money(p.pricing?.monthly),
523
+ " ",
524
+ p.pricing?.currency ?? ""
525
+ ] }),
526
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: money(p.pricing?.yearly) }),
527
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: p.trialDays ? `${p.trialDays} d` : "\u2014" }),
528
+ /* @__PURE__ */ jsx9("td", { style: styles.td, children: /* @__PURE__ */ jsx9(
529
+ "button",
530
+ {
531
+ type: "button",
532
+ style: styles.button,
533
+ onClick: () => {
534
+ if (window.confirm(`Delete stored plan "${p.name}"?`))
535
+ void deletePlan(p.id).catch(() => {
536
+ });
537
+ },
538
+ children: "Delete"
539
+ }
540
+ ) })
541
+ ] }, p.id)) })
542
+ ] })
543
+ ] }) : null
544
+ ] });
545
+ }
546
+
547
+ // src/screens/SubscriberScreen.tsx
548
+ import { useAdminSubscriber } from "@fonderie/react-admin";
549
+ import { useState as useState2 } from "react";
550
+ import { Fragment as Fragment7, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
551
+ function SubscriberScreen({ client }) {
552
+ const [type, setType] = useState2("user");
553
+ const [idInput, setIdInput] = useState2("");
554
+ const [subscriber, setSubscriber] = useState2(null);
555
+ const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(client, subscriber, { limit: 20 });
556
+ const [amount, setAmount] = useState2("");
557
+ const [note, setNote] = useState2("");
558
+ const [granted, setGranted] = useState2(null);
559
+ return /* @__PURE__ */ jsxs10("div", { style: styles.container, children: [
560
+ /* @__PURE__ */ jsx10("h1", { style: styles.title, children: "Subscriber" }),
561
+ /* @__PURE__ */ jsxs10(
562
+ "form",
563
+ {
564
+ style: styles.toolbar,
565
+ onSubmit: (e) => {
566
+ e.preventDefault();
567
+ setGranted(null);
568
+ setSubscriber(idInput.trim() ? { type, id: idInput.trim() } : null);
569
+ },
570
+ children: [
571
+ /* @__PURE__ */ jsxs10(
572
+ "select",
573
+ {
574
+ value: type,
575
+ onChange: (e) => setType(e.target.value),
576
+ style: styles.button,
577
+ "aria-label": "Type",
578
+ children: [
579
+ /* @__PURE__ */ jsx10("option", { value: "user", children: "user" }),
580
+ /* @__PURE__ */ jsx10("option", { value: "workspace", children: "workspace" })
581
+ ]
582
+ }
583
+ ),
584
+ /* @__PURE__ */ jsx10(
585
+ "input",
586
+ {
587
+ value: idInput,
588
+ onChange: (e) => setIdInput(e.target.value),
589
+ placeholder: "subscriber id",
590
+ style: { ...styles.button, cursor: "text", minWidth: 280 },
591
+ "aria-label": "Subscriber id"
592
+ }
593
+ ),
594
+ /* @__PURE__ */ jsx10("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Look up" })
595
+ ]
596
+ }
597
+ ),
598
+ error ? /* @__PURE__ */ jsx10("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
599
+ subscriber && !isLoading ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
600
+ /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Subscription" }),
601
+ subscription ? /* @__PURE__ */ jsx10("table", { style: styles.table, children: /* @__PURE__ */ jsxs10("tbody", { children: [
602
+ /* @__PURE__ */ jsxs10("tr", { children: [
603
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: "plan" }),
604
+ /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
605
+ /* @__PURE__ */ jsx10("strong", { children: subscription.plan }),
606
+ " \xB7 ",
607
+ subscription.interval
608
+ ] })
609
+ ] }),
610
+ /* @__PURE__ */ jsxs10("tr", { children: [
611
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: "status" }),
612
+ /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
613
+ subscription.status,
614
+ subscription.cancelAtPeriodEnd ? " \xB7 cancels at period end" : ""
615
+ ] })
616
+ ] }),
617
+ /* @__PURE__ */ jsxs10("tr", { children: [
618
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: "period" }),
619
+ /* @__PURE__ */ jsxs10("td", { style: styles.td, children: [
620
+ subscription.currentPeriodStart ? new Date(subscription.currentPeriodStart).toLocaleDateString() : "\u2014",
621
+ " ",
622
+ "\u2192",
623
+ " ",
624
+ subscription.currentPeriodEnd ? new Date(subscription.currentPeriodEnd).toLocaleDateString() : "\u2014"
625
+ ] })
626
+ ] }),
627
+ /* @__PURE__ */ jsxs10("tr", { children: [
628
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: "provider" }),
629
+ /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.mono }, children: subscription.providerSubscriptionId ?? "\u2014" })
630
+ ] })
631
+ ] }) }) : /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No subscription." }),
632
+ /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Wallet" }),
633
+ wallet ? /* @__PURE__ */ jsxs10(Fragment7, { children: [
634
+ /* @__PURE__ */ jsxs10("p", { children: [
635
+ /* @__PURE__ */ jsx10("strong", { children: wallet.balance }),
636
+ " ",
637
+ wallet.currency,
638
+ " ",
639
+ /* @__PURE__ */ jsxs10("span", { style: styles.muted, children: [
640
+ "(granted ",
641
+ wallet.granted ?? "0",
642
+ " \xB7 purchased ",
643
+ wallet.purchased ?? "0",
644
+ ") \xB7 minor units, precision ",
645
+ wallet.precision
646
+ ] })
647
+ ] }),
648
+ /* @__PURE__ */ jsxs10(
649
+ "form",
650
+ {
651
+ style: styles.toolbar,
652
+ onSubmit: (e) => {
653
+ e.preventDefault();
654
+ const key = `admin-grant-${subscriber.type}-${subscriber.id}-${Date.now()}`;
655
+ void grant({
656
+ amount: amount.trim(),
657
+ ...note ? { description: note } : {},
658
+ idempotencyKey: key
659
+ }).then(() => {
660
+ setGranted(`Granted ${amount.trim()} ${wallet.currency}.`);
661
+ setAmount("");
662
+ setNote("");
663
+ }).catch(() => {
664
+ });
665
+ },
666
+ children: [
667
+ /* @__PURE__ */ jsx10(
668
+ "input",
669
+ {
670
+ value: amount,
671
+ onChange: (e) => setAmount(e.target.value),
672
+ placeholder: "amount (minor units)",
673
+ style: { ...styles.button, cursor: "text" },
674
+ "aria-label": "Amount"
675
+ }
676
+ ),
677
+ /* @__PURE__ */ jsx10(
678
+ "input",
679
+ {
680
+ value: note,
681
+ onChange: (e) => setNote(e.target.value),
682
+ placeholder: "reason (optional)",
683
+ style: { ...styles.button, cursor: "text", minWidth: 220 },
684
+ "aria-label": "Reason"
685
+ }
686
+ ),
687
+ /* @__PURE__ */ jsx10("button", { type: "submit", style: styles.button, disabled: !/^\d+$/.test(amount.trim()), children: "Grant" }),
688
+ granted ? /* @__PURE__ */ jsx10("span", { style: styles.ok, children: granted }) : null
689
+ ]
690
+ }
691
+ ),
692
+ /* @__PURE__ */ jsx10("h2", { style: styles.subtitle, children: "Ledger" }),
693
+ ledger.length === 0 ? /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "Nothing moved yet." }) : /* @__PURE__ */ jsxs10("table", { style: styles.table, children: [
694
+ /* @__PURE__ */ jsx10("thead", { children: /* @__PURE__ */ jsxs10("tr", { children: [
695
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "When" }),
696
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Kind" }),
697
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Amount" }),
698
+ /* @__PURE__ */ jsx10("th", { style: styles.th, children: "Note" })
699
+ ] }) }),
700
+ /* @__PURE__ */ jsx10("tbody", { children: ledger.map((t) => /* @__PURE__ */ jsxs10("tr", { children: [
701
+ /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.muted }, children: new Date(t.createdAt).toLocaleString() }),
702
+ /* @__PURE__ */ jsx10("td", { style: styles.td, children: t.type }),
703
+ /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.mono }, children: t.amount }),
704
+ /* @__PURE__ */ jsx10("td", { style: { ...styles.td, ...styles.muted }, children: t.description ?? "" })
705
+ ] }, t.id)) })
706
+ ] }),
707
+ hasMoreLedger ? /* @__PURE__ */ jsx10(
708
+ "button",
709
+ {
710
+ type: "button",
711
+ style: { ...styles.button, marginTop: 8 },
712
+ onClick: () => void loadMoreLedger(),
713
+ children: "Load more"
714
+ }
715
+ ) : null
716
+ ] }) : /* @__PURE__ */ jsx10("p", { style: styles.muted, children: "No wallet \u2014 billing has no wallet configuration." })
717
+ ] }) : null
718
+ ] });
719
+ }
720
+
721
+ // src/screens/AuditScreen.tsx
722
+ import { useAdminAudit } from "@fonderie/react-admin";
723
+ import { useState as useState3 } from "react";
724
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
725
+ function AuditScreen({ client, pageSize = 50 }) {
726
+ const [draft, setDraft] = useState3({ workspaceId: "", type: "", actorId: "" });
727
+ const [filter, setFilter] = useState3(
728
+ {}
729
+ );
730
+ const { events, hasMore, isLoading, error, refresh, loadMore } = useAdminAudit(client, {
731
+ ...filter,
732
+ limit: pageSize
733
+ });
734
+ const field = (key, placeholder) => /* @__PURE__ */ jsx11(
735
+ "input",
736
+ {
737
+ value: draft[key],
738
+ onChange: (e) => setDraft({ ...draft, [key]: e.target.value }),
739
+ placeholder,
740
+ style: { ...styles.button, cursor: "text" },
741
+ "aria-label": placeholder
742
+ }
743
+ );
744
+ return /* @__PURE__ */ jsxs11("div", { style: styles.container, children: [
745
+ /* @__PURE__ */ jsx11("h1", { style: styles.title, children: "Audit" }),
746
+ /* @__PURE__ */ jsxs11(
747
+ "form",
748
+ {
749
+ style: styles.toolbar,
750
+ onSubmit: (e) => {
751
+ e.preventDefault();
752
+ setFilter({
753
+ ...draft.workspaceId.trim() ? { workspaceId: draft.workspaceId.trim() } : {},
754
+ ...draft.type.trim() ? { type: draft.type.trim() } : {},
755
+ ...draft.actorId.trim() ? { actorId: draft.actorId.trim() } : {}
756
+ });
757
+ },
758
+ children: [
759
+ field("workspaceId", "workspace id (all if empty)"),
760
+ field("type", "event type"),
761
+ field("actorId", "actor id"),
762
+ /* @__PURE__ */ jsx11("button", { type: "submit", style: styles.button, disabled: isLoading, children: "Filter" }),
763
+ /* @__PURE__ */ jsx11(
764
+ "button",
765
+ {
766
+ type: "button",
767
+ style: styles.button,
768
+ onClick: () => void refresh(),
769
+ disabled: isLoading,
770
+ children: "Refresh"
771
+ }
772
+ )
773
+ ]
774
+ }
775
+ ),
776
+ error ? /* @__PURE__ */ jsx11("p", { style: styles.error, role: "alert", children: error.explanation }) : null,
777
+ events.length === 0 && !isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.muted, children: "Nothing recorded for this filter." }) : /* @__PURE__ */ jsxs11("table", { style: styles.table, children: [
778
+ /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs11("tr", { children: [
779
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "When" }),
780
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Type" }),
781
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Workspace" }),
782
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Actor" }),
783
+ /* @__PURE__ */ jsx11("th", { style: styles.th, children: "Request" })
784
+ ] }) }),
785
+ /* @__PURE__ */ jsx11("tbody", { children: events.map((e) => /* @__PURE__ */ jsxs11("tr", { children: [
786
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: new Date(e.createdAt).toLocaleString() }),
787
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: e.type }),
788
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: String(e.payload["workspaceId"] ?? "\u2014") }),
789
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.mono }, children: e.actorId ?? "\u2014" }),
790
+ /* @__PURE__ */ jsx11("td", { style: { ...styles.td, ...styles.muted }, children: e.requestId ?? "" })
791
+ ] }, e.id)) })
792
+ ] }),
793
+ isLoading ? /* @__PURE__ */ jsx11("p", { style: styles.status, children: "Loading\u2026" }) : null,
794
+ hasMore && !isLoading ? /* @__PURE__ */ jsx11(
795
+ "button",
796
+ {
797
+ type: "button",
798
+ style: { ...styles.button, marginTop: 8 },
799
+ onClick: () => void loadMore(),
800
+ children: "Load more"
801
+ }
802
+ ) : null
803
+ ] });
804
+ }
805
+
806
+ // src/screens/AdminShell.tsx
807
+ import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
480
808
  var NAV = [
481
809
  { group: "Today", items: [{ page: "attention", label: "Attention" }] },
482
810
  {
@@ -489,11 +817,19 @@ var NAV = [
489
817
  ]
490
818
  },
491
819
  { group: "People", items: [{ page: "users", label: "Users", needs: "auth" }] },
820
+ {
821
+ group: "Money",
822
+ items: [
823
+ { page: "catalog", label: "Catalog", needs: "billing" },
824
+ { page: "subscriber", label: "Subscriber", needs: "billing" }
825
+ ]
826
+ },
492
827
  { group: "Settings", items: [{ page: "settings", label: "Config & secrets", needs: "config" }] },
493
828
  { group: "Messaging", items: [{ page: "templates", label: "Templates", needs: "courier" }] },
494
829
  {
495
830
  group: "Activity",
496
831
  items: [
832
+ { page: "audit", label: "Audit", needs: "audit" },
497
833
  { page: "log", label: "Admin log" },
498
834
  { page: "tokens", label: "Access" }
499
835
  ]
@@ -504,52 +840,65 @@ function AdminShell({
504
840
  configClient,
505
841
  courierClient,
506
842
  authClient,
843
+ billingClient,
844
+ auditClient,
507
845
  environment,
508
846
  page,
509
847
  onNavigate
510
848
  }) {
511
- const [own, setOwn] = useState2("attention");
849
+ const [own, setOwn] = useState4("attention");
512
850
  const current = page ?? own;
513
851
  const go = (p) => {
514
852
  if (onNavigate) onNavigate(p);
515
853
  if (page === void 0) setOwn(p);
516
854
  };
517
- const [editing, setEditing] = useState2(null);
855
+ const [editing, setEditing] = useState4(null);
518
856
  const has = {
519
857
  config: Boolean(configClient),
520
858
  courier: Boolean(courierClient),
521
- auth: Boolean(authClient)
859
+ auth: Boolean(authClient),
860
+ billing: Boolean(billingClient),
861
+ audit: Boolean(auditClient)
522
862
  };
523
863
  let body;
524
864
  switch (current) {
525
865
  case "attention":
526
- body = /* @__PURE__ */ jsx9(AttentionScreen, { client });
866
+ body = /* @__PURE__ */ jsx12(AttentionScreen, { client });
527
867
  break;
528
868
  case "modules":
529
- body = /* @__PURE__ */ jsx9(ModulesScreen, { client });
869
+ body = /* @__PURE__ */ jsx12(ModulesScreen, { client });
530
870
  break;
531
871
  case "doctor":
532
- body = /* @__PURE__ */ jsx9(DoctorScreen, { client });
872
+ body = /* @__PURE__ */ jsx12(DoctorScreen, { client });
533
873
  break;
534
874
  case "config":
535
- body = /* @__PURE__ */ jsx9(ConfigScreen, { client });
875
+ body = /* @__PURE__ */ jsx12(ConfigScreen, { client });
536
876
  break;
537
877
  case "routes":
538
- body = /* @__PURE__ */ jsx9(RoutesScreen, { client });
878
+ body = /* @__PURE__ */ jsx12(RoutesScreen, { client });
539
879
  break;
540
880
  case "tokens":
541
- body = /* @__PURE__ */ jsx9(TokensScreen, { client });
881
+ body = /* @__PURE__ */ jsx12(TokensScreen, { client });
542
882
  break;
543
883
  case "log":
544
- body = /* @__PURE__ */ jsx9(AdminLogScreen, { client });
884
+ body = /* @__PURE__ */ jsx12(AdminLogScreen, { client });
885
+ break;
886
+ case "catalog":
887
+ body = billingClient ? /* @__PURE__ */ jsx12(CatalogScreen, { client: billingClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a BillingAdminClient to see the catalog here." });
888
+ break;
889
+ case "subscriber":
890
+ body = billingClient ? /* @__PURE__ */ jsx12(SubscriberScreen, { client: billingClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a BillingAdminClient to look up subscribers here." });
891
+ break;
892
+ case "audit":
893
+ body = auditClient ? /* @__PURE__ */ jsx12(AuditScreen, { client: auditClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass an AuditAdminClient to see the audit trail here." });
545
894
  break;
546
895
  case "users":
547
- body = authClient ? /* @__PURE__ */ jsx9(UsersScreen, { client: authClient }) : /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Pass an AuthAdminClient to look up users here." });
896
+ body = authClient ? /* @__PURE__ */ jsx12(UsersScreen, { client: authClient }) : /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass an AuthAdminClient to look up users here." });
548
897
  break;
549
898
  case "settings":
550
- body = !configClient ? /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Pass a ConfigAdminClient to manage config and secrets here." }) : editing && editing.kind !== "template" ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
551
- /* @__PURE__ */ jsx9("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
552
- /* @__PURE__ */ jsx9(
899
+ 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: [
900
+ /* @__PURE__ */ jsx12("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
901
+ /* @__PURE__ */ jsx12(
553
902
  ConfigEditorScreen,
554
903
  {
555
904
  client: configClient,
@@ -559,7 +908,7 @@ function AdminShell({
559
908
  onSaved: () => setEditing(null)
560
909
  }
561
910
  )
562
- ] }) : /* @__PURE__ */ jsx9(
911
+ ] }) : /* @__PURE__ */ jsx12(
563
912
  ConfigListScreen,
564
913
  {
565
914
  client: configClient,
@@ -570,9 +919,9 @@ function AdminShell({
570
919
  );
571
920
  break;
572
921
  case "templates":
573
- body = !courierClient ? /* @__PURE__ */ jsx9("p", { style: styles.status, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
574
- /* @__PURE__ */ jsx9("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
575
- /* @__PURE__ */ jsx9(
922
+ body = !courierClient ? /* @__PURE__ */ jsx12("p", { style: styles.status, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs12(Fragment8, { children: [
923
+ /* @__PURE__ */ jsx12("button", { type: "button", style: styles.button, onClick: () => setEditing(null), children: "\u2190 Back" }),
924
+ /* @__PURE__ */ jsx12(
576
925
  TemplateEditorScreen,
577
926
  {
578
927
  client: courierClient,
@@ -580,7 +929,7 @@ function AdminShell({
580
929
  onSaved: () => setEditing(null)
581
930
  }
582
931
  )
583
- ] }) : /* @__PURE__ */ jsx9(
932
+ ] }) : /* @__PURE__ */ jsx12(
584
933
  TemplateListScreen,
585
934
  {
586
935
  client: courierClient,
@@ -589,13 +938,13 @@ function AdminShell({
589
938
  );
590
939
  break;
591
940
  }
592
- return /* @__PURE__ */ jsxs9("div", { style: styles.shell, children: [
593
- /* @__PURE__ */ jsx9("nav", { style: styles.nav, "aria-label": "Admin", children: NAV.map((g) => {
941
+ return /* @__PURE__ */ jsxs12("div", { style: styles.shell, children: [
942
+ /* @__PURE__ */ jsx12("nav", { style: styles.nav, "aria-label": "Admin", children: NAV.map((g) => {
594
943
  const items = g.items.filter((i) => !i.needs || has[i.needs]);
595
944
  if (items.length === 0) return null;
596
- return /* @__PURE__ */ jsxs9("div", { children: [
597
- /* @__PURE__ */ jsx9("div", { style: styles.navGroup, children: g.group }),
598
- items.map((i) => /* @__PURE__ */ jsx9(
945
+ return /* @__PURE__ */ jsxs12("div", { children: [
946
+ /* @__PURE__ */ jsx12("div", { style: styles.navGroup, children: g.group }),
947
+ items.map((i) => /* @__PURE__ */ jsx12(
599
948
  "button",
600
949
  {
601
950
  type: "button",
@@ -611,17 +960,20 @@ function AdminShell({
611
960
  ))
612
961
  ] }, g.group);
613
962
  }) }),
614
- /* @__PURE__ */ jsx9("main", { style: styles.main, children: body })
963
+ /* @__PURE__ */ jsx12("main", { style: styles.main, children: body })
615
964
  ] });
616
965
  }
617
966
  export {
618
967
  AdminLogScreen,
619
968
  AdminShell,
620
969
  AttentionScreen,
970
+ AuditScreen,
971
+ CatalogScreen,
621
972
  ConfigScreen,
622
973
  DoctorScreen,
623
974
  ModulesScreen,
624
975
  RoutesScreen,
976
+ SubscriberScreen,
625
977
  TokensScreen,
626
978
  UsersScreen
627
979
  };