@fonderie/react-admin-screens 1.4.0 → 1.5.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.d.cts CHANGED
@@ -18,8 +18,9 @@ interface IAdminShellProps {
18
18
  footer?: ReactNode;
19
19
  operators?: boolean;
20
20
  currentOperator?: string;
21
+ publicConfigUrl?: string;
21
22
  }
22
- declare function AdminShell({ client, configClient, courierClient, authClient, billingClient, auditClient, environment, page, onNavigate, appName, envLabel, footer, operators, currentOperator, }: IAdminShellProps): react.JSX.Element;
23
+ declare function AdminShell({ client, configClient, courierClient, authClient, billingClient, auditClient, environment, page, onNavigate, appName, envLabel, footer, operators, currentOperator, publicConfigUrl, }: IAdminShellProps): react.JSX.Element;
23
24
 
24
25
  interface IAttentionScreenProps {
25
26
  client: AdminClient;
package/dist/index.d.ts CHANGED
@@ -18,8 +18,9 @@ interface IAdminShellProps {
18
18
  footer?: ReactNode;
19
19
  operators?: boolean;
20
20
  currentOperator?: string;
21
+ publicConfigUrl?: string;
21
22
  }
22
- declare function AdminShell({ client, configClient, courierClient, authClient, billingClient, auditClient, environment, page, onNavigate, appName, envLabel, footer, operators, currentOperator, }: IAdminShellProps): react.JSX.Element;
23
+ declare function AdminShell({ client, configClient, courierClient, authClient, billingClient, auditClient, environment, page, onNavigate, appName, envLabel, footer, operators, currentOperator, publicConfigUrl, }: IAdminShellProps): react.JSX.Element;
23
24
 
24
25
  interface IAttentionScreenProps {
25
26
  client: AdminClient;
package/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  // src/screens/AdminShell.tsx
2
2
  import { ConfigEditorScreen, ConfigListScreen } from "@fonderie/react-config-admin-screens";
3
- import { TemplateEditorScreen, TemplateListScreen } from "@fonderie/react-courier-admin-screens";
3
+ import {
4
+ TemplateCreateScreen,
5
+ TemplateEditorScreen,
6
+ TemplateListScreen
7
+ } from "@fonderie/react-courier-admin-screens";
4
8
  import { useEffect as useEffect2, useState as useState9 } from "react";
5
9
 
6
10
  // src/styles.ts
@@ -1554,7 +1558,9 @@ import { useAdminSubscriber } from "@fonderie/react-admin";
1554
1558
  import { useState as useState5 } from "react";
1555
1559
  import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
1556
1560
  function SubscriberBilling({ client, subscriber }) {
1557
- const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(client, subscriber, { limit: 20 });
1561
+ const [currency, setCurrency] = useState5("");
1562
+ const [currencyDraft, setCurrencyDraft] = useState5("");
1563
+ const { subscription, wallet, ledger, hasMoreLedger, isLoading, error, loadMoreLedger, grant } = useAdminSubscriber(client, subscriber, { limit: 20, ...currency ? { currency } : {} });
1558
1564
  const [amount, setAmount] = useState5("");
1559
1565
  const [note, setNote] = useState5("");
1560
1566
  const [granted, setGranted] = useState5(null);
@@ -1595,7 +1601,42 @@ function SubscriberBilling({ client, subscriber }) {
1595
1601
  subscription?.providerSubscriptionId ? /* @__PURE__ */ jsx11("div", { style: { ...styles.statHint, fontFamily: "var(--fonderie-mono,monospace)" }, children: subscription.providerSubscriptionId }) : null
1596
1602
  ] }),
1597
1603
  /* @__PURE__ */ jsxs11("div", { style: styles.card, children: [
1598
- /* @__PURE__ */ jsx11("div", { style: styles.statLabel, children: "Credits" }),
1604
+ /* @__PURE__ */ jsxs11(
1605
+ "div",
1606
+ {
1607
+ style: {
1608
+ display: "flex",
1609
+ justifyContent: "space-between",
1610
+ alignItems: "center",
1611
+ gap: 8
1612
+ },
1613
+ children: [
1614
+ /* @__PURE__ */ jsx11("div", { style: styles.statLabel, children: "Credits" }),
1615
+ /* @__PURE__ */ jsx11(
1616
+ "form",
1617
+ {
1618
+ style: { display: "flex", gap: 4 },
1619
+ onSubmit: (e) => {
1620
+ e.preventDefault();
1621
+ setCurrency(currencyDraft.trim().toUpperCase());
1622
+ },
1623
+ children: /* @__PURE__ */ jsx11(
1624
+ "input",
1625
+ {
1626
+ value: currencyDraft,
1627
+ onChange: (e) => setCurrencyDraft(e.target.value),
1628
+ placeholder: wallet?.currency ?? "currency",
1629
+ maxLength: 8,
1630
+ style: { ...styles.input, height: 26, width: 84, fontSize: 12 },
1631
+ "aria-label": "Wallet currency",
1632
+ title: "Show the wallet in another currency"
1633
+ }
1634
+ )
1635
+ }
1636
+ )
1637
+ ]
1638
+ }
1639
+ ),
1599
1640
  wallet ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
1600
1641
  /* @__PURE__ */ jsxs11("div", { style: styles.statValue, children: [
1601
1642
  wallet.balance,
@@ -2283,10 +2324,8 @@ import { useAdminAudit } from "@fonderie/react-admin";
2283
2324
  import { useState as useState8 } from "react";
2284
2325
  import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
2285
2326
  function AuditScreen({ client, pageSize = 50 }) {
2286
- const [draft, setDraft] = useState8({ workspaceId: "", type: "", actorId: "" });
2287
- const [filter, setFilter] = useState8(
2288
- {}
2289
- );
2327
+ const [draft, setDraft] = useState8({ workspaceId: "", type: "", actorId: "", from: "", to: "" });
2328
+ const [filter, setFilter] = useState8({});
2290
2329
  const { events, hasMore, isLoading, error, refresh, loadMore } = useAdminAudit(client, {
2291
2330
  ...filter,
2292
2331
  limit: pageSize
@@ -2318,13 +2357,38 @@ function AuditScreen({ client, pageSize = 50 }) {
2318
2357
  setFilter({
2319
2358
  ...draft.workspaceId.trim() ? { workspaceId: draft.workspaceId.trim() } : {},
2320
2359
  ...draft.type.trim() ? { type: draft.type.trim() } : {},
2321
- ...draft.actorId.trim() ? { actorId: draft.actorId.trim() } : {}
2360
+ ...draft.actorId.trim() ? { actorId: draft.actorId.trim() } : {},
2361
+ // Dates are whole days in the operator's time zone: "to" includes that day.
2362
+ ...draft.from ? { from: /* @__PURE__ */ new Date(`${draft.from}T00:00:00`) } : {},
2363
+ ...draft.to ? { to: /* @__PURE__ */ new Date(`${draft.to}T23:59:59.999`) } : {}
2322
2364
  });
2323
2365
  },
2324
2366
  children: [
2325
2367
  field("workspaceId", "workspace id (all if empty)"),
2326
2368
  field("type", "event type"),
2327
2369
  field("actorId", "actor id"),
2370
+ /* @__PURE__ */ jsx15(
2371
+ "input",
2372
+ {
2373
+ type: "date",
2374
+ value: draft.from,
2375
+ onChange: (e) => setDraft({ ...draft, from: e.target.value }),
2376
+ style: styles.input,
2377
+ "aria-label": "From date",
2378
+ title: "From (inclusive)"
2379
+ }
2380
+ ),
2381
+ /* @__PURE__ */ jsx15(
2382
+ "input",
2383
+ {
2384
+ type: "date",
2385
+ value: draft.to,
2386
+ onChange: (e) => setDraft({ ...draft, to: e.target.value }),
2387
+ style: styles.input,
2388
+ "aria-label": "To date",
2389
+ title: "To (inclusive)"
2390
+ }
2391
+ ),
2328
2392
  /* @__PURE__ */ jsxs15("button", { type: "submit", style: styles.buttonPrimary, disabled: isLoading, children: [
2329
2393
  /* @__PURE__ */ jsx15(Icon, { name: "search", size: 14 }),
2330
2394
  "Filter"
@@ -2449,7 +2513,8 @@ function AdminShell({
2449
2513
  envLabel,
2450
2514
  footer,
2451
2515
  operators = false,
2452
- currentOperator
2516
+ currentOperator,
2517
+ publicConfigUrl
2453
2518
  }) {
2454
2519
  const narrow = useNarrow();
2455
2520
  const [drawer, setDrawer] = useState9(false);
@@ -2531,7 +2596,7 @@ function AdminShell({
2531
2596
  ) : /* @__PURE__ */ jsx16("p", { style: { ...styles.status, padding: "32px 40px" }, children: "Pass an AuthAdminClient to look up users here." });
2532
2597
  break;
2533
2598
  case "settings":
2534
- body = !configClient ? /* @__PURE__ */ jsx16("p", { style: { ...styles.status, padding: "32px 40px" }, children: "Pass a ConfigAdminClient to manage config and secrets here." }) : editing && editing.kind !== "template" ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
2599
+ body = !configClient ? /* @__PURE__ */ jsx16("p", { style: { ...styles.status, padding: "32px 40px" }, children: "Pass a ConfigAdminClient to manage config and secrets here." }) : editing && (editing.kind === "config" || editing.kind === "secret") ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
2535
2600
  /* @__PURE__ */ jsx16("div", { style: { padding: "24px 40px 0" }, children: /* @__PURE__ */ jsxs16("button", { type: "button", style: styles.buttonGhost, onClick: () => setEditing(null), children: [
2536
2601
  /* @__PURE__ */ jsx16(Icon, { name: "back", size: 14 }),
2537
2602
  "Config & secrets"
@@ -2542,24 +2607,52 @@ function AdminShell({
2542
2607
  client: configClient,
2543
2608
  kind: editing.kind,
2544
2609
  configKey: editing.key,
2545
- ...environment !== void 0 ? { environment } : {},
2546
- onSaved: () => setEditing(null)
2547
- }
2610
+ ...editing.environment !== void 0 ? { environment: editing.environment } : environment !== void 0 ? { environment } : {},
2611
+ ...editing.environments ? { environments: editing.environments } : {},
2612
+ onSaved: () => setEditing(null),
2613
+ onDeleted: () => setEditing(null)
2614
+ },
2615
+ `${editing.kind}:${editing.key}:${editing.environment ?? ""}`
2548
2616
  )
2549
2617
  ] }) : /* @__PURE__ */ jsx16(
2550
2618
  ConfigListScreen,
2551
2619
  {
2552
2620
  client: configClient,
2553
2621
  ...environment !== void 0 ? { environment } : {},
2554
- onSelectConfig: (key) => setEditing({ kind: "config", key }),
2555
- onSelectSecret: (key) => setEditing({ kind: "secret", key }),
2556
- onCreateConfig: () => setEditing({ kind: "config", key: "" }),
2557
- onCreateSecret: () => setEditing({ kind: "secret", key: "" })
2622
+ ...publicConfigUrl ? { publicConfigUrl } : {},
2623
+ onSelectConfig: (key, env) => setEditing({ kind: "config", key, environment: env }),
2624
+ onSelectSecret: (key, env) => setEditing({ kind: "secret", key, environment: env }),
2625
+ onCreateConfig: (c) => setEditing({
2626
+ kind: "config",
2627
+ key: "",
2628
+ environments: c.environments,
2629
+ ...c.environment ? { environment: c.environment } : {}
2630
+ }),
2631
+ onCreateSecret: (c) => setEditing({
2632
+ kind: "secret",
2633
+ key: "",
2634
+ environments: c.environments,
2635
+ ...c.environment ? { environment: c.environment } : {}
2636
+ })
2558
2637
  }
2559
2638
  );
2560
2639
  break;
2561
2640
  case "templates":
2562
- body = !courierClient ? /* @__PURE__ */ jsx16("p", { style: { ...styles.status, padding: "32px 40px" }, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
2641
+ body = !courierClient ? /* @__PURE__ */ jsx16("p", { style: { ...styles.status, padding: "32px 40px" }, children: "Pass a CourierAdminClient to manage templates here." }) : editing?.kind === "template-new" ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
2642
+ /* @__PURE__ */ jsx16("div", { style: { padding: "24px 40px 0" }, children: /* @__PURE__ */ jsxs16("button", { type: "button", style: styles.buttonGhost, onClick: () => setEditing(null), children: [
2643
+ /* @__PURE__ */ jsx16(Icon, { name: "back", size: 14 }),
2644
+ "Templates"
2645
+ ] }) }),
2646
+ /* @__PURE__ */ jsx16(
2647
+ TemplateCreateScreen,
2648
+ {
2649
+ client: courierClient,
2650
+ ...editing.type ? { type: editing.type } : {},
2651
+ ...editing.locales ? { locales: editing.locales } : {},
2652
+ onCreated: (c) => setEditing({ kind: "template", type: c.type, locale: c.locale, system: false })
2653
+ }
2654
+ )
2655
+ ] }) : editing?.kind === "template" ? /* @__PURE__ */ jsxs16(Fragment10, { children: [
2563
2656
  /* @__PURE__ */ jsx16("div", { style: { padding: "24px 40px 0" }, children: /* @__PURE__ */ jsxs16("button", { type: "button", style: styles.buttonGhost, onClick: () => setEditing(null), children: [
2564
2657
  /* @__PURE__ */ jsx16(Icon, { name: "back", size: 14 }),
2565
2658
  "Templates"
@@ -2569,14 +2662,25 @@ function AdminShell({
2569
2662
  {
2570
2663
  client: courierClient,
2571
2664
  type: editing.type,
2572
- onSaved: () => setEditing(null)
2573
- }
2665
+ locale: editing.locale,
2666
+ system: editing.system,
2667
+ onSaved: () => setEditing(null),
2668
+ onDeleted: () => setEditing(null),
2669
+ onAddLocale: (type) => setEditing({ kind: "template-new", type })
2670
+ },
2671
+ `${editing.type}:${editing.locale ?? ""}`
2574
2672
  )
2575
2673
  ] }) : /* @__PURE__ */ jsx16(
2576
2674
  TemplateListScreen,
2577
2675
  {
2578
2676
  client: courierClient,
2579
- onSelectTemplate: (t2) => setEditing({ kind: "template", type: t2.type })
2677
+ onSelectTemplate: (t2) => setEditing({
2678
+ kind: "template",
2679
+ type: t2.type,
2680
+ locale: t2.locale ?? null,
2681
+ system: t2.system === true
2682
+ }),
2683
+ onCreateTemplate: (c) => setEditing({ kind: "template-new", locales: c.locales })
2580
2684
  }
2581
2685
  );
2582
2686
  break;