@quanticjs/notification-ui 8.0.0 → 8.1.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
@@ -460,9 +460,117 @@ function InboxRow({
460
460
  ) });
461
461
  }
462
462
 
463
+ // src/notification-center.tsx
464
+ import { useCallback, useEffect as useEffect4, useRef as useRef2, useState as useState3 } from "react";
465
+ import { cn as cn4, useExitAnimation, useFocusTrap } from "@quanticjs/react-ui";
466
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
467
+ function BellIcon() {
468
+ return /* @__PURE__ */ jsxs4(
469
+ "svg",
470
+ {
471
+ "aria-hidden": true,
472
+ viewBox: "0 0 24 24",
473
+ fill: "none",
474
+ stroke: "currentColor",
475
+ strokeWidth: "2",
476
+ strokeLinecap: "round",
477
+ strokeLinejoin: "round",
478
+ className: "h-5 w-5",
479
+ children: [
480
+ /* @__PURE__ */ jsx6("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
481
+ /* @__PURE__ */ jsx6("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
482
+ ]
483
+ }
484
+ );
485
+ }
486
+ function NotificationCenter({
487
+ appId,
488
+ basePath,
489
+ pollIntervalMs,
490
+ className,
491
+ panelClassName
492
+ }) {
493
+ const [open, setOpen] = useState3(false);
494
+ const containerRef = useRef2(null);
495
+ const panelRef = useRef2(null);
496
+ const { data } = useUnreadCount({ appId, basePath, pollIntervalMs });
497
+ const unreadCount = data?.count ?? 0;
498
+ const badge = unreadCount > 99 ? "99+" : String(unreadCount);
499
+ const label = unreadCount === 0 ? "No unread notifications" : `${unreadCount} unread notifications`;
500
+ const close = useCallback(() => setOpen(false), []);
501
+ useEffect4(() => {
502
+ if (!open) return;
503
+ const onKey = (e) => {
504
+ if (e.key === "Escape") close();
505
+ };
506
+ const onPointer = (e) => {
507
+ const c = containerRef.current;
508
+ if (c && e.target instanceof Node && !c.contains(e.target)) close();
509
+ };
510
+ document.addEventListener("keydown", onKey);
511
+ document.addEventListener("mousedown", onPointer);
512
+ return () => {
513
+ document.removeEventListener("keydown", onKey);
514
+ document.removeEventListener("mousedown", onPointer);
515
+ };
516
+ }, [open, close]);
517
+ useFocusTrap(panelRef, open);
518
+ const panelExit = useExitAnimation(open);
519
+ return /* @__PURE__ */ jsxs4("div", { ref: containerRef, className: cn4("relative inline-block", className), children: [
520
+ /* @__PURE__ */ jsxs4(
521
+ "button",
522
+ {
523
+ type: "button",
524
+ "aria-label": label,
525
+ "aria-haspopup": "dialog",
526
+ "aria-expanded": open,
527
+ onClick: () => setOpen((p) => !p),
528
+ className: "relative inline-flex h-10 w-10 items-center justify-center rounded-full text-foreground hover:bg-muted focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
529
+ children: [
530
+ /* @__PURE__ */ jsx6(BellIcon, {}),
531
+ /* @__PURE__ */ jsx6("span", { role: "status", className: "sr-only", children: label }),
532
+ unreadCount > 0 && /* @__PURE__ */ jsx6(
533
+ "span",
534
+ {
535
+ "aria-hidden": true,
536
+ className: "absolute -end-0.5 -top-0.5 inline-flex min-w-5 items-center justify-center rounded-full bg-destructive px-1.5 text-xs font-semibold text-destructive-foreground",
537
+ children: badge
538
+ }
539
+ )
540
+ ]
541
+ }
542
+ ),
543
+ panelExit.mounted && /* @__PURE__ */ jsx6(
544
+ "div",
545
+ {
546
+ ref: panelRef,
547
+ role: "dialog",
548
+ "aria-label": "Notifications",
549
+ tabIndex: -1,
550
+ "data-state": panelExit.state,
551
+ onAnimationEnd: panelExit.onAnimationEnd,
552
+ className: cn4(
553
+ "absolute end-0 z-(--z-popover) mt-2 w-96 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-raised",
554
+ panelExit.state === "open" ? "animate-pop-in" : "animate-pop-out [animation-fill-mode:forwards]",
555
+ panelClassName
556
+ ),
557
+ children: /* @__PURE__ */ jsx6(
558
+ NotificationInbox,
559
+ {
560
+ appId,
561
+ basePath,
562
+ pollIntervalMs,
563
+ className: "max-h-[28rem] overflow-y-auto"
564
+ }
565
+ )
566
+ }
567
+ )
568
+ ] });
569
+ }
570
+
463
571
  // src/delivery-analytics-page.tsx
464
- import { useState as useState3 } from "react";
465
- import { cn as cn7 } from "@quanticjs/react-ui";
572
+ import { useState as useState4 } from "react";
573
+ import { cn as cn8 } from "@quanticjs/react-ui";
466
574
 
467
575
  // src/use-delivery-analytics.ts
468
576
  import { useApiQuery as useApiQuery4 } from "@quanticjs/react-query";
@@ -514,8 +622,8 @@ function useDeliveryTypes({
514
622
  }
515
623
 
516
624
  // src/funnel-stats.tsx
517
- import { cn as cn4 } from "@quanticjs/react-ui";
518
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
625
+ import { cn as cn5 } from "@quanticjs/react-ui";
626
+ import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
519
627
  var pct = (n) => `${(n * 100).toFixed(1)}%`;
520
628
  function FunnelStats({ funnel, className }) {
521
629
  const cards = [
@@ -528,13 +636,13 @@ function FunnelStats({ funnel, className }) {
528
636
  { label: "Bounce rate", value: pct(funnel.bounceRate) },
529
637
  { label: "Delivery rate", value: pct(funnel.deliveryRate) }
530
638
  ];
531
- return /* @__PURE__ */ jsx6("ul", { className: cn4("grid grid-cols-2 gap-3 sm:grid-cols-4", className), "aria-label": "Delivery funnel", children: cards.map((c) => /* @__PURE__ */ jsxs4(
639
+ return /* @__PURE__ */ jsx7("ul", { className: cn5("grid grid-cols-2 gap-3 sm:grid-cols-4", className), "aria-label": "Delivery funnel", children: cards.map((c) => /* @__PURE__ */ jsxs5(
532
640
  "li",
533
641
  {
534
642
  className: "flex flex-col gap-1 rounded-lg border border-border bg-card p-4",
535
643
  children: [
536
- /* @__PURE__ */ jsx6("span", { className: "text-xs font-medium text-muted-foreground", children: c.label }),
537
- /* @__PURE__ */ jsx6("span", { className: "text-2xl font-semibold text-foreground", children: c.value })
644
+ /* @__PURE__ */ jsx7("span", { className: "text-xs font-medium text-muted-foreground", children: c.label }),
645
+ /* @__PURE__ */ jsx7("span", { className: "text-2xl font-semibold text-foreground", children: c.value })
538
646
  ]
539
647
  },
540
648
  c.label
@@ -542,7 +650,7 @@ function FunnelStats({ funnel, className }) {
542
650
  }
543
651
 
544
652
  // src/trend-chart.tsx
545
- import { cn as cn5 } from "@quanticjs/react-ui";
653
+ import { cn as cn6 } from "@quanticjs/react-ui";
546
654
  import {
547
655
  CartesianGrid,
548
656
  Line,
@@ -552,46 +660,46 @@ import {
552
660
  XAxis,
553
661
  YAxis
554
662
  } from "recharts";
555
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
663
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
556
664
  function TrendChart({ data, className }) {
557
- return /* @__PURE__ */ jsx7("div", { className: cn5("h-72 w-full", className), role: "img", "aria-label": "Delivery trend over time", children: /* @__PURE__ */ jsx7(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs5(LineChart, { data, margin: { top: 8, right: 16, bottom: 8, left: 0 }, children: [
558
- /* @__PURE__ */ jsx7(CartesianGrid, { strokeDasharray: "3 3", stroke: "hsl(var(--border))" }),
559
- /* @__PURE__ */ jsx7(XAxis, { dataKey: "day", stroke: "hsl(var(--muted-foreground))", fontSize: 12 }),
560
- /* @__PURE__ */ jsx7(YAxis, { stroke: "hsl(var(--muted-foreground))", fontSize: 12, allowDecimals: false }),
561
- /* @__PURE__ */ jsx7(Tooltip, {}),
562
- /* @__PURE__ */ jsx7(Line, { type: "monotone", dataKey: "sends", stroke: "hsl(var(--primary))", dot: false }),
563
- /* @__PURE__ */ jsx7(Line, { type: "monotone", dataKey: "delivered", stroke: "hsl(var(--chart-2, var(--primary)))", dot: false }),
564
- /* @__PURE__ */ jsx7(Line, { type: "monotone", dataKey: "opened", stroke: "hsl(var(--chart-3, var(--primary)))", dot: false }),
565
- /* @__PURE__ */ jsx7(Line, { type: "monotone", dataKey: "clicked", stroke: "hsl(var(--chart-4, var(--primary)))", dot: false })
665
+ return /* @__PURE__ */ jsx8("div", { className: cn6("h-72 w-full", className), role: "img", "aria-label": "Delivery trend over time", children: /* @__PURE__ */ jsx8(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs6(LineChart, { data, margin: { top: 8, right: 16, bottom: 8, left: 0 }, children: [
666
+ /* @__PURE__ */ jsx8(CartesianGrid, { strokeDasharray: "3 3", stroke: "hsl(var(--border))" }),
667
+ /* @__PURE__ */ jsx8(XAxis, { dataKey: "day", stroke: "hsl(var(--muted-foreground))", fontSize: 12 }),
668
+ /* @__PURE__ */ jsx8(YAxis, { stroke: "hsl(var(--muted-foreground))", fontSize: 12, allowDecimals: false }),
669
+ /* @__PURE__ */ jsx8(Tooltip, {}),
670
+ /* @__PURE__ */ jsx8(Line, { type: "monotone", dataKey: "sends", stroke: "hsl(var(--primary))", dot: false }),
671
+ /* @__PURE__ */ jsx8(Line, { type: "monotone", dataKey: "delivered", stroke: "hsl(var(--chart-2, var(--primary)))", dot: false }),
672
+ /* @__PURE__ */ jsx8(Line, { type: "monotone", dataKey: "opened", stroke: "hsl(var(--chart-3, var(--primary)))", dot: false }),
673
+ /* @__PURE__ */ jsx8(Line, { type: "monotone", dataKey: "clicked", stroke: "hsl(var(--chart-4, var(--primary)))", dot: false })
566
674
  ] }) }) });
567
675
  }
568
676
 
569
677
  // src/type-table.tsx
570
- import { cn as cn6 } from "@quanticjs/react-ui";
571
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
678
+ import { cn as cn7 } from "@quanticjs/react-ui";
679
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
572
680
  var pct2 = (n) => `${(n * 100).toFixed(1)}%`;
573
681
  function TypeTable({ rows, className }) {
574
- return /* @__PURE__ */ jsxs6("table", { className: cn6("w-full border-collapse text-sm", className), children: [
575
- /* @__PURE__ */ jsx8("caption", { className: "sr-only", children: "Delivery breakdown by notification type" }),
576
- /* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs6("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
577
- /* @__PURE__ */ jsx8("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Type" }),
578
- /* @__PURE__ */ jsx8("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Sends" }),
579
- /* @__PURE__ */ jsx8("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Delivered" }),
580
- /* @__PURE__ */ jsx8("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Open rate" }),
581
- /* @__PURE__ */ jsx8("th", { scope: "col", className: "py-2 font-medium", children: "Click rate" })
682
+ return /* @__PURE__ */ jsxs7("table", { className: cn7("w-full border-collapse text-sm", className), children: [
683
+ /* @__PURE__ */ jsx9("caption", { className: "sr-only", children: "Delivery breakdown by notification type" }),
684
+ /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsxs7("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
685
+ /* @__PURE__ */ jsx9("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Type" }),
686
+ /* @__PURE__ */ jsx9("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Sends" }),
687
+ /* @__PURE__ */ jsx9("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Delivered" }),
688
+ /* @__PURE__ */ jsx9("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Open rate" }),
689
+ /* @__PURE__ */ jsx9("th", { scope: "col", className: "py-2 font-medium", children: "Click rate" })
582
690
  ] }) }),
583
- /* @__PURE__ */ jsx8("tbody", { children: rows.map((r) => /* @__PURE__ */ jsxs6("tr", { className: "border-b border-border/50", children: [
584
- /* @__PURE__ */ jsx8("td", { className: "py-2 pe-4 font-medium text-foreground", children: r.type }),
585
- /* @__PURE__ */ jsx8("td", { className: "py-2 pe-4 text-foreground", children: r.sends }),
586
- /* @__PURE__ */ jsx8("td", { className: "py-2 pe-4 text-foreground", children: r.delivered }),
587
- /* @__PURE__ */ jsx8("td", { className: "py-2 pe-4 text-foreground", children: pct2(r.openRate) }),
588
- /* @__PURE__ */ jsx8("td", { className: "py-2 text-foreground", children: pct2(r.clickRate) })
691
+ /* @__PURE__ */ jsx9("tbody", { children: rows.map((r) => /* @__PURE__ */ jsxs7("tr", { className: "border-b border-border/50", children: [
692
+ /* @__PURE__ */ jsx9("td", { className: "py-2 pe-4 font-medium text-foreground", children: r.type }),
693
+ /* @__PURE__ */ jsx9("td", { className: "py-2 pe-4 text-foreground", children: r.sends }),
694
+ /* @__PURE__ */ jsx9("td", { className: "py-2 pe-4 text-foreground", children: r.delivered }),
695
+ /* @__PURE__ */ jsx9("td", { className: "py-2 pe-4 text-foreground", children: pct2(r.openRate) }),
696
+ /* @__PURE__ */ jsx9("td", { className: "py-2 text-foreground", children: pct2(r.clickRate) })
589
697
  ] }, r.type)) })
590
698
  ] });
591
699
  }
592
700
 
593
701
  // src/delivery-analytics-page.tsx
594
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
702
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
595
703
  var DEFAULT_FROM = "2026-06-01";
596
704
  var DEFAULT_TO = "2026-06-30";
597
705
  var CHANNELS = ["", "email", "inapp", "push", "sms"];
@@ -600,36 +708,36 @@ function DeliveryAnalyticsPage({
600
708
  organizationId,
601
709
  className
602
710
  }) {
603
- const [channel, setChannel] = useState3("");
604
- const [from, setFrom] = useState3(DEFAULT_FROM);
605
- const [to, setTo] = useState3(DEFAULT_TO);
711
+ const [channel, setChannel] = useState4("");
712
+ const [from, setFrom] = useState4(DEFAULT_FROM);
713
+ const [to, setTo] = useState4(DEFAULT_TO);
606
714
  const filters = { from, to, channel: channel || void 0, organizationId, basePath };
607
715
  const summary = useDeliveryAnalytics(filters);
608
716
  const funnel = useFunnelStats(filters);
609
717
  const types = useDeliveryTypes({ from, to, organizationId, basePath });
610
718
  const isLoading = summary.isLoading || funnel.isLoading || types.isLoading;
611
719
  const isError = summary.isError || funnel.isError || types.isError;
612
- return /* @__PURE__ */ jsxs7("main", { className: cn7("flex flex-col gap-6 p-4 sm:p-6", className), children: [
613
- /* @__PURE__ */ jsxs7("header", { className: "flex flex-col gap-1", children: [
614
- /* @__PURE__ */ jsx9("h1", { className: "text-xl font-semibold text-foreground", children: "Delivery Analytics" }),
615
- /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: "Cross-channel send, open, and click performance." })
720
+ return /* @__PURE__ */ jsxs8("main", { className: cn8("flex flex-col gap-6 p-4 sm:p-6", className), children: [
721
+ /* @__PURE__ */ jsxs8("header", { className: "flex flex-col gap-1", children: [
722
+ /* @__PURE__ */ jsx10("h1", { className: "text-xl font-semibold text-foreground", children: "Delivery Analytics" }),
723
+ /* @__PURE__ */ jsx10("p", { className: "text-sm text-muted-foreground", children: "Cross-channel send, open, and click performance." })
616
724
  ] }),
617
- /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-end gap-3", children: [
618
- /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1 text-sm", children: [
619
- /* @__PURE__ */ jsx9("span", { className: "font-medium text-foreground", children: "Channel" }),
620
- /* @__PURE__ */ jsx9(
725
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap items-end gap-3", children: [
726
+ /* @__PURE__ */ jsxs8("label", { className: "flex flex-col gap-1 text-sm", children: [
727
+ /* @__PURE__ */ jsx10("span", { className: "font-medium text-foreground", children: "Channel" }),
728
+ /* @__PURE__ */ jsx10(
621
729
  "select",
622
730
  {
623
731
  value: channel,
624
732
  onChange: (e) => setChannel(e.target.value),
625
733
  className: "rounded border border-border bg-background px-2 py-1.5 text-foreground",
626
- children: CHANNELS.map((c) => /* @__PURE__ */ jsx9("option", { value: c, children: c === "" ? "All channels" : c }, c || "all"))
734
+ children: CHANNELS.map((c) => /* @__PURE__ */ jsx10("option", { value: c, children: c === "" ? "All channels" : c }, c || "all"))
627
735
  }
628
736
  )
629
737
  ] }),
630
- /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1 text-sm", children: [
631
- /* @__PURE__ */ jsx9("span", { className: "font-medium text-foreground", children: "From" }),
632
- /* @__PURE__ */ jsx9(
738
+ /* @__PURE__ */ jsxs8("label", { className: "flex flex-col gap-1 text-sm", children: [
739
+ /* @__PURE__ */ jsx10("span", { className: "font-medium text-foreground", children: "From" }),
740
+ /* @__PURE__ */ jsx10(
633
741
  "input",
634
742
  {
635
743
  type: "date",
@@ -639,9 +747,9 @@ function DeliveryAnalyticsPage({
639
747
  }
640
748
  )
641
749
  ] }),
642
- /* @__PURE__ */ jsxs7("label", { className: "flex flex-col gap-1 text-sm", children: [
643
- /* @__PURE__ */ jsx9("span", { className: "font-medium text-foreground", children: "To" }),
644
- /* @__PURE__ */ jsx9(
750
+ /* @__PURE__ */ jsxs8("label", { className: "flex flex-col gap-1 text-sm", children: [
751
+ /* @__PURE__ */ jsx10("span", { className: "font-medium text-foreground", children: "To" }),
752
+ /* @__PURE__ */ jsx10(
645
753
  "input",
646
754
  {
647
755
  type: "date",
@@ -652,13 +760,13 @@ function DeliveryAnalyticsPage({
652
760
  )
653
761
  ] })
654
762
  ] }),
655
- isLoading ? /* @__PURE__ */ jsxs7("div", { role: "status", "aria-label": "Loading delivery analytics", className: "flex flex-col gap-3", children: [
656
- /* @__PURE__ */ jsx9("span", { className: "sr-only", children: "Loading delivery analytics" }),
657
- /* @__PURE__ */ jsx9("div", { "aria-hidden": "true", className: "h-24 animate-pulse rounded bg-muted" }),
658
- /* @__PURE__ */ jsx9("div", { "aria-hidden": "true", className: "h-72 animate-pulse rounded bg-muted" })
659
- ] }) : isError ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-start gap-3", children: [
660
- /* @__PURE__ */ jsx9("p", { className: "text-sm text-foreground", children: "Failed to load delivery analytics" }),
661
- /* @__PURE__ */ jsx9(
763
+ isLoading ? /* @__PURE__ */ jsxs8("div", { role: "status", "aria-label": "Loading delivery analytics", className: "flex flex-col gap-3", children: [
764
+ /* @__PURE__ */ jsx10("span", { className: "sr-only", children: "Loading delivery analytics" }),
765
+ /* @__PURE__ */ jsx10("div", { "aria-hidden": "true", className: "h-24 animate-pulse rounded bg-muted" }),
766
+ /* @__PURE__ */ jsx10("div", { "aria-hidden": "true", className: "h-72 animate-pulse rounded bg-muted" })
767
+ ] }) : isError ? /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-start gap-3", children: [
768
+ /* @__PURE__ */ jsx10("p", { className: "text-sm text-foreground", children: "Failed to load delivery analytics" }),
769
+ /* @__PURE__ */ jsx10(
662
770
  "button",
663
771
  {
664
772
  type: "button",
@@ -671,23 +779,23 @@ function DeliveryAnalyticsPage({
671
779
  children: "Try again"
672
780
  }
673
781
  )
674
- ] }) : (summary.data?.length ?? 0) === 0 ? /* @__PURE__ */ jsx9("p", { className: "rounded border border-border p-6 text-center text-sm text-muted-foreground", children: "No delivery data for the selected range" }) : /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-6", children: [
675
- funnel.data ? /* @__PURE__ */ jsx9(FunnelStats, { funnel: funnel.data }) : null,
676
- /* @__PURE__ */ jsxs7("section", { "aria-label": "Delivery trend", className: "rounded-lg border border-border p-4", children: [
677
- /* @__PURE__ */ jsx9("h2", { className: "mb-3 text-sm font-semibold text-foreground", children: "Trend" }),
678
- /* @__PURE__ */ jsx9(TrendChart, { data: summary.data ?? [] })
782
+ ] }) : (summary.data?.length ?? 0) === 0 ? /* @__PURE__ */ jsx10("p", { className: "rounded border border-border p-6 text-center text-sm text-muted-foreground", children: "No delivery data for the selected range" }) : /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-6", children: [
783
+ funnel.data ? /* @__PURE__ */ jsx10(FunnelStats, { funnel: funnel.data }) : null,
784
+ /* @__PURE__ */ jsxs8("section", { "aria-label": "Delivery trend", className: "rounded-lg border border-border p-4", children: [
785
+ /* @__PURE__ */ jsx10("h2", { className: "mb-3 text-sm font-semibold text-foreground", children: "Trend" }),
786
+ /* @__PURE__ */ jsx10(TrendChart, { data: summary.data ?? [] })
679
787
  ] }),
680
- /* @__PURE__ */ jsxs7("section", { "aria-label": "Delivery by type", className: "rounded-lg border border-border p-4", children: [
681
- /* @__PURE__ */ jsx9("h2", { className: "mb-3 text-sm font-semibold text-foreground", children: "By type" }),
682
- /* @__PURE__ */ jsx9(TypeTable, { rows: types.data ?? [] })
788
+ /* @__PURE__ */ jsxs8("section", { "aria-label": "Delivery by type", className: "rounded-lg border border-border p-4", children: [
789
+ /* @__PURE__ */ jsx10("h2", { className: "mb-3 text-sm font-semibold text-foreground", children: "By type" }),
790
+ /* @__PURE__ */ jsx10(TypeTable, { rows: types.data ?? [] })
683
791
  ] })
684
792
  ] })
685
793
  ] });
686
794
  }
687
795
 
688
796
  // src/template-status-badge.tsx
689
- import { cn as cn8 } from "@quanticjs/react-ui";
690
- import { jsx as jsx10 } from "react/jsx-runtime";
797
+ import { cn as cn9 } from "@quanticjs/react-ui";
798
+ import { jsx as jsx11 } from "react/jsx-runtime";
691
799
  var STATUS_STYLES = {
692
800
  draft: "bg-muted text-muted-foreground",
693
801
  published: "bg-primary text-primary-foreground",
@@ -698,10 +806,10 @@ function TemplateStatusBadge({
698
806
  className
699
807
  }) {
700
808
  const style = STATUS_STYLES[status] ?? "bg-muted text-muted-foreground";
701
- return /* @__PURE__ */ jsx10(
809
+ return /* @__PURE__ */ jsx11(
702
810
  "span",
703
811
  {
704
- className: cn8(
812
+ className: cn9(
705
813
  "inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium capitalize",
706
814
  style,
707
815
  className
@@ -712,32 +820,32 @@ function TemplateStatusBadge({
712
820
  }
713
821
 
714
822
  // src/template-list.tsx
715
- import { cn as cn9 } from "@quanticjs/react-ui";
823
+ import { cn as cn10 } from "@quanticjs/react-ui";
716
824
  import { useApiQuery as useApiQuery7 } from "@quanticjs/react-query";
717
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
825
+ import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
718
826
  function TemplateList({ basePath = "/api/templates", className }) {
719
827
  const { data, isLoading, isError, refetch } = useApiQuery7(
720
828
  ["templates", basePath],
721
829
  (client) => client.get(basePath)
722
830
  );
723
831
  if (isLoading) {
724
- return /* @__PURE__ */ jsxs8(
832
+ return /* @__PURE__ */ jsxs9(
725
833
  "div",
726
834
  {
727
835
  role: "status",
728
836
  "aria-label": "Loading templates",
729
- className: cn9("flex flex-col gap-2 p-4", className),
837
+ className: cn10("flex flex-col gap-2 p-4", className),
730
838
  children: [
731
- /* @__PURE__ */ jsx11("span", { className: "sr-only", children: "Loading templates" }),
732
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx11("div", { "aria-hidden": "true", className: "h-12 animate-pulse rounded bg-muted" }, i))
839
+ /* @__PURE__ */ jsx12("span", { className: "sr-only", children: "Loading templates" }),
840
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx12("div", { "aria-hidden": "true", className: "h-12 animate-pulse rounded bg-muted" }, i))
733
841
  ]
734
842
  }
735
843
  );
736
844
  }
737
845
  if (isError) {
738
- return /* @__PURE__ */ jsxs8("div", { className: cn9("flex flex-col items-start gap-3 p-4", className), children: [
739
- /* @__PURE__ */ jsx11("p", { className: "text-sm text-foreground", children: "Failed to load templates" }),
740
- /* @__PURE__ */ jsx11(
846
+ return /* @__PURE__ */ jsxs9("div", { className: cn10("flex flex-col items-start gap-3 p-4", className), children: [
847
+ /* @__PURE__ */ jsx12("p", { className: "text-sm text-foreground", children: "Failed to load templates" }),
848
+ /* @__PURE__ */ jsx12(
741
849
  "button",
742
850
  {
743
851
  type: "button",
@@ -750,29 +858,29 @@ function TemplateList({ basePath = "/api/templates", className }) {
750
858
  }
751
859
  const items = data ?? [];
752
860
  if (items.length === 0) {
753
- return /* @__PURE__ */ jsx11("div", { className: cn9("p-6 text-center text-sm text-muted-foreground", className), children: "No templates found" });
861
+ return /* @__PURE__ */ jsx12("div", { className: cn10("p-6 text-center text-sm text-muted-foreground", className), children: "No templates found" });
754
862
  }
755
- return /* @__PURE__ */ jsx11("section", { "aria-label": "Templates", className: cn9("flex flex-col", className), children: /* @__PURE__ */ jsxs8("table", { className: "w-full text-sm", children: [
756
- /* @__PURE__ */ jsx11("thead", { children: /* @__PURE__ */ jsxs8("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
757
- /* @__PURE__ */ jsx11("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Template" }),
758
- /* @__PURE__ */ jsx11("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
759
- /* @__PURE__ */ jsx11("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locales" }),
760
- /* @__PURE__ */ jsx11("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Versions" })
863
+ return /* @__PURE__ */ jsx12("section", { "aria-label": "Templates", className: cn10("flex flex-col", className), children: /* @__PURE__ */ jsxs9("table", { className: "w-full text-sm", children: [
864
+ /* @__PURE__ */ jsx12("thead", { children: /* @__PURE__ */ jsxs9("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
865
+ /* @__PURE__ */ jsx12("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Template" }),
866
+ /* @__PURE__ */ jsx12("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
867
+ /* @__PURE__ */ jsx12("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locales" }),
868
+ /* @__PURE__ */ jsx12("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Versions" })
761
869
  ] }) }),
762
- /* @__PURE__ */ jsx11("tbody", { children: items.map((item) => /* @__PURE__ */ jsxs8("tr", { className: "border-b border-border", children: [
763
- /* @__PURE__ */ jsx11("td", { className: "py-3 pe-4 font-medium text-foreground", children: item.templateId }),
764
- /* @__PURE__ */ jsx11("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx11(TemplateStatusBadge, { status: item.latestStatus }) }),
765
- /* @__PURE__ */ jsx11("td", { className: "px-4 py-3 text-muted-foreground", children: item.locales.join(", ") }),
766
- /* @__PURE__ */ jsx11("td", { className: "px-4 py-3 text-muted-foreground", children: item.versionCount })
870
+ /* @__PURE__ */ jsx12("tbody", { children: items.map((item) => /* @__PURE__ */ jsxs9("tr", { className: "border-b border-border", children: [
871
+ /* @__PURE__ */ jsx12("td", { className: "py-3 pe-4 font-medium text-foreground", children: item.templateId }),
872
+ /* @__PURE__ */ jsx12("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx12(TemplateStatusBadge, { status: item.latestStatus }) }),
873
+ /* @__PURE__ */ jsx12("td", { className: "px-4 py-3 text-muted-foreground", children: item.locales.join(", ") }),
874
+ /* @__PURE__ */ jsx12("td", { className: "px-4 py-3 text-muted-foreground", children: item.versionCount })
767
875
  ] }, item.templateId)) })
768
876
  ] }) });
769
877
  }
770
878
 
771
879
  // src/template-editor.tsx
772
- import { useState as useState4 } from "react";
773
- import { cn as cn10, useToast as useToast3 } from "@quanticjs/react-ui";
880
+ import { useState as useState5 } from "react";
881
+ import { cn as cn11, useToast as useToast3 } from "@quanticjs/react-ui";
774
882
  import { useApiMutation as useApiMutation3 } from "@quanticjs/react-query";
775
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
883
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
776
884
  var FIELD_DEFS = [
777
885
  { key: "subject", label: "Subject", multiline: false },
778
886
  { key: "heading", label: "Heading", multiline: false },
@@ -794,16 +902,16 @@ function TemplateEditor({
794
902
  className
795
903
  }) {
796
904
  const toast = useToast3();
797
- const [fields, setFields] = useState4({
905
+ const [fields, setFields] = useState5({
798
906
  subject: initialFields?.subject ?? "",
799
907
  heading: initialFields?.heading ?? "",
800
908
  body: initialFields?.body ?? "",
801
909
  cta: initialFields?.cta ?? "",
802
910
  html: initialFields?.html ?? ""
803
911
  });
804
- const [errors, setErrors] = useState4({});
805
- const [status, setStatus] = useState4(initialStatus);
806
- const [activeVersionId, setActiveVersionId] = useState4(versionId);
912
+ const [errors, setErrors] = useState5({});
913
+ const [status, setStatus] = useState5(initialStatus);
914
+ const [activeVersionId, setActiveVersionId] = useState5(versionId);
807
915
  const save = useApiMutation3(
808
916
  (client, payload) => client.put(`${basePath}/${templateId}`, payload),
809
917
  {
@@ -847,21 +955,21 @@ function TemplateEditor({
847
955
  if (!validate()) return;
848
956
  save.mutate(fields);
849
957
  };
850
- return /* @__PURE__ */ jsxs9("form", { onSubmit, className: cn10("flex flex-col gap-4", className), noValidate: true, children: [
851
- /* @__PURE__ */ jsxs9("header", { className: "flex items-center justify-between", children: [
852
- /* @__PURE__ */ jsxs9("h2", { className: "text-sm font-semibold text-foreground", children: [
958
+ return /* @__PURE__ */ jsxs10("form", { onSubmit, className: cn11("flex flex-col gap-4", className), noValidate: true, children: [
959
+ /* @__PURE__ */ jsxs10("header", { className: "flex items-center justify-between", children: [
960
+ /* @__PURE__ */ jsxs10("h2", { className: "text-sm font-semibold text-foreground", children: [
853
961
  "Edit template: ",
854
962
  templateId
855
963
  ] }),
856
- /* @__PURE__ */ jsx12(TemplateStatusBadge, { status })
964
+ /* @__PURE__ */ jsx13(TemplateStatusBadge, { status })
857
965
  ] }),
858
966
  FIELD_DEFS.map(({ key, label, multiline }) => {
859
967
  const fieldId = `template-${key}`;
860
968
  const errorId = `${fieldId}-error`;
861
969
  const error = errors[key];
862
- return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1", children: [
863
- /* @__PURE__ */ jsx12("label", { htmlFor: fieldId, className: "text-sm font-medium text-foreground", children: label }),
864
- multiline ? /* @__PURE__ */ jsx12(
970
+ return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-1", children: [
971
+ /* @__PURE__ */ jsx13("label", { htmlFor: fieldId, className: "text-sm font-medium text-foreground", children: label }),
972
+ multiline ? /* @__PURE__ */ jsx13(
865
973
  "textarea",
866
974
  {
867
975
  id: fieldId,
@@ -872,7 +980,7 @@ function TemplateEditor({
872
980
  onChange: (e) => setFields((prev) => ({ ...prev, [key]: e.target.value })),
873
981
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
874
982
  }
875
- ) : /* @__PURE__ */ jsx12(
983
+ ) : /* @__PURE__ */ jsx13(
876
984
  "input",
877
985
  {
878
986
  id: fieldId,
@@ -884,11 +992,11 @@ function TemplateEditor({
884
992
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
885
993
  }
886
994
  ),
887
- error && /* @__PURE__ */ jsx12("p", { id: errorId, className: "text-xs text-destructive", children: error })
995
+ error && /* @__PURE__ */ jsx13("p", { id: errorId, className: "text-xs text-destructive", children: error })
888
996
  ] }, key);
889
997
  }),
890
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
891
- /* @__PURE__ */ jsx12(
998
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3", children: [
999
+ /* @__PURE__ */ jsx13(
892
1000
  "button",
893
1001
  {
894
1002
  type: "submit",
@@ -897,7 +1005,7 @@ function TemplateEditor({
897
1005
  children: save.isPending ? "Saving\u2026" : "Save draft"
898
1006
  }
899
1007
  ),
900
- /* @__PURE__ */ jsx12(
1008
+ /* @__PURE__ */ jsx13(
901
1009
  "button",
902
1010
  {
903
1011
  type: "button",
@@ -912,10 +1020,10 @@ function TemplateEditor({
912
1020
  }
913
1021
 
914
1022
  // src/template-preview-pane.tsx
915
- import { useEffect as useEffect4 } from "react";
916
- import { cn as cn11 } from "@quanticjs/react-ui";
1023
+ import { useEffect as useEffect5 } from "react";
1024
+ import { cn as cn12 } from "@quanticjs/react-ui";
917
1025
  import { useApiMutation as useApiMutation4 } from "@quanticjs/react-query";
918
- import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1026
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
919
1027
  function TemplatePreviewPane({
920
1028
  templateId,
921
1029
  versionId,
@@ -927,28 +1035,28 @@ function TemplatePreviewPane({
927
1035
  (client, payload) => client.post(`${basePath}/${templateId}/preview`, payload)
928
1036
  );
929
1037
  const { mutate, data, isPending, isError } = preview;
930
- useEffect4(() => {
1038
+ useEffect5(() => {
931
1039
  mutate({ versionId, vars });
932
1040
  }, [templateId, versionId]);
933
1041
  if (isPending) {
934
- return /* @__PURE__ */ jsxs10(
1042
+ return /* @__PURE__ */ jsxs11(
935
1043
  "div",
936
1044
  {
937
1045
  role: "status",
938
1046
  "aria-label": "Loading preview",
939
- className: cn11("flex flex-col gap-2 p-4", className),
1047
+ className: cn12("flex flex-col gap-2 p-4", className),
940
1048
  children: [
941
- /* @__PURE__ */ jsx13("span", { className: "sr-only", children: "Loading preview" }),
942
- /* @__PURE__ */ jsx13("div", { "aria-hidden": "true", className: "h-6 w-1/2 animate-pulse rounded bg-muted" }),
943
- /* @__PURE__ */ jsx13("div", { "aria-hidden": "true", className: "h-40 animate-pulse rounded bg-muted" })
1049
+ /* @__PURE__ */ jsx14("span", { className: "sr-only", children: "Loading preview" }),
1050
+ /* @__PURE__ */ jsx14("div", { "aria-hidden": "true", className: "h-6 w-1/2 animate-pulse rounded bg-muted" }),
1051
+ /* @__PURE__ */ jsx14("div", { "aria-hidden": "true", className: "h-40 animate-pulse rounded bg-muted" })
944
1052
  ]
945
1053
  }
946
1054
  );
947
1055
  }
948
1056
  if (isError || !data) {
949
- return /* @__PURE__ */ jsxs10("div", { className: cn11("flex flex-col items-start gap-3 p-4", className), children: [
950
- /* @__PURE__ */ jsx13("p", { className: "text-sm text-foreground", children: "Failed to load preview" }),
951
- /* @__PURE__ */ jsx13(
1057
+ return /* @__PURE__ */ jsxs11("div", { className: cn12("flex flex-col items-start gap-3 p-4", className), children: [
1058
+ /* @__PURE__ */ jsx14("p", { className: "text-sm text-foreground", children: "Failed to load preview" }),
1059
+ /* @__PURE__ */ jsx14(
952
1060
  "button",
953
1061
  {
954
1062
  type: "button",
@@ -959,9 +1067,9 @@ function TemplatePreviewPane({
959
1067
  )
960
1068
  ] });
961
1069
  }
962
- return /* @__PURE__ */ jsxs10("section", { "aria-label": "Template preview", className: cn11("flex flex-col gap-4", className), children: [
963
- /* @__PURE__ */ jsx13("h2", { className: "text-sm font-semibold text-foreground", children: data.subject }),
964
- /* @__PURE__ */ jsx13(
1070
+ return /* @__PURE__ */ jsxs11("section", { "aria-label": "Template preview", className: cn12("flex flex-col gap-4", className), children: [
1071
+ /* @__PURE__ */ jsx14("h2", { className: "text-sm font-semibold text-foreground", children: data.subject }),
1072
+ /* @__PURE__ */ jsx14(
965
1073
  "iframe",
966
1074
  {
967
1075
  title: "Email preview",
@@ -970,17 +1078,17 @@ function TemplatePreviewPane({
970
1078
  className: "h-96 w-full rounded-md border border-border bg-background"
971
1079
  }
972
1080
  ),
973
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-1", children: [
974
- /* @__PURE__ */ jsx13("h3", { className: "text-xs font-medium text-muted-foreground", children: "Plain text" }),
975
- /* @__PURE__ */ jsx13("pre", { className: "overflow-auto whitespace-pre-wrap rounded-md border border-border bg-muted p-3 text-xs text-foreground", children: data.text })
1081
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1", children: [
1082
+ /* @__PURE__ */ jsx14("h3", { className: "text-xs font-medium text-muted-foreground", children: "Plain text" }),
1083
+ /* @__PURE__ */ jsx14("pre", { className: "overflow-auto whitespace-pre-wrap rounded-md border border-border bg-muted p-3 text-xs text-foreground", children: data.text })
976
1084
  ] })
977
1085
  ] });
978
1086
  }
979
1087
 
980
1088
  // src/template-version-history.tsx
981
- import { cn as cn12, useToast as useToast4 } from "@quanticjs/react-ui";
1089
+ import { cn as cn13, useToast as useToast4 } from "@quanticjs/react-ui";
982
1090
  import { useApiQuery as useApiQuery8, useApiMutation as useApiMutation5 } from "@quanticjs/react-query";
983
- import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1091
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
984
1092
  function TemplateVersionHistory({
985
1093
  templateId,
986
1094
  basePath = "/api/templates",
@@ -1005,23 +1113,23 @@ function TemplateVersionHistory({
1005
1113
  }
1006
1114
  );
1007
1115
  if (isLoading) {
1008
- return /* @__PURE__ */ jsxs11(
1116
+ return /* @__PURE__ */ jsxs12(
1009
1117
  "div",
1010
1118
  {
1011
1119
  role: "status",
1012
1120
  "aria-label": "Loading versions",
1013
- className: cn12("flex flex-col gap-2 p-4", className),
1121
+ className: cn13("flex flex-col gap-2 p-4", className),
1014
1122
  children: [
1015
- /* @__PURE__ */ jsx14("span", { className: "sr-only", children: "Loading versions" }),
1016
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx14("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1123
+ /* @__PURE__ */ jsx15("span", { className: "sr-only", children: "Loading versions" }),
1124
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx15("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1017
1125
  ]
1018
1126
  }
1019
1127
  );
1020
1128
  }
1021
1129
  if (isError) {
1022
- return /* @__PURE__ */ jsxs11("div", { className: cn12("flex flex-col items-start gap-3 p-4", className), children: [
1023
- /* @__PURE__ */ jsx14("p", { className: "text-sm text-foreground", children: "Failed to load versions" }),
1024
- /* @__PURE__ */ jsx14(
1130
+ return /* @__PURE__ */ jsxs12("div", { className: cn13("flex flex-col items-start gap-3 p-4", className), children: [
1131
+ /* @__PURE__ */ jsx15("p", { className: "text-sm text-foreground", children: "Failed to load versions" }),
1132
+ /* @__PURE__ */ jsx15(
1025
1133
  "button",
1026
1134
  {
1027
1135
  type: "button",
@@ -1034,25 +1142,25 @@ function TemplateVersionHistory({
1034
1142
  }
1035
1143
  const versions = data ?? [];
1036
1144
  if (versions.length === 0) {
1037
- return /* @__PURE__ */ jsx14("div", { className: cn12("p-6 text-center text-sm text-muted-foreground", className), children: "No versions" });
1145
+ return /* @__PURE__ */ jsx15("div", { className: cn13("p-6 text-center text-sm text-muted-foreground", className), children: "No versions" });
1038
1146
  }
1039
- return /* @__PURE__ */ jsx14("section", { "aria-label": "Version history", className: cn12("flex flex-col", className), children: /* @__PURE__ */ jsxs11("table", { className: "w-full text-sm", children: [
1040
- /* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsxs11("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1041
- /* @__PURE__ */ jsx14("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Version" }),
1042
- /* @__PURE__ */ jsx14("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1043
- /* @__PURE__ */ jsx14("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Author" }),
1044
- /* @__PURE__ */ jsx14("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Date" }),
1045
- /* @__PURE__ */ jsx14("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx14("span", { className: "sr-only", children: "Actions" }) })
1147
+ return /* @__PURE__ */ jsx15("section", { "aria-label": "Version history", className: cn13("flex flex-col", className), children: /* @__PURE__ */ jsxs12("table", { className: "w-full text-sm", children: [
1148
+ /* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsxs12("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1149
+ /* @__PURE__ */ jsx15("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Version" }),
1150
+ /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1151
+ /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Author" }),
1152
+ /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Date" }),
1153
+ /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx15("span", { className: "sr-only", children: "Actions" }) })
1046
1154
  ] }) }),
1047
- /* @__PURE__ */ jsx14("tbody", { children: versions.map((version) => /* @__PURE__ */ jsxs11("tr", { className: "border-b border-border", children: [
1048
- /* @__PURE__ */ jsxs11("td", { className: "py-3 pe-4 font-medium text-foreground", children: [
1155
+ /* @__PURE__ */ jsx15("tbody", { children: versions.map((version) => /* @__PURE__ */ jsxs12("tr", { className: "border-b border-border", children: [
1156
+ /* @__PURE__ */ jsxs12("td", { className: "py-3 pe-4 font-medium text-foreground", children: [
1049
1157
  "v",
1050
1158
  version.versionNumber
1051
1159
  ] }),
1052
- /* @__PURE__ */ jsx14("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx14(TemplateStatusBadge, { status: version.status }) }),
1053
- /* @__PURE__ */ jsx14("td", { className: "px-4 py-3 text-muted-foreground", children: version.createdBy }),
1054
- /* @__PURE__ */ jsx14("td", { className: "px-4 py-3 text-muted-foreground", children: version.createdAt }),
1055
- /* @__PURE__ */ jsx14("td", { className: "px-4 py-3 text-end", children: canRollback && version.status === "archived" && /* @__PURE__ */ jsx14(
1160
+ /* @__PURE__ */ jsx15("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx15(TemplateStatusBadge, { status: version.status }) }),
1161
+ /* @__PURE__ */ jsx15("td", { className: "px-4 py-3 text-muted-foreground", children: version.createdBy }),
1162
+ /* @__PURE__ */ jsx15("td", { className: "px-4 py-3 text-muted-foreground", children: version.createdAt }),
1163
+ /* @__PURE__ */ jsx15("td", { className: "px-4 py-3 text-end", children: canRollback && version.status === "archived" && /* @__PURE__ */ jsx15(
1056
1164
  "button",
1057
1165
  {
1058
1166
  type: "button",
@@ -1067,39 +1175,39 @@ function TemplateVersionHistory({
1067
1175
  }
1068
1176
 
1069
1177
  // src/delivery-log-viewer.tsx
1070
- import { useState as useState5 } from "react";
1071
- import { cn as cn13 } from "@quanticjs/react-ui";
1178
+ import { useState as useState6 } from "react";
1179
+ import { cn as cn14 } from "@quanticjs/react-ui";
1072
1180
  import { useApiQuery as useApiQuery9 } from "@quanticjs/react-query";
1073
- import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1181
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1074
1182
  var LIMIT = 20;
1075
1183
  function DeliveryLogViewer({
1076
1184
  templateId,
1077
1185
  basePath = "/api/templates",
1078
1186
  className
1079
1187
  }) {
1080
- const [page, setPage] = useState5(1);
1188
+ const [page, setPage] = useState6(1);
1081
1189
  const { data, isLoading, isError, refetch } = useApiQuery9(
1082
1190
  ["templates", templateId, "delivery-logs", page],
1083
1191
  (client) => client.get(`${basePath}/${templateId}/delivery-logs?page=${page}&limit=${LIMIT}`)
1084
1192
  );
1085
1193
  if (isLoading) {
1086
- return /* @__PURE__ */ jsxs12(
1194
+ return /* @__PURE__ */ jsxs13(
1087
1195
  "div",
1088
1196
  {
1089
1197
  role: "status",
1090
1198
  "aria-label": "Loading delivery logs",
1091
- className: cn13("flex flex-col gap-2 p-4", className),
1199
+ className: cn14("flex flex-col gap-2 p-4", className),
1092
1200
  children: [
1093
- /* @__PURE__ */ jsx15("span", { className: "sr-only", children: "Loading delivery logs" }),
1094
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx15("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1201
+ /* @__PURE__ */ jsx16("span", { className: "sr-only", children: "Loading delivery logs" }),
1202
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx16("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1095
1203
  ]
1096
1204
  }
1097
1205
  );
1098
1206
  }
1099
1207
  if (isError) {
1100
- return /* @__PURE__ */ jsxs12("div", { className: cn13("flex flex-col items-start gap-3 p-4", className), children: [
1101
- /* @__PURE__ */ jsx15("p", { className: "text-sm text-foreground", children: "Failed to load delivery logs" }),
1102
- /* @__PURE__ */ jsx15(
1208
+ return /* @__PURE__ */ jsxs13("div", { className: cn14("flex flex-col items-start gap-3 p-4", className), children: [
1209
+ /* @__PURE__ */ jsx16("p", { className: "text-sm text-foreground", children: "Failed to load delivery logs" }),
1210
+ /* @__PURE__ */ jsx16(
1103
1211
  "button",
1104
1212
  {
1105
1213
  type: "button",
@@ -1113,25 +1221,25 @@ function DeliveryLogViewer({
1113
1221
  const rows = data?.items ?? [];
1114
1222
  const totalPages = data?.totalPages ?? 1;
1115
1223
  if (rows.length === 0) {
1116
- return /* @__PURE__ */ jsx15("div", { className: cn13("p-6 text-center text-sm text-muted-foreground", className), children: "No delivery logs" });
1224
+ return /* @__PURE__ */ jsx16("div", { className: cn14("p-6 text-center text-sm text-muted-foreground", className), children: "No delivery logs" });
1117
1225
  }
1118
- return /* @__PURE__ */ jsxs12("section", { "aria-label": "Delivery logs", className: cn13("flex flex-col gap-3", className), children: [
1119
- /* @__PURE__ */ jsxs12("table", { className: "w-full text-sm", children: [
1120
- /* @__PURE__ */ jsx15("thead", { children: /* @__PURE__ */ jsxs12("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1121
- /* @__PURE__ */ jsx15("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Recipient" }),
1122
- /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1123
- /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
1124
- /* @__PURE__ */ jsx15("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Last error" })
1226
+ return /* @__PURE__ */ jsxs13("section", { "aria-label": "Delivery logs", className: cn14("flex flex-col gap-3", className), children: [
1227
+ /* @__PURE__ */ jsxs13("table", { className: "w-full text-sm", children: [
1228
+ /* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs13("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1229
+ /* @__PURE__ */ jsx16("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Recipient" }),
1230
+ /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1231
+ /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
1232
+ /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Last error" })
1125
1233
  ] }) }),
1126
- /* @__PURE__ */ jsx15("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs12("tr", { className: "border-b border-border", children: [
1127
- /* @__PURE__ */ jsx15("td", { className: "py-3 pe-4 text-foreground", children: row.recipientEmail }),
1128
- /* @__PURE__ */ jsx15("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx15(TemplateStatusBadge, { status: row.status }) }),
1129
- /* @__PURE__ */ jsx15("td", { className: "px-4 py-3 text-muted-foreground", children: row.attempts }),
1130
- /* @__PURE__ */ jsx15("td", { className: "px-4 py-3 text-muted-foreground", children: row.lastError ?? "\u2014" })
1234
+ /* @__PURE__ */ jsx16("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs13("tr", { className: "border-b border-border", children: [
1235
+ /* @__PURE__ */ jsx16("td", { className: "py-3 pe-4 text-foreground", children: row.recipientEmail }),
1236
+ /* @__PURE__ */ jsx16("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx16(TemplateStatusBadge, { status: row.status }) }),
1237
+ /* @__PURE__ */ jsx16("td", { className: "px-4 py-3 text-muted-foreground", children: row.attempts }),
1238
+ /* @__PURE__ */ jsx16("td", { className: "px-4 py-3 text-muted-foreground", children: row.lastError ?? "\u2014" })
1131
1239
  ] }, row.id)) })
1132
1240
  ] }),
1133
- /* @__PURE__ */ jsxs12("nav", { "aria-label": "Delivery log pagination", className: "flex items-center justify-between", children: [
1134
- /* @__PURE__ */ jsx15(
1241
+ /* @__PURE__ */ jsxs13("nav", { "aria-label": "Delivery log pagination", className: "flex items-center justify-between", children: [
1242
+ /* @__PURE__ */ jsx16(
1135
1243
  "button",
1136
1244
  {
1137
1245
  type: "button",
@@ -1141,13 +1249,13 @@ function DeliveryLogViewer({
1141
1249
  children: "Previous"
1142
1250
  }
1143
1251
  ),
1144
- /* @__PURE__ */ jsxs12("span", { className: "text-xs text-muted-foreground", children: [
1252
+ /* @__PURE__ */ jsxs13("span", { className: "text-xs text-muted-foreground", children: [
1145
1253
  "Page ",
1146
1254
  page,
1147
1255
  " of ",
1148
1256
  totalPages
1149
1257
  ] }),
1150
- /* @__PURE__ */ jsx15(
1258
+ /* @__PURE__ */ jsx16(
1151
1259
  "button",
1152
1260
  {
1153
1261
  type: "button",
@@ -1173,9 +1281,9 @@ function useBroadcasts({ page = 1, status, basePath = "/api" } = {}) {
1173
1281
  }
1174
1282
 
1175
1283
  // src/broadcast-list.tsx
1176
- import { useState as useState6 } from "react";
1177
- import { cn as cn14, formatDateTime, StatusBadge } from "@quanticjs/react-ui";
1178
- import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1284
+ import { useState as useState7 } from "react";
1285
+ import { cn as cn15, formatDateTime, StatusBadge } from "@quanticjs/react-ui";
1286
+ import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
1179
1287
  function statusVariant(status) {
1180
1288
  switch (status) {
1181
1289
  case "completed":
@@ -1200,26 +1308,26 @@ function BroadcastList({
1200
1308
  onSelect,
1201
1309
  className
1202
1310
  }) {
1203
- const [page, setPage] = useState6(1);
1311
+ const [page, setPage] = useState7(1);
1204
1312
  const { data, isLoading, isError, refetch } = useBroadcasts({ page, status, basePath });
1205
1313
  if (isLoading) {
1206
- return /* @__PURE__ */ jsxs13(
1314
+ return /* @__PURE__ */ jsxs14(
1207
1315
  "div",
1208
1316
  {
1209
1317
  role: "status",
1210
1318
  "aria-label": "Loading broadcasts",
1211
- className: cn14("flex flex-col gap-2 p-4", className),
1319
+ className: cn15("flex flex-col gap-2 p-4", className),
1212
1320
  children: [
1213
- /* @__PURE__ */ jsx16("span", { className: "sr-only", children: "Loading broadcasts" }),
1214
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx16("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1321
+ /* @__PURE__ */ jsx17("span", { className: "sr-only", children: "Loading broadcasts" }),
1322
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx17("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1215
1323
  ]
1216
1324
  }
1217
1325
  );
1218
1326
  }
1219
1327
  if (isError) {
1220
- return /* @__PURE__ */ jsxs13("div", { className: cn14("flex flex-col items-start gap-3 p-4", className), children: [
1221
- /* @__PURE__ */ jsx16("p", { className: "text-sm text-foreground", children: "Failed to load broadcasts" }),
1222
- /* @__PURE__ */ jsx16(
1328
+ return /* @__PURE__ */ jsxs14("div", { className: cn15("flex flex-col items-start gap-3 p-4", className), children: [
1329
+ /* @__PURE__ */ jsx17("p", { className: "text-sm text-foreground", children: "Failed to load broadcasts" }),
1330
+ /* @__PURE__ */ jsx17(
1223
1331
  "button",
1224
1332
  {
1225
1333
  type: "button",
@@ -1233,9 +1341,9 @@ function BroadcastList({
1233
1341
  const rows = data?.items ?? [];
1234
1342
  const totalPages = data?.totalPages ?? 1;
1235
1343
  if (rows.length === 0) {
1236
- return /* @__PURE__ */ jsx16("div", { className: cn14("p-6 text-center text-sm text-muted-foreground", className), children: "No broadcasts" });
1344
+ return /* @__PURE__ */ jsx17("div", { className: cn15("p-6 text-center text-sm text-muted-foreground", className), children: "No broadcasts" });
1237
1345
  }
1238
- const renderTemplateCell = (row) => onSelect ? /* @__PURE__ */ jsx16(
1346
+ const renderTemplateCell = (row) => onSelect ? /* @__PURE__ */ jsx17(
1239
1347
  "button",
1240
1348
  {
1241
1349
  type: "button",
@@ -1243,34 +1351,34 @@ function BroadcastList({
1243
1351
  className: "rounded text-start font-medium text-primary hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
1244
1352
  children: row.templateId
1245
1353
  }
1246
- ) : /* @__PURE__ */ jsx16("span", { className: "text-foreground", children: row.templateId });
1247
- return /* @__PURE__ */ jsxs13("section", { "aria-label": "Broadcasts", className: cn14("flex flex-col gap-3", className), children: [
1248
- /* @__PURE__ */ jsxs13("table", { className: "w-full text-sm", children: [
1249
- /* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs13("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1250
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Template" }),
1251
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1252
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Channels" }),
1253
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Sent / Failed / Skipped" }),
1254
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created by" }),
1255
- /* @__PURE__ */ jsx16("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
1354
+ ) : /* @__PURE__ */ jsx17("span", { className: "text-foreground", children: row.templateId });
1355
+ return /* @__PURE__ */ jsxs14("section", { "aria-label": "Broadcasts", className: cn15("flex flex-col gap-3", className), children: [
1356
+ /* @__PURE__ */ jsxs14("table", { className: "w-full text-sm", children: [
1357
+ /* @__PURE__ */ jsx17("thead", { children: /* @__PURE__ */ jsxs14("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1358
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Template" }),
1359
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
1360
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Channels" }),
1361
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Sent / Failed / Skipped" }),
1362
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created by" }),
1363
+ /* @__PURE__ */ jsx17("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
1256
1364
  ] }) }),
1257
- /* @__PURE__ */ jsx16("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs13("tr", { className: "border-b border-border", children: [
1258
- /* @__PURE__ */ jsx16("td", { className: "py-3 pe-4", children: renderTemplateCell(row) }),
1259
- /* @__PURE__ */ jsx16("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx16(StatusBadge, { variant: statusVariant(row.status), children: row.status }) }),
1260
- /* @__PURE__ */ jsx16("td", { className: "px-4 py-3 text-muted-foreground", children: row.channels.length > 0 ? row.channels.join(", ") : "\u2014" }),
1261
- /* @__PURE__ */ jsxs13("td", { className: "px-4 py-3 text-muted-foreground", children: [
1365
+ /* @__PURE__ */ jsx17("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs14("tr", { className: "border-b border-border", children: [
1366
+ /* @__PURE__ */ jsx17("td", { className: "py-3 pe-4", children: renderTemplateCell(row) }),
1367
+ /* @__PURE__ */ jsx17("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx17(StatusBadge, { variant: statusVariant(row.status), children: row.status }) }),
1368
+ /* @__PURE__ */ jsx17("td", { className: "px-4 py-3 text-muted-foreground", children: row.channels.length > 0 ? row.channels.join(", ") : "\u2014" }),
1369
+ /* @__PURE__ */ jsxs14("td", { className: "px-4 py-3 text-muted-foreground", children: [
1262
1370
  row.sentCount,
1263
1371
  " / ",
1264
1372
  row.failedCount,
1265
1373
  " / ",
1266
1374
  row.skippedCount
1267
1375
  ] }),
1268
- /* @__PURE__ */ jsx16("td", { className: "px-4 py-3 text-muted-foreground", children: row.createdBy }),
1269
- /* @__PURE__ */ jsx16("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime(row.createdAt) })
1376
+ /* @__PURE__ */ jsx17("td", { className: "px-4 py-3 text-muted-foreground", children: row.createdBy }),
1377
+ /* @__PURE__ */ jsx17("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime(row.createdAt) })
1270
1378
  ] }, row.id)) })
1271
1379
  ] }),
1272
- /* @__PURE__ */ jsxs13("nav", { "aria-label": "Broadcast pagination", className: "flex items-center justify-between", children: [
1273
- /* @__PURE__ */ jsx16(
1380
+ /* @__PURE__ */ jsxs14("nav", { "aria-label": "Broadcast pagination", className: "flex items-center justify-between", children: [
1381
+ /* @__PURE__ */ jsx17(
1274
1382
  "button",
1275
1383
  {
1276
1384
  type: "button",
@@ -1280,13 +1388,13 @@ function BroadcastList({
1280
1388
  children: "Previous"
1281
1389
  }
1282
1390
  ),
1283
- /* @__PURE__ */ jsxs13("span", { className: "text-xs text-muted-foreground", children: [
1391
+ /* @__PURE__ */ jsxs14("span", { className: "text-xs text-muted-foreground", children: [
1284
1392
  "Page ",
1285
1393
  page,
1286
1394
  " of ",
1287
1395
  totalPages
1288
1396
  ] }),
1289
- /* @__PURE__ */ jsx16(
1397
+ /* @__PURE__ */ jsx17(
1290
1398
  "button",
1291
1399
  {
1292
1400
  type: "button",
@@ -1301,9 +1409,9 @@ function BroadcastList({
1301
1409
  }
1302
1410
 
1303
1411
  // src/broadcast-progress.tsx
1304
- import { cn as cn15, useToast as useToast5, StatusBadge as StatusBadge2 } from "@quanticjs/react-ui";
1412
+ import { cn as cn16, useToast as useToast5, StatusBadge as StatusBadge2 } from "@quanticjs/react-ui";
1305
1413
  import { useApiQuery as useApiQuery11, useApiMutation as useApiMutation6 } from "@quanticjs/react-query";
1306
- import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
1414
+ import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
1307
1415
  var TERMINAL_STATUSES = ["completed", "completed_with_errors", "failed", "cancelled"];
1308
1416
  function isTerminalStatus(status) {
1309
1417
  return status !== void 0 && TERMINAL_STATUSES.includes(status);
@@ -1350,23 +1458,23 @@ function BroadcastProgress({
1350
1458
  }
1351
1459
  );
1352
1460
  if (isLoading) {
1353
- return /* @__PURE__ */ jsxs14(
1461
+ return /* @__PURE__ */ jsxs15(
1354
1462
  "div",
1355
1463
  {
1356
1464
  role: "status",
1357
1465
  "aria-label": "Loading broadcast",
1358
- className: cn15("flex flex-col gap-2 p-4", className),
1466
+ className: cn16("flex flex-col gap-2 p-4", className),
1359
1467
  children: [
1360
- /* @__PURE__ */ jsx17("span", { className: "sr-only", children: "Loading broadcast" }),
1361
- [0, 1].map((i) => /* @__PURE__ */ jsx17("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1468
+ /* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Loading broadcast" }),
1469
+ [0, 1].map((i) => /* @__PURE__ */ jsx18("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1362
1470
  ]
1363
1471
  }
1364
1472
  );
1365
1473
  }
1366
1474
  if (isError) {
1367
- return /* @__PURE__ */ jsxs14("div", { className: cn15("flex flex-col items-start gap-3 p-4", className), children: [
1368
- /* @__PURE__ */ jsx17("p", { className: "text-sm text-foreground", children: "Failed to load broadcast" }),
1369
- /* @__PURE__ */ jsx17(
1475
+ return /* @__PURE__ */ jsxs15("div", { className: cn16("flex flex-col items-start gap-3 p-4", className), children: [
1476
+ /* @__PURE__ */ jsx18("p", { className: "text-sm text-foreground", children: "Failed to load broadcast" }),
1477
+ /* @__PURE__ */ jsx18(
1370
1478
  "button",
1371
1479
  {
1372
1480
  type: "button",
@@ -1378,21 +1486,21 @@ function BroadcastProgress({
1378
1486
  ] });
1379
1487
  }
1380
1488
  if (!data) {
1381
- return /* @__PURE__ */ jsx17("div", { className: cn15("p-6 text-center text-sm text-muted-foreground", className), children: "No broadcast" });
1489
+ return /* @__PURE__ */ jsx18("div", { className: cn16("p-6 text-center text-sm text-muted-foreground", className), children: "No broadcast" });
1382
1490
  }
1383
1491
  const total = data.totalRecipients;
1384
1492
  const processed = data.sentCount + data.failedCount + data.skippedCount;
1385
1493
  const pct3 = total > 0 ? Math.min(100, Math.round(processed / total * 100)) : 0;
1386
1494
  const terminal = isTerminalStatus(data.status);
1387
- return /* @__PURE__ */ jsxs14("section", { "aria-label": "Broadcast progress", className: cn15("flex flex-col gap-4 p-4", className), children: [
1388
- /* @__PURE__ */ jsxs14("header", { className: "flex items-center justify-between", children: [
1389
- /* @__PURE__ */ jsxs14("h2", { className: "text-sm font-semibold text-foreground", children: [
1495
+ return /* @__PURE__ */ jsxs15("section", { "aria-label": "Broadcast progress", className: cn16("flex flex-col gap-4 p-4", className), children: [
1496
+ /* @__PURE__ */ jsxs15("header", { className: "flex items-center justify-between", children: [
1497
+ /* @__PURE__ */ jsxs15("h2", { className: "text-sm font-semibold text-foreground", children: [
1390
1498
  "Broadcast ",
1391
1499
  data.templateId
1392
1500
  ] }),
1393
- /* @__PURE__ */ jsx17(StatusBadge2, { variant: statusVariant2(data.status), appearance: "solid", children: data.status })
1501
+ /* @__PURE__ */ jsx18(StatusBadge2, { variant: statusVariant2(data.status), appearance: "solid", children: data.status })
1394
1502
  ] }),
1395
- /* @__PURE__ */ jsx17(
1503
+ /* @__PURE__ */ jsx18(
1396
1504
  "div",
1397
1505
  {
1398
1506
  role: "progressbar",
@@ -1401,10 +1509,10 @@ function BroadcastProgress({
1401
1509
  "aria-valuemax": 100,
1402
1510
  "aria-label": "Broadcast completion",
1403
1511
  className: "h-2 w-full overflow-hidden rounded-full bg-muted",
1404
- children: /* @__PURE__ */ jsx17("div", { className: "h-full rounded-full bg-primary", style: { width: `${pct3}%` } })
1512
+ children: /* @__PURE__ */ jsx18("div", { className: "h-full rounded-full bg-primary", style: { width: `${pct3}%` } })
1405
1513
  }
1406
1514
  ),
1407
- /* @__PURE__ */ jsxs14("p", { className: "text-xs text-muted-foreground", children: [
1515
+ /* @__PURE__ */ jsxs15("p", { className: "text-xs text-muted-foreground", children: [
1408
1516
  processed,
1409
1517
  " of ",
1410
1518
  total,
@@ -1412,25 +1520,25 @@ function BroadcastProgress({
1412
1520
  pct3,
1413
1521
  "%)"
1414
1522
  ] }),
1415
- /* @__PURE__ */ jsxs14("dl", { className: "grid grid-cols-2 gap-3 text-sm sm:grid-cols-4", children: [
1416
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1417
- /* @__PURE__ */ jsx17("dt", { className: "text-xs text-muted-foreground", children: "Sent" }),
1418
- /* @__PURE__ */ jsx17("dd", { className: "text-foreground", children: data.sentCount })
1523
+ /* @__PURE__ */ jsxs15("dl", { className: "grid grid-cols-2 gap-3 text-sm sm:grid-cols-4", children: [
1524
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1525
+ /* @__PURE__ */ jsx18("dt", { className: "text-xs text-muted-foreground", children: "Sent" }),
1526
+ /* @__PURE__ */ jsx18("dd", { className: "text-foreground", children: data.sentCount })
1419
1527
  ] }),
1420
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1421
- /* @__PURE__ */ jsx17("dt", { className: "text-xs text-muted-foreground", children: "Failed" }),
1422
- /* @__PURE__ */ jsx17("dd", { className: "text-foreground", children: data.failedCount })
1528
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1529
+ /* @__PURE__ */ jsx18("dt", { className: "text-xs text-muted-foreground", children: "Failed" }),
1530
+ /* @__PURE__ */ jsx18("dd", { className: "text-foreground", children: data.failedCount })
1423
1531
  ] }),
1424
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1425
- /* @__PURE__ */ jsx17("dt", { className: "text-xs text-muted-foreground", children: "Skipped" }),
1426
- /* @__PURE__ */ jsx17("dd", { className: "text-foreground", children: data.skippedCount })
1532
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1533
+ /* @__PURE__ */ jsx18("dt", { className: "text-xs text-muted-foreground", children: "Skipped" }),
1534
+ /* @__PURE__ */ jsx18("dd", { className: "text-foreground", children: data.skippedCount })
1427
1535
  ] }),
1428
- /* @__PURE__ */ jsxs14("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1429
- /* @__PURE__ */ jsx17("dt", { className: "text-xs text-muted-foreground", children: "Total" }),
1430
- /* @__PURE__ */ jsx17("dd", { className: "text-foreground", children: total })
1536
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-col rounded-md border border-border bg-card p-3", children: [
1537
+ /* @__PURE__ */ jsx18("dt", { className: "text-xs text-muted-foreground", children: "Total" }),
1538
+ /* @__PURE__ */ jsx18("dd", { className: "text-foreground", children: total })
1431
1539
  ] })
1432
1540
  ] }),
1433
- /* @__PURE__ */ jsx17("div", { children: /* @__PURE__ */ jsx17(
1541
+ /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18(
1434
1542
  "button",
1435
1543
  {
1436
1544
  type: "button",
@@ -1444,10 +1552,10 @@ function BroadcastProgress({
1444
1552
  }
1445
1553
 
1446
1554
  // src/broadcast-composer.tsx
1447
- import { useState as useState7 } from "react";
1448
- import { cn as cn16, useToast as useToast6 } from "@quanticjs/react-ui";
1555
+ import { useState as useState8 } from "react";
1556
+ import { cn as cn17, useToast as useToast6 } from "@quanticjs/react-ui";
1449
1557
  import { useApiQuery as useApiQuery12, useApiMutation as useApiMutation7 } from "@quanticjs/react-query";
1450
- import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
1558
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1451
1559
  var CHANNELS2 = ["inapp", "email", "push", "sms", "webhook", "slack", "teams"];
1452
1560
  function normalizeList(data) {
1453
1561
  if (!data) return [];
@@ -1463,14 +1571,14 @@ function BroadcastComposer({
1463
1571
  className
1464
1572
  }) {
1465
1573
  const toast = useToast6();
1466
- const [idempotencyKey] = useState7(() => crypto.randomUUID());
1467
- const [templateId, setTemplateId] = useState7("");
1468
- const [channels, setChannels] = useState7([]);
1469
- const [audienceMode, setAudienceMode] = useState7("segment");
1470
- const [segmentId, setSegmentId] = useState7("");
1471
- const [recipientsRaw, setRecipientsRaw] = useState7("");
1472
- const [type, setType] = useState7("");
1473
- const [errors, setErrors] = useState7({});
1574
+ const [idempotencyKey] = useState8(() => crypto.randomUUID());
1575
+ const [templateId, setTemplateId] = useState8("");
1576
+ const [channels, setChannels] = useState8([]);
1577
+ const [audienceMode, setAudienceMode] = useState8("segment");
1578
+ const [segmentId, setSegmentId] = useState8("");
1579
+ const [recipientsRaw, setRecipientsRaw] = useState8("");
1580
+ const [type, setType] = useState8("");
1581
+ const [errors, setErrors] = useState8({});
1474
1582
  const templatesQuery = useApiQuery12(
1475
1583
  ["templates"],
1476
1584
  (client) => client.get(`${basePath}/templates`)
@@ -1495,23 +1603,23 @@ function BroadcastComposer({
1495
1603
  const isLoading = templatesQuery.isLoading || segmentsQuery.isLoading;
1496
1604
  const isError = templatesQuery.isError || segmentsQuery.isError;
1497
1605
  if (isLoading) {
1498
- return /* @__PURE__ */ jsxs15(
1606
+ return /* @__PURE__ */ jsxs16(
1499
1607
  "div",
1500
1608
  {
1501
1609
  role: "status",
1502
1610
  "aria-label": "Loading broadcast composer",
1503
- className: cn16("flex flex-col gap-2 p-4", className),
1611
+ className: cn17("flex flex-col gap-2 p-4", className),
1504
1612
  children: [
1505
- /* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Loading broadcast composer" }),
1506
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx18("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1613
+ /* @__PURE__ */ jsx19("span", { className: "sr-only", children: "Loading broadcast composer" }),
1614
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx19("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1507
1615
  ]
1508
1616
  }
1509
1617
  );
1510
1618
  }
1511
1619
  if (isError) {
1512
- return /* @__PURE__ */ jsxs15("div", { className: cn16("flex flex-col items-start gap-3 p-4", className), children: [
1513
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-foreground", children: "Failed to load broadcast composer" }),
1514
- /* @__PURE__ */ jsx18(
1620
+ return /* @__PURE__ */ jsxs16("div", { className: cn17("flex flex-col items-start gap-3 p-4", className), children: [
1621
+ /* @__PURE__ */ jsx19("p", { className: "text-sm text-foreground", children: "Failed to load broadcast composer" }),
1622
+ /* @__PURE__ */ jsx19(
1515
1623
  "button",
1516
1624
  {
1517
1625
  type: "button",
@@ -1558,11 +1666,11 @@ function BroadcastComposer({
1558
1666
  idempotencyKey
1559
1667
  });
1560
1668
  };
1561
- return /* @__PURE__ */ jsxs15("form", { onSubmit, className: cn16("flex flex-col gap-4 p-4", className), noValidate: true, children: [
1562
- /* @__PURE__ */ jsx18("h2", { className: "text-sm font-semibold text-foreground", children: "New broadcast" }),
1563
- /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
1564
- /* @__PURE__ */ jsx18("label", { htmlFor: "composer-template", className: "text-sm font-medium text-foreground", children: "Template" }),
1565
- /* @__PURE__ */ jsxs15(
1669
+ return /* @__PURE__ */ jsxs16("form", { onSubmit, className: cn17("flex flex-col gap-4 p-4", className), noValidate: true, children: [
1670
+ /* @__PURE__ */ jsx19("h2", { className: "text-sm font-semibold text-foreground", children: "New broadcast" }),
1671
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
1672
+ /* @__PURE__ */ jsx19("label", { htmlFor: "composer-template", className: "text-sm font-medium text-foreground", children: "Template" }),
1673
+ /* @__PURE__ */ jsxs16(
1566
1674
  "select",
1567
1675
  {
1568
1676
  id: "composer-template",
@@ -1572,30 +1680,30 @@ function BroadcastComposer({
1572
1680
  onChange: (e) => setTemplateId(e.target.value),
1573
1681
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
1574
1682
  children: [
1575
- /* @__PURE__ */ jsx18("option", { value: "", children: "Select a template\u2026" }),
1576
- templates.map((t) => /* @__PURE__ */ jsx18("option", { value: t.id, children: t.name ?? t.id }, t.id))
1683
+ /* @__PURE__ */ jsx19("option", { value: "", children: "Select a template\u2026" }),
1684
+ templates.map((t) => /* @__PURE__ */ jsx19("option", { value: t.id, children: t.name ?? t.id }, t.id))
1577
1685
  ]
1578
1686
  }
1579
1687
  ),
1580
- errors.templateId && /* @__PURE__ */ jsx18("p", { id: "composer-template-error", className: "text-xs text-destructive", children: errors.templateId })
1688
+ errors.templateId && /* @__PURE__ */ jsx19("p", { id: "composer-template-error", className: "text-xs text-destructive", children: errors.templateId })
1581
1689
  ] }),
1582
- /* @__PURE__ */ jsxs15(
1690
+ /* @__PURE__ */ jsxs16(
1583
1691
  "fieldset",
1584
1692
  {
1585
1693
  className: "flex flex-col gap-2",
1586
1694
  "aria-invalid": errors.channels ? "true" : void 0,
1587
1695
  "aria-describedby": errors.channels ? "composer-channels-error" : void 0,
1588
1696
  children: [
1589
- /* @__PURE__ */ jsx18("legend", { className: "text-sm font-medium text-foreground", children: "Channels" }),
1590
- /* @__PURE__ */ jsx18("div", { className: "flex flex-wrap gap-3", children: CHANNELS2.map((channel) => {
1697
+ /* @__PURE__ */ jsx19("legend", { className: "text-sm font-medium text-foreground", children: "Channels" }),
1698
+ /* @__PURE__ */ jsx19("div", { className: "flex flex-wrap gap-3", children: CHANNELS2.map((channel) => {
1591
1699
  const checkboxId = `composer-channel-${channel}`;
1592
- return /* @__PURE__ */ jsxs15(
1700
+ return /* @__PURE__ */ jsxs16(
1593
1701
  "label",
1594
1702
  {
1595
1703
  htmlFor: checkboxId,
1596
1704
  className: "flex items-center gap-2 text-sm text-foreground",
1597
1705
  children: [
1598
- /* @__PURE__ */ jsx18(
1706
+ /* @__PURE__ */ jsx19(
1599
1707
  "input",
1600
1708
  {
1601
1709
  id: checkboxId,
@@ -1611,20 +1719,20 @@ function BroadcastComposer({
1611
1719
  channel
1612
1720
  );
1613
1721
  }) }),
1614
- errors.channels && /* @__PURE__ */ jsx18("p", { id: "composer-channels-error", className: "text-xs text-destructive", children: errors.channels })
1722
+ errors.channels && /* @__PURE__ */ jsx19("p", { id: "composer-channels-error", className: "text-xs text-destructive", children: errors.channels })
1615
1723
  ]
1616
1724
  }
1617
1725
  ),
1618
- /* @__PURE__ */ jsxs15("fieldset", { className: "flex flex-col gap-2", children: [
1619
- /* @__PURE__ */ jsx18("legend", { className: "text-sm font-medium text-foreground", children: "Audience" }),
1620
- /* @__PURE__ */ jsxs15("div", { className: "flex gap-4", children: [
1621
- /* @__PURE__ */ jsxs15(
1726
+ /* @__PURE__ */ jsxs16("fieldset", { className: "flex flex-col gap-2", children: [
1727
+ /* @__PURE__ */ jsx19("legend", { className: "text-sm font-medium text-foreground", children: "Audience" }),
1728
+ /* @__PURE__ */ jsxs16("div", { className: "flex gap-4", children: [
1729
+ /* @__PURE__ */ jsxs16(
1622
1730
  "label",
1623
1731
  {
1624
1732
  htmlFor: "composer-audience-segment",
1625
1733
  className: "flex items-center gap-2 text-sm text-foreground",
1626
1734
  children: [
1627
- /* @__PURE__ */ jsx18(
1735
+ /* @__PURE__ */ jsx19(
1628
1736
  "input",
1629
1737
  {
1630
1738
  id: "composer-audience-segment",
@@ -1639,13 +1747,13 @@ function BroadcastComposer({
1639
1747
  ]
1640
1748
  }
1641
1749
  ),
1642
- /* @__PURE__ */ jsxs15(
1750
+ /* @__PURE__ */ jsxs16(
1643
1751
  "label",
1644
1752
  {
1645
1753
  htmlFor: "composer-audience-recipients",
1646
1754
  className: "flex items-center gap-2 text-sm text-foreground",
1647
1755
  children: [
1648
- /* @__PURE__ */ jsx18(
1756
+ /* @__PURE__ */ jsx19(
1649
1757
  "input",
1650
1758
  {
1651
1759
  id: "composer-audience-recipients",
@@ -1661,7 +1769,7 @@ function BroadcastComposer({
1661
1769
  }
1662
1770
  )
1663
1771
  ] }),
1664
- audienceMode === "segment" ? /* @__PURE__ */ jsxs15(
1772
+ audienceMode === "segment" ? /* @__PURE__ */ jsxs16(
1665
1773
  "select",
1666
1774
  {
1667
1775
  id: "composer-segment",
@@ -1672,11 +1780,11 @@ function BroadcastComposer({
1672
1780
  onChange: (e) => setSegmentId(e.target.value),
1673
1781
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
1674
1782
  children: [
1675
- /* @__PURE__ */ jsx18("option", { value: "", children: "Select a segment\u2026" }),
1676
- segments.map((s) => /* @__PURE__ */ jsx18("option", { value: s.id, children: s.name }, s.id))
1783
+ /* @__PURE__ */ jsx19("option", { value: "", children: "Select a segment\u2026" }),
1784
+ segments.map((s) => /* @__PURE__ */ jsx19("option", { value: s.id, children: s.name }, s.id))
1677
1785
  ]
1678
1786
  }
1679
- ) : /* @__PURE__ */ jsx18(
1787
+ ) : /* @__PURE__ */ jsx19(
1680
1788
  "textarea",
1681
1789
  {
1682
1790
  id: "composer-recipients",
@@ -1690,11 +1798,11 @@ function BroadcastComposer({
1690
1798
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
1691
1799
  }
1692
1800
  ),
1693
- errors.audience && /* @__PURE__ */ jsx18("p", { id: "composer-audience-error", className: "text-xs text-destructive", children: errors.audience })
1801
+ errors.audience && /* @__PURE__ */ jsx19("p", { id: "composer-audience-error", className: "text-xs text-destructive", children: errors.audience })
1694
1802
  ] }),
1695
- /* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1", children: [
1696
- /* @__PURE__ */ jsx18("label", { htmlFor: "composer-type", className: "text-sm font-medium text-foreground", children: "Type (optional)" }),
1697
- /* @__PURE__ */ jsx18(
1803
+ /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
1804
+ /* @__PURE__ */ jsx19("label", { htmlFor: "composer-type", className: "text-sm font-medium text-foreground", children: "Type (optional)" }),
1805
+ /* @__PURE__ */ jsx19(
1698
1806
  "input",
1699
1807
  {
1700
1808
  id: "composer-type",
@@ -1705,7 +1813,7 @@ function BroadcastComposer({
1705
1813
  }
1706
1814
  )
1707
1815
  ] }),
1708
- /* @__PURE__ */ jsx18("div", { children: /* @__PURE__ */ jsx18(
1816
+ /* @__PURE__ */ jsx19("div", { children: /* @__PURE__ */ jsx19(
1709
1817
  "button",
1710
1818
  {
1711
1819
  type: "submit",
@@ -1718,9 +1826,9 @@ function BroadcastComposer({
1718
1826
  }
1719
1827
 
1720
1828
  // src/segment-list.tsx
1721
- import { cn as cn17, formatDateTime as formatDateTime2, StatusBadge as StatusBadge3 } from "@quanticjs/react-ui";
1829
+ import { cn as cn18, formatDateTime as formatDateTime2, StatusBadge as StatusBadge3 } from "@quanticjs/react-ui";
1722
1830
  import { useApiQuery as useApiQuery13 } from "@quanticjs/react-query";
1723
- import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1831
+ import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1724
1832
  function normalize(data) {
1725
1833
  if (Array.isArray(data)) return data;
1726
1834
  return data?.items ?? [];
@@ -1746,23 +1854,23 @@ function SegmentList({
1746
1854
  (client) => client.get(`${basePath}/v1/segments`)
1747
1855
  );
1748
1856
  if (isLoading) {
1749
- return /* @__PURE__ */ jsxs16(
1857
+ return /* @__PURE__ */ jsxs17(
1750
1858
  "div",
1751
1859
  {
1752
1860
  role: "status",
1753
1861
  "aria-label": "Loading segments",
1754
- className: cn17("flex flex-col gap-2 p-4", className),
1862
+ className: cn18("flex flex-col gap-2 p-4", className),
1755
1863
  children: [
1756
- /* @__PURE__ */ jsx19("span", { className: "sr-only", children: "Loading segments" }),
1757
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx19("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1864
+ /* @__PURE__ */ jsx20("span", { className: "sr-only", children: "Loading segments" }),
1865
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx20("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
1758
1866
  ]
1759
1867
  }
1760
1868
  );
1761
1869
  }
1762
1870
  if (isError) {
1763
- return /* @__PURE__ */ jsxs16("div", { className: cn17("flex flex-col items-start gap-3 p-4", className), children: [
1764
- /* @__PURE__ */ jsx19("p", { className: "text-sm text-foreground", children: "Failed to load segments" }),
1765
- /* @__PURE__ */ jsx19(
1871
+ return /* @__PURE__ */ jsxs17("div", { className: cn18("flex flex-col items-start gap-3 p-4", className), children: [
1872
+ /* @__PURE__ */ jsx20("p", { className: "text-sm text-foreground", children: "Failed to load segments" }),
1873
+ /* @__PURE__ */ jsx20(
1766
1874
  "button",
1767
1875
  {
1768
1876
  type: "button",
@@ -1774,7 +1882,7 @@ function SegmentList({
1774
1882
  ] });
1775
1883
  }
1776
1884
  const rows = normalize(data);
1777
- const header = onCreate ? /* @__PURE__ */ jsx19("header", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsx19(
1885
+ const header = onCreate ? /* @__PURE__ */ jsx20("header", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsx20(
1778
1886
  "button",
1779
1887
  {
1780
1888
  type: "button",
@@ -1784,12 +1892,12 @@ function SegmentList({
1784
1892
  }
1785
1893
  ) }) : null;
1786
1894
  if (rows.length === 0) {
1787
- return /* @__PURE__ */ jsxs16("section", { "aria-label": "Segments", className: cn17("flex flex-col gap-3", className), children: [
1895
+ return /* @__PURE__ */ jsxs17("section", { "aria-label": "Segments", className: cn18("flex flex-col gap-3", className), children: [
1788
1896
  header,
1789
- /* @__PURE__ */ jsx19("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No segments" })
1897
+ /* @__PURE__ */ jsx20("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No segments" })
1790
1898
  ] });
1791
1899
  }
1792
- const renderNameCell = (row) => onSelect ? /* @__PURE__ */ jsx19(
1900
+ const renderNameCell = (row) => onSelect ? /* @__PURE__ */ jsx20(
1793
1901
  "button",
1794
1902
  {
1795
1903
  type: "button",
@@ -1797,33 +1905,33 @@ function SegmentList({
1797
1905
  className: "rounded text-start font-medium text-primary hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
1798
1906
  children: row.name
1799
1907
  }
1800
- ) : /* @__PURE__ */ jsx19("span", { className: "text-foreground", children: row.name });
1801
- return /* @__PURE__ */ jsxs16("section", { "aria-label": "Segments", className: cn17("flex flex-col gap-3", className), children: [
1908
+ ) : /* @__PURE__ */ jsx20("span", { className: "text-foreground", children: row.name });
1909
+ return /* @__PURE__ */ jsxs17("section", { "aria-label": "Segments", className: cn18("flex flex-col gap-3", className), children: [
1802
1910
  header,
1803
- /* @__PURE__ */ jsxs16("table", { className: "w-full text-sm", children: [
1804
- /* @__PURE__ */ jsx19("thead", { children: /* @__PURE__ */ jsxs16("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1805
- /* @__PURE__ */ jsx19("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Name" }),
1806
- /* @__PURE__ */ jsx19("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Type" }),
1807
- /* @__PURE__ */ jsx19("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Description" }),
1808
- /* @__PURE__ */ jsx19("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Recipients" }),
1809
- /* @__PURE__ */ jsx19("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
1911
+ /* @__PURE__ */ jsxs17("table", { className: "w-full text-sm", children: [
1912
+ /* @__PURE__ */ jsx20("thead", { children: /* @__PURE__ */ jsxs17("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
1913
+ /* @__PURE__ */ jsx20("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Name" }),
1914
+ /* @__PURE__ */ jsx20("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Type" }),
1915
+ /* @__PURE__ */ jsx20("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Description" }),
1916
+ /* @__PURE__ */ jsx20("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Recipients" }),
1917
+ /* @__PURE__ */ jsx20("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
1810
1918
  ] }) }),
1811
- /* @__PURE__ */ jsx19("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs16("tr", { className: "border-b border-border", children: [
1812
- /* @__PURE__ */ jsx19("td", { className: "py-3 pe-4", children: renderNameCell(row) }),
1813
- /* @__PURE__ */ jsx19("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx19(StatusBadge3, { variant: typeVariant(row.type), appearance: "dot", children: row.type }) }),
1814
- /* @__PURE__ */ jsx19("td", { className: "px-4 py-3 text-muted-foreground", children: row.description ?? "\u2014" }),
1815
- /* @__PURE__ */ jsx19("td", { className: "px-4 py-3 text-muted-foreground", children: row.recipientIds?.length ?? "\u2014" }),
1816
- /* @__PURE__ */ jsx19("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime2(row.createdAt) })
1919
+ /* @__PURE__ */ jsx20("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs17("tr", { className: "border-b border-border", children: [
1920
+ /* @__PURE__ */ jsx20("td", { className: "py-3 pe-4", children: renderNameCell(row) }),
1921
+ /* @__PURE__ */ jsx20("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx20(StatusBadge3, { variant: typeVariant(row.type), appearance: "dot", children: row.type }) }),
1922
+ /* @__PURE__ */ jsx20("td", { className: "px-4 py-3 text-muted-foreground", children: row.description ?? "\u2014" }),
1923
+ /* @__PURE__ */ jsx20("td", { className: "px-4 py-3 text-muted-foreground", children: row.recipientIds?.length ?? "\u2014" }),
1924
+ /* @__PURE__ */ jsx20("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime2(row.createdAt) })
1817
1925
  ] }, row.id)) })
1818
1926
  ] })
1819
1927
  ] });
1820
1928
  }
1821
1929
 
1822
1930
  // src/segment-builder.tsx
1823
- import { useState as useState8 } from "react";
1824
- import { cn as cn18, useToast as useToast7 } from "@quanticjs/react-ui";
1931
+ import { useState as useState9 } from "react";
1932
+ import { cn as cn19, useToast as useToast7 } from "@quanticjs/react-ui";
1825
1933
  import { useApiMutation as useApiMutation8 } from "@quanticjs/react-query";
1826
- import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1934
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1827
1935
  function parseRecipientIds(value) {
1828
1936
  return value.split(/[\n,]/).map((id) => id.trim()).filter((id) => id.length > 0);
1829
1937
  }
@@ -1836,11 +1944,11 @@ function SegmentBuilder({
1836
1944
  className
1837
1945
  }) {
1838
1946
  const toast = useToast7();
1839
- const [name, setName] = useState8(initial?.name ?? "");
1840
- const [type, setType] = useState8(initial?.type ?? "static");
1841
- const [description, setDescription] = useState8(initial?.description ?? "");
1842
- const [recipientText, setRecipientText] = useState8((initial?.recipientIds ?? []).join("\n"));
1843
- const [errors, setErrors] = useState8({});
1947
+ const [name, setName] = useState9(initial?.name ?? "");
1948
+ const [type, setType] = useState9(initial?.type ?? "static");
1949
+ const [description, setDescription] = useState9(initial?.description ?? "");
1950
+ const [recipientText, setRecipientText] = useState9((initial?.recipientIds ?? []).join("\n"));
1951
+ const [errors, setErrors] = useState9({});
1844
1952
  const isEdit = Boolean(segmentId);
1845
1953
  const onMutationError = (error) => toast.error(error.isServerError ? "Something went wrong" : error.title, {
1846
1954
  description: error.isServerError ? `Please try again. (ref: ${error.correlationId ?? "unknown"})` : `${error.detail ?? ""} (ref: ${error.correlationId ?? "unknown"})`
@@ -1889,11 +1997,11 @@ function SegmentBuilder({
1889
1997
  if (!window.confirm("Delete this segment? This cannot be undone.")) return;
1890
1998
  remove.mutate();
1891
1999
  };
1892
- return /* @__PURE__ */ jsxs17("form", { onSubmit, className: cn18("flex flex-col gap-4", className), noValidate: true, children: [
1893
- /* @__PURE__ */ jsx20("header", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx20("h2", { className: "text-sm font-semibold text-foreground", children: isEdit ? `Edit segment: ${segmentId}` : "New segment" }) }),
1894
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
1895
- /* @__PURE__ */ jsx20("label", { htmlFor: "segment-name", className: "text-sm font-medium text-foreground", children: "Name" }),
1896
- /* @__PURE__ */ jsx20(
2000
+ return /* @__PURE__ */ jsxs18("form", { onSubmit, className: cn19("flex flex-col gap-4", className), noValidate: true, children: [
2001
+ /* @__PURE__ */ jsx21("header", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx21("h2", { className: "text-sm font-semibold text-foreground", children: isEdit ? `Edit segment: ${segmentId}` : "New segment" }) }),
2002
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2003
+ /* @__PURE__ */ jsx21("label", { htmlFor: "segment-name", className: "text-sm font-medium text-foreground", children: "Name" }),
2004
+ /* @__PURE__ */ jsx21(
1897
2005
  "input",
1898
2006
  {
1899
2007
  id: "segment-name",
@@ -1905,11 +2013,11 @@ function SegmentBuilder({
1905
2013
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
1906
2014
  }
1907
2015
  ),
1908
- errors.name && /* @__PURE__ */ jsx20("p", { id: "segment-name-error", className: "text-xs text-destructive", children: errors.name })
2016
+ errors.name && /* @__PURE__ */ jsx21("p", { id: "segment-name-error", className: "text-xs text-destructive", children: errors.name })
1909
2017
  ] }),
1910
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
1911
- /* @__PURE__ */ jsx20("label", { htmlFor: "segment-type", className: "text-sm font-medium text-foreground", children: "Type" }),
1912
- /* @__PURE__ */ jsxs17(
2018
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2019
+ /* @__PURE__ */ jsx21("label", { htmlFor: "segment-type", className: "text-sm font-medium text-foreground", children: "Type" }),
2020
+ /* @__PURE__ */ jsxs18(
1913
2021
  "select",
1914
2022
  {
1915
2023
  id: "segment-type",
@@ -1917,15 +2025,15 @@ function SegmentBuilder({
1917
2025
  onChange: (e) => setType(e.target.value),
1918
2026
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
1919
2027
  children: [
1920
- /* @__PURE__ */ jsx20("option", { value: "static", children: "static" }),
1921
- /* @__PURE__ */ jsx20("option", { value: "dynamic", children: "dynamic" })
2028
+ /* @__PURE__ */ jsx21("option", { value: "static", children: "static" }),
2029
+ /* @__PURE__ */ jsx21("option", { value: "dynamic", children: "dynamic" })
1922
2030
  ]
1923
2031
  }
1924
2032
  )
1925
2033
  ] }),
1926
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
1927
- /* @__PURE__ */ jsx20("label", { htmlFor: "segment-description", className: "text-sm font-medium text-foreground", children: "Description" }),
1928
- /* @__PURE__ */ jsx20(
2034
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2035
+ /* @__PURE__ */ jsx21("label", { htmlFor: "segment-description", className: "text-sm font-medium text-foreground", children: "Description" }),
2036
+ /* @__PURE__ */ jsx21(
1929
2037
  "textarea",
1930
2038
  {
1931
2039
  id: "segment-description",
@@ -1936,9 +2044,9 @@ function SegmentBuilder({
1936
2044
  }
1937
2045
  )
1938
2046
  ] }),
1939
- type === "static" && /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
1940
- /* @__PURE__ */ jsx20("label", { htmlFor: "segment-recipients", className: "text-sm font-medium text-foreground", children: "Recipient ids" }),
1941
- /* @__PURE__ */ jsx20(
2047
+ type === "static" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2048
+ /* @__PURE__ */ jsx21("label", { htmlFor: "segment-recipients", className: "text-sm font-medium text-foreground", children: "Recipient ids" }),
2049
+ /* @__PURE__ */ jsx21(
1942
2050
  "textarea",
1943
2051
  {
1944
2052
  id: "segment-recipients",
@@ -1951,10 +2059,10 @@ function SegmentBuilder({
1951
2059
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
1952
2060
  }
1953
2061
  ),
1954
- errors.recipientIds && /* @__PURE__ */ jsx20("p", { id: "segment-recipients-error", className: "text-xs text-destructive", children: errors.recipientIds })
2062
+ errors.recipientIds && /* @__PURE__ */ jsx21("p", { id: "segment-recipients-error", className: "text-xs text-destructive", children: errors.recipientIds })
1955
2063
  ] }),
1956
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
1957
- /* @__PURE__ */ jsx20(
2064
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3", children: [
2065
+ /* @__PURE__ */ jsx21(
1958
2066
  "button",
1959
2067
  {
1960
2068
  type: "submit",
@@ -1963,7 +2071,7 @@ function SegmentBuilder({
1963
2071
  children: save.isPending ? "Saving\u2026" : isEdit ? "Save changes" : "Create segment"
1964
2072
  }
1965
2073
  ),
1966
- isEdit && /* @__PURE__ */ jsx20(
2074
+ isEdit && /* @__PURE__ */ jsx21(
1967
2075
  "button",
1968
2076
  {
1969
2077
  type: "button",
@@ -1978,18 +2086,18 @@ function SegmentBuilder({
1978
2086
  }
1979
2087
 
1980
2088
  // src/suppression-manager.tsx
1981
- import { useState as useState9 } from "react";
1982
- import { cn as cn19, formatDateTime as formatDateTime3, useToast as useToast8 } from "@quanticjs/react-ui";
2089
+ import { useState as useState10 } from "react";
2090
+ import { cn as cn20, formatDateTime as formatDateTime3, useToast as useToast8 } from "@quanticjs/react-ui";
1983
2091
  import { useApiMutation as useApiMutation9, useApiQuery as useApiQuery14 } from "@quanticjs/react-query";
1984
- import { Fragment, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
2092
+ import { Fragment, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
1985
2093
  var LIMIT3 = 20;
1986
2094
  var CHANNELS3 = ["inapp", "email", "push", "sms"];
1987
2095
  function SuppressionManager({ basePath = "/api", className }) {
1988
2096
  const toast = useToast8();
1989
- const [page, setPage] = useState9(1);
1990
- const [channel, setChannel] = useState9("email");
1991
- const [address, setAddress] = useState9("");
1992
- const [reason, setReason] = useState9("");
2097
+ const [page, setPage] = useState10(1);
2098
+ const [channel, setChannel] = useState10("email");
2099
+ const [address, setAddress] = useState10("");
2100
+ const [reason, setReason] = useState10("");
1993
2101
  const { data, isLoading, isError, refetch } = useApiQuery14(
1994
2102
  ["suppression", page],
1995
2103
  (client) => client.get(`${basePath}/v1/admin/suppression?page=${page}&limit=${LIMIT3}`)
@@ -2025,23 +2133,23 @@ function SuppressionManager({ basePath = "/api", className }) {
2025
2133
  event.preventDefault();
2026
2134
  add.mutate({ channel, address: address.trim(), reason: reason.trim() });
2027
2135
  };
2028
- const addForm = /* @__PURE__ */ jsxs18("form", { onSubmit: onAdd, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2029
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2030
- /* @__PURE__ */ jsx21("label", { htmlFor: "suppression-channel", className: "text-sm font-medium text-foreground", children: "Channel" }),
2031
- /* @__PURE__ */ jsx21(
2136
+ const addForm = /* @__PURE__ */ jsxs19("form", { onSubmit: onAdd, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2137
+ /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
2138
+ /* @__PURE__ */ jsx22("label", { htmlFor: "suppression-channel", className: "text-sm font-medium text-foreground", children: "Channel" }),
2139
+ /* @__PURE__ */ jsx22(
2032
2140
  "select",
2033
2141
  {
2034
2142
  id: "suppression-channel",
2035
2143
  value: channel,
2036
2144
  onChange: (e) => setChannel(e.target.value),
2037
2145
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
2038
- children: CHANNELS3.map((c) => /* @__PURE__ */ jsx21("option", { value: c, children: c }, c))
2146
+ children: CHANNELS3.map((c) => /* @__PURE__ */ jsx22("option", { value: c, children: c }, c))
2039
2147
  }
2040
2148
  )
2041
2149
  ] }),
2042
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2043
- /* @__PURE__ */ jsx21("label", { htmlFor: "suppression-address", className: "text-sm font-medium text-foreground", children: "Address" }),
2044
- /* @__PURE__ */ jsx21(
2150
+ /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
2151
+ /* @__PURE__ */ jsx22("label", { htmlFor: "suppression-address", className: "text-sm font-medium text-foreground", children: "Address" }),
2152
+ /* @__PURE__ */ jsx22(
2045
2153
  "input",
2046
2154
  {
2047
2155
  id: "suppression-address",
@@ -2052,9 +2160,9 @@ function SuppressionManager({ basePath = "/api", className }) {
2052
2160
  }
2053
2161
  )
2054
2162
  ] }),
2055
- /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-1", children: [
2056
- /* @__PURE__ */ jsx21("label", { htmlFor: "suppression-reason", className: "text-sm font-medium text-foreground", children: "Reason" }),
2057
- /* @__PURE__ */ jsx21(
2163
+ /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-1", children: [
2164
+ /* @__PURE__ */ jsx22("label", { htmlFor: "suppression-reason", className: "text-sm font-medium text-foreground", children: "Reason" }),
2165
+ /* @__PURE__ */ jsx22(
2058
2166
  "input",
2059
2167
  {
2060
2168
  id: "suppression-reason",
@@ -2065,7 +2173,7 @@ function SuppressionManager({ basePath = "/api", className }) {
2065
2173
  }
2066
2174
  )
2067
2175
  ] }),
2068
- /* @__PURE__ */ jsx21(
2176
+ /* @__PURE__ */ jsx22(
2069
2177
  "button",
2070
2178
  {
2071
2179
  type: "submit",
@@ -2077,14 +2185,14 @@ function SuppressionManager({ basePath = "/api", className }) {
2077
2185
  ] });
2078
2186
  let body;
2079
2187
  if (isLoading) {
2080
- body = /* @__PURE__ */ jsxs18("div", { role: "status", "aria-label": "Loading suppressions", className: "flex flex-col gap-2 p-4", children: [
2081
- /* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Loading suppressions" }),
2082
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx21("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2188
+ body = /* @__PURE__ */ jsxs19("div", { role: "status", "aria-label": "Loading suppressions", className: "flex flex-col gap-2 p-4", children: [
2189
+ /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Loading suppressions" }),
2190
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx22("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2083
2191
  ] });
2084
2192
  } else if (isError) {
2085
- body = /* @__PURE__ */ jsxs18("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2086
- /* @__PURE__ */ jsx21("p", { className: "text-sm text-foreground", children: "Failed to load suppressions" }),
2087
- /* @__PURE__ */ jsx21(
2193
+ body = /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2194
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-foreground", children: "Failed to load suppressions" }),
2195
+ /* @__PURE__ */ jsx22(
2088
2196
  "button",
2089
2197
  {
2090
2198
  type: "button",
@@ -2098,23 +2206,23 @@ function SuppressionManager({ basePath = "/api", className }) {
2098
2206
  const rows = data?.items ?? [];
2099
2207
  const totalPages = data?.totalPages ?? 1;
2100
2208
  if (rows.length === 0) {
2101
- body = /* @__PURE__ */ jsx21("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No suppressions" });
2209
+ body = /* @__PURE__ */ jsx22("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No suppressions" });
2102
2210
  } else {
2103
- body = /* @__PURE__ */ jsxs18(Fragment, { children: [
2104
- /* @__PURE__ */ jsxs18("table", { className: "w-full text-sm", children: [
2105
- /* @__PURE__ */ jsx21("thead", { children: /* @__PURE__ */ jsxs18("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2106
- /* @__PURE__ */ jsx21("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
2107
- /* @__PURE__ */ jsx21("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Address" }),
2108
- /* @__PURE__ */ jsx21("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Reason" }),
2109
- /* @__PURE__ */ jsx21("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
2110
- /* @__PURE__ */ jsx21("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Actions" }) })
2211
+ body = /* @__PURE__ */ jsxs19(Fragment, { children: [
2212
+ /* @__PURE__ */ jsxs19("table", { className: "w-full text-sm", children: [
2213
+ /* @__PURE__ */ jsx22("thead", { children: /* @__PURE__ */ jsxs19("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2214
+ /* @__PURE__ */ jsx22("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
2215
+ /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Address" }),
2216
+ /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Reason" }),
2217
+ /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
2218
+ /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Actions" }) })
2111
2219
  ] }) }),
2112
- /* @__PURE__ */ jsx21("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs18("tr", { className: "border-b border-border", children: [
2113
- /* @__PURE__ */ jsx21("td", { className: "py-3 pe-4 text-foreground", children: row.channel }),
2114
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-foreground", children: row.address }),
2115
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-muted-foreground", children: row.reason }),
2116
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime3(row.createdAt) }),
2117
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx21(
2220
+ /* @__PURE__ */ jsx22("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs19("tr", { className: "border-b border-border", children: [
2221
+ /* @__PURE__ */ jsx22("td", { className: "py-3 pe-4 text-foreground", children: row.channel }),
2222
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-foreground", children: row.address }),
2223
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-muted-foreground", children: row.reason }),
2224
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime3(row.createdAt) }),
2225
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx22(
2118
2226
  "button",
2119
2227
  {
2120
2228
  type: "button",
@@ -2126,8 +2234,8 @@ function SuppressionManager({ basePath = "/api", className }) {
2126
2234
  ) })
2127
2235
  ] }, row.id)) })
2128
2236
  ] }),
2129
- /* @__PURE__ */ jsxs18("nav", { "aria-label": "Suppression pagination", className: "flex items-center justify-between", children: [
2130
- /* @__PURE__ */ jsx21(
2237
+ /* @__PURE__ */ jsxs19("nav", { "aria-label": "Suppression pagination", className: "flex items-center justify-between", children: [
2238
+ /* @__PURE__ */ jsx22(
2131
2239
  "button",
2132
2240
  {
2133
2241
  type: "button",
@@ -2137,13 +2245,13 @@ function SuppressionManager({ basePath = "/api", className }) {
2137
2245
  children: "Previous"
2138
2246
  }
2139
2247
  ),
2140
- /* @__PURE__ */ jsxs18("span", { className: "text-xs text-muted-foreground", children: [
2248
+ /* @__PURE__ */ jsxs19("span", { className: "text-xs text-muted-foreground", children: [
2141
2249
  "Page ",
2142
2250
  page,
2143
2251
  " of ",
2144
2252
  totalPages
2145
2253
  ] }),
2146
- /* @__PURE__ */ jsx21(
2254
+ /* @__PURE__ */ jsx22(
2147
2255
  "button",
2148
2256
  {
2149
2257
  type: "button",
@@ -2157,22 +2265,22 @@ function SuppressionManager({ basePath = "/api", className }) {
2157
2265
  ] });
2158
2266
  }
2159
2267
  }
2160
- return /* @__PURE__ */ jsxs18("section", { "aria-label": "Suppression list", className: cn19("flex flex-col gap-4", className), children: [
2268
+ return /* @__PURE__ */ jsxs19("section", { "aria-label": "Suppression list", className: cn20("flex flex-col gap-4", className), children: [
2161
2269
  addForm,
2162
2270
  body
2163
2271
  ] });
2164
2272
  }
2165
2273
 
2166
2274
  // src/dlq-console.tsx
2167
- import { Fragment as Fragment2, useState as useState10 } from "react";
2275
+ import { Fragment as Fragment2, useState as useState11 } from "react";
2168
2276
  import {
2169
- cn as cn20,
2277
+ cn as cn21,
2170
2278
  formatDateTime as formatDateTime4,
2171
2279
  StatusBadge as StatusBadge4,
2172
2280
  useToast as useToast9
2173
2281
  } from "@quanticjs/react-ui";
2174
2282
  import { useApiMutation as useApiMutation10, useApiQuery as useApiQuery15 } from "@quanticjs/react-query";
2175
- import { Fragment as Fragment3, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
2283
+ import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
2176
2284
  var LIMIT4 = 20;
2177
2285
  var STATUS_FILTERS = ["queued", "replayed", "discarded"];
2178
2286
  function buildErrorDescription(error) {
@@ -2196,15 +2304,15 @@ function DlqMessageDetailRow({ id, basePath }) {
2196
2304
  (client) => client.get(`${basePath}/admin/dlq/${id}`)
2197
2305
  );
2198
2306
  if (isLoading) {
2199
- return /* @__PURE__ */ jsxs19("div", { role: "status", "aria-label": "Loading message detail", className: "flex flex-col gap-2 p-3", children: [
2200
- /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Loading message detail" }),
2201
- /* @__PURE__ */ jsx22("div", { "aria-hidden": "true", className: "h-16 animate-pulse rounded bg-muted" })
2307
+ return /* @__PURE__ */ jsxs20("div", { role: "status", "aria-label": "Loading message detail", className: "flex flex-col gap-2 p-3", children: [
2308
+ /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Loading message detail" }),
2309
+ /* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: "h-16 animate-pulse rounded bg-muted" })
2202
2310
  ] });
2203
2311
  }
2204
2312
  if (isError) {
2205
- return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-start gap-3 p-3", children: [
2206
- /* @__PURE__ */ jsx22("p", { className: "text-sm text-foreground", children: "Failed to load message detail" }),
2207
- /* @__PURE__ */ jsx22(
2313
+ return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col items-start gap-3 p-3", children: [
2314
+ /* @__PURE__ */ jsx23("p", { className: "text-sm text-foreground", children: "Failed to load message detail" }),
2315
+ /* @__PURE__ */ jsx23(
2208
2316
  "button",
2209
2317
  {
2210
2318
  type: "button",
@@ -2215,19 +2323,19 @@ function DlqMessageDetailRow({ id, basePath }) {
2215
2323
  )
2216
2324
  ] });
2217
2325
  }
2218
- return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2 p-3 text-sm", children: [
2219
- /* @__PURE__ */ jsxs19("p", { className: "text-muted-foreground", children: [
2326
+ return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-2 p-3 text-sm", children: [
2327
+ /* @__PURE__ */ jsxs20("p", { className: "text-muted-foreground", children: [
2220
2328
  "Error: ",
2221
- /* @__PURE__ */ jsx22("span", { className: "text-foreground", children: data?.errorMessage ?? "\u2014" })
2329
+ /* @__PURE__ */ jsx23("span", { className: "text-foreground", children: data?.errorMessage ?? "\u2014" })
2222
2330
  ] }),
2223
- /* @__PURE__ */ jsx22("pre", { className: "max-h-64 overflow-auto rounded bg-muted p-3 text-xs text-foreground", children: JSON.stringify(data?.payload ?? {}, null, 2) })
2331
+ /* @__PURE__ */ jsx23("pre", { className: "max-h-64 overflow-auto rounded bg-muted p-3 text-xs text-foreground", children: JSON.stringify(data?.payload ?? {}, null, 2) })
2224
2332
  ] });
2225
2333
  }
2226
2334
  function DlqConsole({ basePath = "/api", className }) {
2227
2335
  const toast = useToast9();
2228
- const [page, setPage] = useState10(1);
2229
- const [statusFilter, setStatusFilter] = useState10("");
2230
- const [expandedId, setExpandedId] = useState10(null);
2336
+ const [page, setPage] = useState11(1);
2337
+ const [statusFilter, setStatusFilter] = useState11("");
2338
+ const [expandedId, setExpandedId] = useState11(null);
2231
2339
  const statusQuery = statusFilter ? `&status=${statusFilter}` : "";
2232
2340
  const { data, isLoading, isError, refetch } = useApiQuery15(
2233
2341
  ["dlq", page, statusFilter],
@@ -2268,9 +2376,9 @@ function DlqConsole({ basePath = "/api", className }) {
2268
2376
  })
2269
2377
  }
2270
2378
  );
2271
- const filterControl = /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
2272
- /* @__PURE__ */ jsx22("label", { htmlFor: "dlq-status", className: "text-sm font-medium text-foreground", children: "Status" }),
2273
- /* @__PURE__ */ jsxs19(
2379
+ const filterControl = /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
2380
+ /* @__PURE__ */ jsx23("label", { htmlFor: "dlq-status", className: "text-sm font-medium text-foreground", children: "Status" }),
2381
+ /* @__PURE__ */ jsxs20(
2274
2382
  "select",
2275
2383
  {
2276
2384
  id: "dlq-status",
@@ -2281,30 +2389,30 @@ function DlqConsole({ basePath = "/api", className }) {
2281
2389
  },
2282
2390
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
2283
2391
  children: [
2284
- /* @__PURE__ */ jsx22("option", { value: "", children: "All" }),
2285
- STATUS_FILTERS.map((s) => /* @__PURE__ */ jsx22("option", { value: s, children: s }, s))
2392
+ /* @__PURE__ */ jsx23("option", { value: "", children: "All" }),
2393
+ STATUS_FILTERS.map((s) => /* @__PURE__ */ jsx23("option", { value: s, children: s }, s))
2286
2394
  ]
2287
2395
  }
2288
2396
  )
2289
2397
  ] });
2290
2398
  let body;
2291
2399
  if (isLoading) {
2292
- body = /* @__PURE__ */ jsxs19(
2400
+ body = /* @__PURE__ */ jsxs20(
2293
2401
  "div",
2294
2402
  {
2295
2403
  role: "status",
2296
2404
  "aria-label": "Loading dead-letter messages",
2297
2405
  className: "flex flex-col gap-2 p-4",
2298
2406
  children: [
2299
- /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Loading dead-letter messages" }),
2300
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx22("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2407
+ /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Loading dead-letter messages" }),
2408
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2301
2409
  ]
2302
2410
  }
2303
2411
  );
2304
2412
  } else if (isError) {
2305
- body = /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2306
- /* @__PURE__ */ jsx22("p", { className: "text-sm text-foreground", children: "Failed to load dead-letter messages" }),
2307
- /* @__PURE__ */ jsx22(
2413
+ body = /* @__PURE__ */ jsxs20("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2414
+ /* @__PURE__ */ jsx23("p", { className: "text-sm text-foreground", children: "Failed to load dead-letter messages" }),
2415
+ /* @__PURE__ */ jsx23(
2308
2416
  "button",
2309
2417
  {
2310
2418
  type: "button",
@@ -2318,23 +2426,23 @@ function DlqConsole({ basePath = "/api", className }) {
2318
2426
  const rows = data?.items ?? [];
2319
2427
  const totalPages = data?.totalPages ?? 1;
2320
2428
  if (rows.length === 0) {
2321
- body = /* @__PURE__ */ jsx22("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No dead-letter messages" });
2429
+ body = /* @__PURE__ */ jsx23("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No dead-letter messages" });
2322
2430
  } else {
2323
- body = /* @__PURE__ */ jsxs19(Fragment3, { children: [
2324
- /* @__PURE__ */ jsxs19("table", { className: "w-full text-sm", children: [
2325
- /* @__PURE__ */ jsx22("thead", { children: /* @__PURE__ */ jsxs19("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2326
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Request" }),
2327
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Failure reason" }),
2328
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
2329
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
2330
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: "First seen" }),
2331
- /* @__PURE__ */ jsx22("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx22("span", { className: "sr-only", children: "Actions" }) })
2431
+ body = /* @__PURE__ */ jsxs20(Fragment3, { children: [
2432
+ /* @__PURE__ */ jsxs20("table", { className: "w-full text-sm", children: [
2433
+ /* @__PURE__ */ jsx23("thead", { children: /* @__PURE__ */ jsxs20("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2434
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Request" }),
2435
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Failure reason" }),
2436
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
2437
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
2438
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "First seen" }),
2439
+ /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Actions" }) })
2332
2440
  ] }) }),
2333
- /* @__PURE__ */ jsx22("tbody", { children: rows.map((row) => {
2441
+ /* @__PURE__ */ jsx23("tbody", { children: rows.map((row) => {
2334
2442
  const isExpanded = expandedId === row.id;
2335
- return /* @__PURE__ */ jsxs19(Fragment2, { children: [
2336
- /* @__PURE__ */ jsxs19("tr", { className: "border-b border-border", children: [
2337
- /* @__PURE__ */ jsx22("td", { className: "py-3 pe-4", children: /* @__PURE__ */ jsx22(
2443
+ return /* @__PURE__ */ jsxs20(Fragment2, { children: [
2444
+ /* @__PURE__ */ jsxs20("tr", { className: "border-b border-border", children: [
2445
+ /* @__PURE__ */ jsx23("td", { className: "py-3 pe-4", children: /* @__PURE__ */ jsx23(
2338
2446
  "button",
2339
2447
  {
2340
2448
  type: "button",
@@ -2344,12 +2452,12 @@ function DlqConsole({ basePath = "/api", className }) {
2344
2452
  children: row.requestId ?? row.id
2345
2453
  }
2346
2454
  ) }),
2347
- /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-muted-foreground", children: row.failureReason }),
2348
- /* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx22(StatusBadge4, { variant: statusVariant3(row.status), appearance: "dot", children: row.status }) }),
2349
- /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-muted-foreground", children: row.attemptCount }),
2350
- /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime4(row.firstSeenAt) }),
2351
- /* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
2352
- /* @__PURE__ */ jsx22(
2455
+ /* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-muted-foreground", children: row.failureReason }),
2456
+ /* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx23(StatusBadge4, { variant: statusVariant3(row.status), appearance: "dot", children: row.status }) }),
2457
+ /* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-muted-foreground", children: row.attemptCount }),
2458
+ /* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime4(row.firstSeenAt) }),
2459
+ /* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2", children: [
2460
+ /* @__PURE__ */ jsx23(
2353
2461
  "button",
2354
2462
  {
2355
2463
  type: "button",
@@ -2359,7 +2467,7 @@ function DlqConsole({ basePath = "/api", className }) {
2359
2467
  children: "Replay"
2360
2468
  }
2361
2469
  ),
2362
- /* @__PURE__ */ jsx22(
2470
+ /* @__PURE__ */ jsx23(
2363
2471
  "button",
2364
2472
  {
2365
2473
  type: "button",
@@ -2371,12 +2479,12 @@ function DlqConsole({ basePath = "/api", className }) {
2371
2479
  )
2372
2480
  ] }) })
2373
2481
  ] }),
2374
- isExpanded && /* @__PURE__ */ jsx22("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx22("td", { colSpan: 6, className: "bg-muted/40", children: /* @__PURE__ */ jsx22(DlqMessageDetailRow, { id: row.id, basePath }) }) })
2482
+ isExpanded && /* @__PURE__ */ jsx23("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx23("td", { colSpan: 6, className: "bg-muted/40", children: /* @__PURE__ */ jsx23(DlqMessageDetailRow, { id: row.id, basePath }) }) })
2375
2483
  ] }, row.id);
2376
2484
  }) })
2377
2485
  ] }),
2378
- /* @__PURE__ */ jsxs19("nav", { "aria-label": "Dead-letter pagination", className: "flex items-center justify-between", children: [
2379
- /* @__PURE__ */ jsx22(
2486
+ /* @__PURE__ */ jsxs20("nav", { "aria-label": "Dead-letter pagination", className: "flex items-center justify-between", children: [
2487
+ /* @__PURE__ */ jsx23(
2380
2488
  "button",
2381
2489
  {
2382
2490
  type: "button",
@@ -2386,13 +2494,13 @@ function DlqConsole({ basePath = "/api", className }) {
2386
2494
  children: "Previous"
2387
2495
  }
2388
2496
  ),
2389
- /* @__PURE__ */ jsxs19("span", { className: "text-xs text-muted-foreground", children: [
2497
+ /* @__PURE__ */ jsxs20("span", { className: "text-xs text-muted-foreground", children: [
2390
2498
  "Page ",
2391
2499
  page,
2392
2500
  " of ",
2393
2501
  totalPages
2394
2502
  ] }),
2395
- /* @__PURE__ */ jsx22(
2503
+ /* @__PURE__ */ jsx23(
2396
2504
  "button",
2397
2505
  {
2398
2506
  type: "button",
@@ -2406,9 +2514,9 @@ function DlqConsole({ basePath = "/api", className }) {
2406
2514
  ] });
2407
2515
  }
2408
2516
  }
2409
- return /* @__PURE__ */ jsxs19("section", { "aria-label": "Dead-letter queue", className: cn20("flex flex-col gap-4", className), children: [
2410
- /* @__PURE__ */ jsxs19("header", { className: "flex items-center justify-between", children: [
2411
- /* @__PURE__ */ jsx22("h2", { className: "text-sm font-semibold text-foreground", children: "Dead-letter queue" }),
2517
+ return /* @__PURE__ */ jsxs20("section", { "aria-label": "Dead-letter queue", className: cn21("flex flex-col gap-4", className), children: [
2518
+ /* @__PURE__ */ jsxs20("header", { className: "flex items-center justify-between", children: [
2519
+ /* @__PURE__ */ jsx23("h2", { className: "text-sm font-semibold text-foreground", children: "Dead-letter queue" }),
2412
2520
  filterControl
2413
2521
  ] }),
2414
2522
  body
@@ -2416,10 +2524,10 @@ function DlqConsole({ basePath = "/api", className }) {
2416
2524
  }
2417
2525
 
2418
2526
  // src/catalog-editor.tsx
2419
- import { useMemo as useMemo3, useState as useState11 } from "react";
2420
- import { cn as cn21, useToast as useToast10 } from "@quanticjs/react-ui";
2527
+ import { useMemo as useMemo3, useState as useState12 } from "react";
2528
+ import { cn as cn22, useToast as useToast10 } from "@quanticjs/react-ui";
2421
2529
  import { useApiMutation as useApiMutation11, useApiQuery as useApiQuery16 } from "@quanticjs/react-query";
2422
- import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
2530
+ import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
2423
2531
  function normalize2(data) {
2424
2532
  if (!data) return [];
2425
2533
  if (Array.isArray(data)) return data;
@@ -2432,12 +2540,12 @@ function normalize2(data) {
2432
2540
  }
2433
2541
  function CatalogEditor({ basePath = "/api", className }) {
2434
2542
  const toast = useToast10();
2435
- const [filter, setFilter] = useState11("");
2436
- const [editingId, setEditingId] = useState11(null);
2437
- const [editValue, setEditValue] = useState11("");
2438
- const [newKey, setNewKey] = useState11("");
2439
- const [newLocale, setNewLocale] = useState11("");
2440
- const [newValue, setNewValue] = useState11("");
2543
+ const [filter, setFilter] = useState12("");
2544
+ const [editingId, setEditingId] = useState12(null);
2545
+ const [editValue, setEditValue] = useState12("");
2546
+ const [newKey, setNewKey] = useState12("");
2547
+ const [newLocale, setNewLocale] = useState12("");
2548
+ const [newValue, setNewValue] = useState12("");
2441
2549
  const { data, isLoading, isError, refetch } = useApiQuery16(["i18n-catalog"], (client) => client.get(`${basePath}/i18n/catalog/export`));
2442
2550
  const onMutationError = (error) => toast.error(error.isServerError ? "Something went wrong" : error.title, {
2443
2551
  description: error.isServerError ? `Please try again. (ref: ${error.correlationId ?? "unknown"})` : `${error.detail ?? ""} (ref: ${error.correlationId ?? "unknown"})`
@@ -2501,10 +2609,10 @@ function CatalogEditor({ basePath = "/api", className }) {
2501
2609
  setEditingId(`${entry.key}:${entry.locale}`);
2502
2610
  setEditValue(entry.value);
2503
2611
  };
2504
- const addForm = /* @__PURE__ */ jsxs20("form", { onSubmit: onAdd, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2505
- /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
2506
- /* @__PURE__ */ jsx23("label", { htmlFor: "catalog-new-key", className: "text-sm font-medium text-foreground", children: "Key" }),
2507
- /* @__PURE__ */ jsx23(
2612
+ const addForm = /* @__PURE__ */ jsxs21("form", { onSubmit: onAdd, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2613
+ /* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-1", children: [
2614
+ /* @__PURE__ */ jsx24("label", { htmlFor: "catalog-new-key", className: "text-sm font-medium text-foreground", children: "Key" }),
2615
+ /* @__PURE__ */ jsx24(
2508
2616
  "input",
2509
2617
  {
2510
2618
  id: "catalog-new-key",
@@ -2515,9 +2623,9 @@ function CatalogEditor({ basePath = "/api", className }) {
2515
2623
  }
2516
2624
  )
2517
2625
  ] }),
2518
- /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
2519
- /* @__PURE__ */ jsx23("label", { htmlFor: "catalog-new-locale", className: "text-sm font-medium text-foreground", children: "Locale" }),
2520
- /* @__PURE__ */ jsx23(
2626
+ /* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-1", children: [
2627
+ /* @__PURE__ */ jsx24("label", { htmlFor: "catalog-new-locale", className: "text-sm font-medium text-foreground", children: "Locale" }),
2628
+ /* @__PURE__ */ jsx24(
2521
2629
  "input",
2522
2630
  {
2523
2631
  id: "catalog-new-locale",
@@ -2528,9 +2636,9 @@ function CatalogEditor({ basePath = "/api", className }) {
2528
2636
  }
2529
2637
  )
2530
2638
  ] }),
2531
- /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
2532
- /* @__PURE__ */ jsx23("label", { htmlFor: "catalog-new-value", className: "text-sm font-medium text-foreground", children: "Value" }),
2533
- /* @__PURE__ */ jsx23(
2639
+ /* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-1", children: [
2640
+ /* @__PURE__ */ jsx24("label", { htmlFor: "catalog-new-value", className: "text-sm font-medium text-foreground", children: "Value" }),
2641
+ /* @__PURE__ */ jsx24(
2534
2642
  "input",
2535
2643
  {
2536
2644
  id: "catalog-new-value",
@@ -2541,7 +2649,7 @@ function CatalogEditor({ basePath = "/api", className }) {
2541
2649
  }
2542
2650
  )
2543
2651
  ] }),
2544
- /* @__PURE__ */ jsx23(
2652
+ /* @__PURE__ */ jsx24(
2545
2653
  "button",
2546
2654
  {
2547
2655
  type: "submit",
@@ -2551,9 +2659,9 @@ function CatalogEditor({ basePath = "/api", className }) {
2551
2659
  }
2552
2660
  )
2553
2661
  ] });
2554
- const filterInput = /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-1", children: [
2555
- /* @__PURE__ */ jsx23("label", { htmlFor: "catalog-filter", className: "text-sm font-medium text-foreground", children: "Filter by key" }),
2556
- /* @__PURE__ */ jsx23(
2662
+ const filterInput = /* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-1", children: [
2663
+ /* @__PURE__ */ jsx24("label", { htmlFor: "catalog-filter", className: "text-sm font-medium text-foreground", children: "Filter by key" }),
2664
+ /* @__PURE__ */ jsx24(
2557
2665
  "input",
2558
2666
  {
2559
2667
  id: "catalog-filter",
@@ -2566,14 +2674,14 @@ function CatalogEditor({ basePath = "/api", className }) {
2566
2674
  ] });
2567
2675
  let body;
2568
2676
  if (isLoading) {
2569
- body = /* @__PURE__ */ jsxs20("div", { role: "status", "aria-label": "Loading catalog", className: "flex flex-col gap-2 p-4", children: [
2570
- /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Loading catalog" }),
2571
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx23("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2677
+ body = /* @__PURE__ */ jsxs21("div", { role: "status", "aria-label": "Loading catalog", className: "flex flex-col gap-2 p-4", children: [
2678
+ /* @__PURE__ */ jsx24("span", { className: "sr-only", children: "Loading catalog" }),
2679
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx24("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2572
2680
  ] });
2573
2681
  } else if (isError) {
2574
- body = /* @__PURE__ */ jsxs20("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2575
- /* @__PURE__ */ jsx23("p", { className: "text-sm text-foreground", children: "Failed to load catalog" }),
2576
- /* @__PURE__ */ jsx23(
2682
+ body = /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2683
+ /* @__PURE__ */ jsx24("p", { className: "text-sm text-foreground", children: "Failed to load catalog" }),
2684
+ /* @__PURE__ */ jsx24(
2577
2685
  "button",
2578
2686
  {
2579
2687
  type: "button",
@@ -2584,22 +2692,22 @@ function CatalogEditor({ basePath = "/api", className }) {
2584
2692
  )
2585
2693
  ] });
2586
2694
  } else if (filtered.length === 0) {
2587
- body = /* @__PURE__ */ jsx23("div", { className: "p-6 text-center text-sm text-muted-foreground", children: entries.length === 0 ? "No catalog entries" : "No entries match your filter" });
2695
+ body = /* @__PURE__ */ jsx24("div", { className: "p-6 text-center text-sm text-muted-foreground", children: entries.length === 0 ? "No catalog entries" : "No entries match your filter" });
2588
2696
  } else {
2589
- body = /* @__PURE__ */ jsxs20("table", { className: "w-full text-sm", children: [
2590
- /* @__PURE__ */ jsx23("thead", { children: /* @__PURE__ */ jsxs20("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2591
- /* @__PURE__ */ jsx23("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2592
- /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locale" }),
2593
- /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Value" }),
2594
- /* @__PURE__ */ jsx23("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx23("span", { className: "sr-only", children: "Actions" }) })
2697
+ body = /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
2698
+ /* @__PURE__ */ jsx24("thead", { children: /* @__PURE__ */ jsxs21("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2699
+ /* @__PURE__ */ jsx24("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2700
+ /* @__PURE__ */ jsx24("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locale" }),
2701
+ /* @__PURE__ */ jsx24("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Value" }),
2702
+ /* @__PURE__ */ jsx24("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx24("span", { className: "sr-only", children: "Actions" }) })
2595
2703
  ] }) }),
2596
- /* @__PURE__ */ jsx23("tbody", { children: filtered.map((entry) => {
2704
+ /* @__PURE__ */ jsx24("tbody", { children: filtered.map((entry) => {
2597
2705
  const rowId = `${entry.key}:${entry.locale}`;
2598
2706
  const isEditing = editingId === rowId;
2599
- return /* @__PURE__ */ jsxs20("tr", { className: "border-b border-border", children: [
2600
- /* @__PURE__ */ jsx23("td", { className: "py-3 pe-4 font-mono text-foreground", children: entry.key }),
2601
- /* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-foreground", children: entry.locale }),
2602
- /* @__PURE__ */ jsx23("td", { className: "px-4 py-3 text-foreground", children: isEditing ? /* @__PURE__ */ jsx23(
2707
+ return /* @__PURE__ */ jsxs21("tr", { className: "border-b border-border", children: [
2708
+ /* @__PURE__ */ jsx24("td", { className: "py-3 pe-4 font-mono text-foreground", children: entry.key }),
2709
+ /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-foreground", children: entry.locale }),
2710
+ /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-foreground", children: isEditing ? /* @__PURE__ */ jsx24(
2603
2711
  "input",
2604
2712
  {
2605
2713
  type: "text",
@@ -2609,8 +2717,8 @@ function CatalogEditor({ basePath = "/api", className }) {
2609
2717
  className: "w-full rounded-md border border-border bg-background px-3 py-1.5 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
2610
2718
  }
2611
2719
  ) : entry.value }),
2612
- /* @__PURE__ */ jsx23("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx23("div", { className: "flex items-center gap-2", children: isEditing ? /* @__PURE__ */ jsxs20(Fragment4, { children: [
2613
- /* @__PURE__ */ jsx23(
2720
+ /* @__PURE__ */ jsx24("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx24("div", { className: "flex items-center gap-2", children: isEditing ? /* @__PURE__ */ jsxs21(Fragment4, { children: [
2721
+ /* @__PURE__ */ jsx24(
2614
2722
  "button",
2615
2723
  {
2616
2724
  type: "button",
@@ -2624,7 +2732,7 @@ function CatalogEditor({ basePath = "/api", className }) {
2624
2732
  children: "Save"
2625
2733
  }
2626
2734
  ),
2627
- /* @__PURE__ */ jsx23(
2735
+ /* @__PURE__ */ jsx24(
2628
2736
  "button",
2629
2737
  {
2630
2738
  type: "button",
@@ -2633,8 +2741,8 @@ function CatalogEditor({ basePath = "/api", className }) {
2633
2741
  children: "Cancel"
2634
2742
  }
2635
2743
  )
2636
- ] }) : /* @__PURE__ */ jsxs20(Fragment4, { children: [
2637
- /* @__PURE__ */ jsx23(
2744
+ ] }) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
2745
+ /* @__PURE__ */ jsx24(
2638
2746
  "button",
2639
2747
  {
2640
2748
  type: "button",
@@ -2643,7 +2751,7 @@ function CatalogEditor({ basePath = "/api", className }) {
2643
2751
  children: "Edit"
2644
2752
  }
2645
2753
  ),
2646
- /* @__PURE__ */ jsx23(
2754
+ /* @__PURE__ */ jsx24(
2647
2755
  "button",
2648
2756
  {
2649
2757
  type: "button",
@@ -2658,7 +2766,7 @@ function CatalogEditor({ basePath = "/api", className }) {
2658
2766
  }) })
2659
2767
  ] });
2660
2768
  }
2661
- return /* @__PURE__ */ jsxs20("section", { "aria-label": "Catalog editor", className: cn21("flex flex-col gap-4", className), children: [
2769
+ return /* @__PURE__ */ jsxs21("section", { "aria-label": "Catalog editor", className: cn22("flex flex-col gap-4", className), children: [
2662
2770
  addForm,
2663
2771
  filterInput,
2664
2772
  body
@@ -2666,9 +2774,9 @@ function CatalogEditor({ basePath = "/api", className }) {
2666
2774
  }
2667
2775
 
2668
2776
  // src/missing-translations-panel.tsx
2669
- import { cn as cn22 } from "@quanticjs/react-ui";
2777
+ import { cn as cn23 } from "@quanticjs/react-ui";
2670
2778
  import { useApiQuery as useApiQuery17 } from "@quanticjs/react-query";
2671
- import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
2779
+ import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
2672
2780
  function normalize3(data) {
2673
2781
  if (Array.isArray(data)) return data;
2674
2782
  return data?.missing ?? [];
@@ -2682,23 +2790,23 @@ function MissingTranslationsPanel({
2682
2790
  (client) => client.get(`${basePath}/i18n/catalog/missing`)
2683
2791
  );
2684
2792
  if (isLoading) {
2685
- return /* @__PURE__ */ jsxs21(
2793
+ return /* @__PURE__ */ jsxs22(
2686
2794
  "div",
2687
2795
  {
2688
2796
  role: "status",
2689
2797
  "aria-label": "Loading missing translations",
2690
- className: cn22("flex flex-col gap-2 p-4", className),
2798
+ className: cn23("flex flex-col gap-2 p-4", className),
2691
2799
  children: [
2692
- /* @__PURE__ */ jsx24("span", { className: "sr-only", children: "Loading missing translations" }),
2693
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx24("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2800
+ /* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Loading missing translations" }),
2801
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx25("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2694
2802
  ]
2695
2803
  }
2696
2804
  );
2697
2805
  }
2698
2806
  if (isError) {
2699
- return /* @__PURE__ */ jsxs21("div", { className: cn22("flex flex-col items-start gap-3 p-4", className), children: [
2700
- /* @__PURE__ */ jsx24("p", { className: "text-sm text-foreground", children: "Failed to load missing translations" }),
2701
- /* @__PURE__ */ jsx24(
2807
+ return /* @__PURE__ */ jsxs22("div", { className: cn23("flex flex-col items-start gap-3 p-4", className), children: [
2808
+ /* @__PURE__ */ jsx25("p", { className: "text-sm text-foreground", children: "Failed to load missing translations" }),
2809
+ /* @__PURE__ */ jsx25(
2702
2810
  "button",
2703
2811
  {
2704
2812
  type: "button",
@@ -2711,26 +2819,26 @@ function MissingTranslationsPanel({
2711
2819
  }
2712
2820
  const rows = normalize3(data);
2713
2821
  if (rows.length === 0) {
2714
- return /* @__PURE__ */ jsx24("div", { className: cn22("p-6 text-center text-sm text-muted-foreground", className), children: "No missing translations" });
2822
+ return /* @__PURE__ */ jsx25("div", { className: cn23("p-6 text-center text-sm text-muted-foreground", className), children: "No missing translations" });
2715
2823
  }
2716
- return /* @__PURE__ */ jsx24("section", { "aria-label": "Missing translations", className: cn22("flex flex-col gap-3", className), children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
2717
- /* @__PURE__ */ jsx24("thead", { children: /* @__PURE__ */ jsxs21("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2718
- /* @__PURE__ */ jsx24("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2719
- /* @__PURE__ */ jsx24("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locale" }),
2720
- /* @__PURE__ */ jsx24("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Type" })
2824
+ return /* @__PURE__ */ jsx25("section", { "aria-label": "Missing translations", className: cn23("flex flex-col gap-3", className), children: /* @__PURE__ */ jsxs22("table", { className: "w-full text-sm", children: [
2825
+ /* @__PURE__ */ jsx25("thead", { children: /* @__PURE__ */ jsxs22("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2826
+ /* @__PURE__ */ jsx25("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2827
+ /* @__PURE__ */ jsx25("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Locale" }),
2828
+ /* @__PURE__ */ jsx25("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Type" })
2721
2829
  ] }) }),
2722
- /* @__PURE__ */ jsx24("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxs21("tr", { className: "border-b border-border", children: [
2723
- /* @__PURE__ */ jsx24("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.key }),
2724
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-foreground", children: row.locale }),
2725
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-muted-foreground", children: row.type ?? "\u2014" })
2830
+ /* @__PURE__ */ jsx25("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxs22("tr", { className: "border-b border-border", children: [
2831
+ /* @__PURE__ */ jsx25("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.key }),
2832
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-foreground", children: row.locale }),
2833
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-muted-foreground", children: row.type ?? "\u2014" })
2726
2834
  ] }, `${row.key}:${row.locale}:${i}`)) })
2727
2835
  ] }) });
2728
2836
  }
2729
2837
 
2730
2838
  // src/fallback-report-panel.tsx
2731
- import { cn as cn23 } from "@quanticjs/react-ui";
2839
+ import { cn as cn24 } from "@quanticjs/react-ui";
2732
2840
  import { useApiQuery as useApiQuery18 } from "@quanticjs/react-query";
2733
- import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
2841
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
2734
2842
  function normalize4(data) {
2735
2843
  if (Array.isArray(data)) return data;
2736
2844
  return data?.entries ?? [];
@@ -2741,23 +2849,23 @@ function FallbackReportPanel({ basePath = "/api", className }) {
2741
2849
  (client) => client.get(`${basePath}/i18n/catalog/fallback-report`)
2742
2850
  );
2743
2851
  if (isLoading) {
2744
- return /* @__PURE__ */ jsxs22(
2852
+ return /* @__PURE__ */ jsxs23(
2745
2853
  "div",
2746
2854
  {
2747
2855
  role: "status",
2748
2856
  "aria-label": "Loading fallback report",
2749
- className: cn23("flex flex-col gap-2 p-4", className),
2857
+ className: cn24("flex flex-col gap-2 p-4", className),
2750
2858
  children: [
2751
- /* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Loading fallback report" }),
2752
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx25("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2859
+ /* @__PURE__ */ jsx26("span", { className: "sr-only", children: "Loading fallback report" }),
2860
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx26("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2753
2861
  ]
2754
2862
  }
2755
2863
  );
2756
2864
  }
2757
2865
  if (isError) {
2758
- return /* @__PURE__ */ jsxs22("div", { className: cn23("flex flex-col items-start gap-3 p-4", className), children: [
2759
- /* @__PURE__ */ jsx25("p", { className: "text-sm text-foreground", children: "Failed to load fallback report" }),
2760
- /* @__PURE__ */ jsx25(
2866
+ return /* @__PURE__ */ jsxs23("div", { className: cn24("flex flex-col items-start gap-3 p-4", className), children: [
2867
+ /* @__PURE__ */ jsx26("p", { className: "text-sm text-foreground", children: "Failed to load fallback report" }),
2868
+ /* @__PURE__ */ jsx26(
2761
2869
  "button",
2762
2870
  {
2763
2871
  type: "button",
@@ -2770,38 +2878,38 @@ function FallbackReportPanel({ basePath = "/api", className }) {
2770
2878
  }
2771
2879
  const rows = normalize4(data);
2772
2880
  if (rows.length === 0) {
2773
- return /* @__PURE__ */ jsx25("div", { className: cn23("p-6 text-center text-sm text-muted-foreground", className), children: "No fallbacks reported" });
2881
+ return /* @__PURE__ */ jsx26("div", { className: cn24("p-6 text-center text-sm text-muted-foreground", className), children: "No fallbacks reported" });
2774
2882
  }
2775
- return /* @__PURE__ */ jsx25("section", { "aria-label": "Fallback report", className: cn23("flex flex-col gap-3", className), children: /* @__PURE__ */ jsxs22("table", { className: "w-full text-sm", children: [
2776
- /* @__PURE__ */ jsx25("thead", { children: /* @__PURE__ */ jsxs22("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2777
- /* @__PURE__ */ jsx25("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2778
- /* @__PURE__ */ jsx25("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Requested" }),
2779
- /* @__PURE__ */ jsx25("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Resolved" }),
2780
- /* @__PURE__ */ jsx25("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Chain" })
2883
+ return /* @__PURE__ */ jsx26("section", { "aria-label": "Fallback report", className: cn24("flex flex-col gap-3", className), children: /* @__PURE__ */ jsxs23("table", { className: "w-full text-sm", children: [
2884
+ /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsxs23("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2885
+ /* @__PURE__ */ jsx26("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Key" }),
2886
+ /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Requested" }),
2887
+ /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Resolved" }),
2888
+ /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Chain" })
2781
2889
  ] }) }),
2782
- /* @__PURE__ */ jsx25("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxs22("tr", { className: "border-b border-border", children: [
2783
- /* @__PURE__ */ jsx25("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.key }),
2784
- /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-foreground", children: row.requestedLocale }),
2785
- /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-foreground", children: row.resolvedLocale }),
2786
- /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-muted-foreground", children: row.steps && row.steps.length > 0 ? /* @__PURE__ */ jsx25("ol", { className: "flex flex-wrap items-center gap-1", children: row.steps.map((step, si) => /* @__PURE__ */ jsxs22("li", { className: "flex items-center gap-1", children: [
2787
- /* @__PURE__ */ jsx25("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs text-foreground", children: step }),
2788
- si < (row.steps?.length ?? 0) - 1 && /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2192" })
2890
+ /* @__PURE__ */ jsx26("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxs23("tr", { className: "border-b border-border", children: [
2891
+ /* @__PURE__ */ jsx26("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.key }),
2892
+ /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-foreground", children: row.requestedLocale }),
2893
+ /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-foreground", children: row.resolvedLocale }),
2894
+ /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-muted-foreground", children: row.steps && row.steps.length > 0 ? /* @__PURE__ */ jsx26("ol", { className: "flex flex-wrap items-center gap-1", children: row.steps.map((step, si) => /* @__PURE__ */ jsxs23("li", { className: "flex items-center gap-1", children: [
2895
+ /* @__PURE__ */ jsx26("span", { className: "rounded bg-muted px-1.5 py-0.5 text-xs text-foreground", children: step }),
2896
+ si < (row.steps?.length ?? 0) - 1 && /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", className: "text-muted-foreground", children: "\u2192" })
2789
2897
  ] }, `${step}:${si}`)) }) : "\u2014" })
2790
2898
  ] }, `${row.key}:${row.requestedLocale}:${i}`)) })
2791
2899
  ] }) });
2792
2900
  }
2793
2901
 
2794
2902
  // src/recipient-admin-panel.tsx
2795
- import { useState as useState12 } from "react";
2796
- import { cn as cn24, formatDateTime as formatDateTime5, useToast as useToast11 } from "@quanticjs/react-ui";
2903
+ import { useState as useState13 } from "react";
2904
+ import { cn as cn25, formatDateTime as formatDateTime5, useToast as useToast11 } from "@quanticjs/react-ui";
2797
2905
  import { useApiMutation as useApiMutation12, useApiQuery as useApiQuery19 } from "@quanticjs/react-query";
2798
- import { Fragment as Fragment5, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
2906
+ import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
2799
2907
  var LIMIT5 = 20;
2800
2908
  function RecipientAdminPanel({ basePath = "/api", className }) {
2801
2909
  const toast = useToast11();
2802
- const [page, setPage] = useState12(1);
2803
- const [search, setSearch] = useState12("");
2804
- const [query, setQuery] = useState12("");
2910
+ const [page, setPage] = useState13(1);
2911
+ const [search, setSearch] = useState13("");
2912
+ const [query, setQuery] = useState13("");
2805
2913
  const { data, isLoading, isError, refetch } = useApiQuery19(
2806
2914
  ["recipients", page, query],
2807
2915
  (client) => client.get(
@@ -2846,10 +2954,10 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2846
2954
  if (row.consentSms) active.push("sms");
2847
2955
  return active.length > 0 ? active.join(", ") : "none";
2848
2956
  };
2849
- const searchForm = /* @__PURE__ */ jsxs23("form", { onSubmit: onSearch, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2850
- /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-1", children: [
2851
- /* @__PURE__ */ jsx26("label", { htmlFor: "recipient-search", className: "text-sm font-medium text-foreground", children: "Search recipients" }),
2852
- /* @__PURE__ */ jsx26(
2957
+ const searchForm = /* @__PURE__ */ jsxs24("form", { onSubmit: onSearch, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
2958
+ /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-1", children: [
2959
+ /* @__PURE__ */ jsx27("label", { htmlFor: "recipient-search", className: "text-sm font-medium text-foreground", children: "Search recipients" }),
2960
+ /* @__PURE__ */ jsx27(
2853
2961
  "input",
2854
2962
  {
2855
2963
  id: "recipient-search",
@@ -2860,7 +2968,7 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2860
2968
  }
2861
2969
  )
2862
2970
  ] }),
2863
- /* @__PURE__ */ jsx26(
2971
+ /* @__PURE__ */ jsx27(
2864
2972
  "button",
2865
2973
  {
2866
2974
  type: "submit",
@@ -2871,14 +2979,14 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2871
2979
  ] });
2872
2980
  let body;
2873
2981
  if (isLoading) {
2874
- body = /* @__PURE__ */ jsxs23("div", { role: "status", "aria-label": "Loading recipients", className: "flex flex-col gap-2 p-4", children: [
2875
- /* @__PURE__ */ jsx26("span", { className: "sr-only", children: "Loading recipients" }),
2876
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx26("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2982
+ body = /* @__PURE__ */ jsxs24("div", { role: "status", "aria-label": "Loading recipients", className: "flex flex-col gap-2 p-4", children: [
2983
+ /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Loading recipients" }),
2984
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx27("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
2877
2985
  ] });
2878
2986
  } else if (isError) {
2879
- body = /* @__PURE__ */ jsxs23("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2880
- /* @__PURE__ */ jsx26("p", { className: "text-sm text-foreground", children: "Failed to load recipients" }),
2881
- /* @__PURE__ */ jsx26(
2987
+ body = /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start gap-3 p-4", children: [
2988
+ /* @__PURE__ */ jsx27("p", { className: "text-sm text-foreground", children: "Failed to load recipients" }),
2989
+ /* @__PURE__ */ jsx27(
2882
2990
  "button",
2883
2991
  {
2884
2992
  type: "button",
@@ -2892,26 +3000,26 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2892
3000
  const rows = data?.items ?? [];
2893
3001
  const totalPages = data?.totalPages ?? 1;
2894
3002
  if (rows.length === 0) {
2895
- body = /* @__PURE__ */ jsx26("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No recipients" });
3003
+ body = /* @__PURE__ */ jsx27("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No recipients" });
2896
3004
  } else {
2897
- body = /* @__PURE__ */ jsxs23(Fragment5, { children: [
2898
- /* @__PURE__ */ jsxs23("table", { className: "w-full text-sm", children: [
2899
- /* @__PURE__ */ jsx26("thead", { children: /* @__PURE__ */ jsxs23("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
2900
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "User" }),
2901
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Email" }),
2902
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Phone" }),
2903
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Consents" }),
2904
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
2905
- /* @__PURE__ */ jsx26("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx26("span", { className: "sr-only", children: "Actions" }) })
3005
+ body = /* @__PURE__ */ jsxs24(Fragment5, { children: [
3006
+ /* @__PURE__ */ jsxs24("table", { className: "w-full text-sm", children: [
3007
+ /* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3008
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "User" }),
3009
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Email" }),
3010
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Phone" }),
3011
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Consents" }),
3012
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
3013
+ /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Actions" }) })
2906
3014
  ] }) }),
2907
- /* @__PURE__ */ jsx26("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs23("tr", { className: "border-b border-border", children: [
2908
- /* @__PURE__ */ jsx26("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.userId }),
2909
- /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-foreground", children: row.email ?? "\u2014" }),
2910
- /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-foreground", children: row.phone ?? "\u2014" }),
2911
- /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-muted-foreground", children: consents(row) }),
2912
- /* @__PURE__ */ jsx26("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime5(row.createdAt) }),
2913
- /* @__PURE__ */ jsx26("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2", children: [
2914
- /* @__PURE__ */ jsx26(
3015
+ /* @__PURE__ */ jsx27("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border", children: [
3016
+ /* @__PURE__ */ jsx27("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.userId }),
3017
+ /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-foreground", children: row.email ?? "\u2014" }),
3018
+ /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-foreground", children: row.phone ?? "\u2014" }),
3019
+ /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-muted-foreground", children: consents(row) }),
3020
+ /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime5(row.createdAt) }),
3021
+ /* @__PURE__ */ jsx27("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
3022
+ /* @__PURE__ */ jsx27(
2915
3023
  "button",
2916
3024
  {
2917
3025
  type: "button",
@@ -2921,7 +3029,7 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2921
3029
  children: "Export"
2922
3030
  }
2923
3031
  ),
2924
- /* @__PURE__ */ jsx26(
3032
+ /* @__PURE__ */ jsx27(
2925
3033
  "button",
2926
3034
  {
2927
3035
  type: "button",
@@ -2934,8 +3042,8 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2934
3042
  ] }) })
2935
3043
  ] }, row.userId)) })
2936
3044
  ] }),
2937
- /* @__PURE__ */ jsxs23("nav", { "aria-label": "Recipient pagination", className: "flex items-center justify-between", children: [
2938
- /* @__PURE__ */ jsx26(
3045
+ /* @__PURE__ */ jsxs24("nav", { "aria-label": "Recipient pagination", className: "flex items-center justify-between", children: [
3046
+ /* @__PURE__ */ jsx27(
2939
3047
  "button",
2940
3048
  {
2941
3049
  type: "button",
@@ -2945,13 +3053,13 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2945
3053
  children: "Previous"
2946
3054
  }
2947
3055
  ),
2948
- /* @__PURE__ */ jsxs23("span", { className: "text-xs text-muted-foreground", children: [
3056
+ /* @__PURE__ */ jsxs24("span", { className: "text-xs text-muted-foreground", children: [
2949
3057
  "Page ",
2950
3058
  page,
2951
3059
  " of ",
2952
3060
  totalPages
2953
3061
  ] }),
2954
- /* @__PURE__ */ jsx26(
3062
+ /* @__PURE__ */ jsx27(
2955
3063
  "button",
2956
3064
  {
2957
3065
  type: "button",
@@ -2965,17 +3073,17 @@ function RecipientAdminPanel({ basePath = "/api", className }) {
2965
3073
  ] });
2966
3074
  }
2967
3075
  }
2968
- return /* @__PURE__ */ jsxs23("section", { "aria-label": "Recipient administration", className: cn24("flex flex-col gap-4", className), children: [
3076
+ return /* @__PURE__ */ jsxs24("section", { "aria-label": "Recipient administration", className: cn25("flex flex-col gap-4", className), children: [
2969
3077
  searchForm,
2970
3078
  body
2971
3079
  ] });
2972
3080
  }
2973
3081
 
2974
3082
  // src/webhook-endpoint-manager.tsx
2975
- import { Fragment as Fragment6, useState as useState13 } from "react";
2976
- import { cn as cn25, formatDateTime as formatDateTime6, useToast as useToast12, StatusBadge as StatusBadge5 } from "@quanticjs/react-ui";
3083
+ import { Fragment as Fragment6, useState as useState14 } from "react";
3084
+ import { cn as cn26, formatDateTime as formatDateTime6, useToast as useToast12, StatusBadge as StatusBadge5 } from "@quanticjs/react-ui";
2977
3085
  import { useApiMutation as useApiMutation13, useApiQuery as useApiQuery20 } from "@quanticjs/react-query";
2978
- import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
3086
+ import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
2979
3087
  var EVENT_TYPES = [
2980
3088
  "notification.sent",
2981
3089
  "notification.delivered",
@@ -3001,15 +3109,15 @@ function WebhookDeliveries({ endpointId, basePath }) {
3001
3109
  (client) => client.get(`${basePath}/webhook-endpoints/${endpointId}/deliveries`)
3002
3110
  );
3003
3111
  if (isLoading) {
3004
- return /* @__PURE__ */ jsxs24("div", { role: "status", "aria-label": "Loading deliveries", className: "flex flex-col gap-2 p-3", children: [
3005
- /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Loading deliveries" }),
3006
- [0, 1].map((i) => /* @__PURE__ */ jsx27("div", { "aria-hidden": "true", className: "h-8 animate-pulse rounded bg-muted" }, i))
3112
+ return /* @__PURE__ */ jsxs25("div", { role: "status", "aria-label": "Loading deliveries", className: "flex flex-col gap-2 p-3", children: [
3113
+ /* @__PURE__ */ jsx28("span", { className: "sr-only", children: "Loading deliveries" }),
3114
+ [0, 1].map((i) => /* @__PURE__ */ jsx28("div", { "aria-hidden": "true", className: "h-8 animate-pulse rounded bg-muted" }, i))
3007
3115
  ] });
3008
3116
  }
3009
3117
  if (isError) {
3010
- return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start gap-2 p-3", children: [
3011
- /* @__PURE__ */ jsx27("p", { className: "text-sm text-foreground", children: "Failed to load deliveries" }),
3012
- /* @__PURE__ */ jsx27(
3118
+ return /* @__PURE__ */ jsxs25("div", { className: "flex flex-col items-start gap-2 p-3", children: [
3119
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-foreground", children: "Failed to load deliveries" }),
3120
+ /* @__PURE__ */ jsx28(
3013
3121
  "button",
3014
3122
  {
3015
3123
  type: "button",
@@ -3022,18 +3130,18 @@ function WebhookDeliveries({ endpointId, basePath }) {
3022
3130
  }
3023
3131
  const rows = normalizeDeliveries(data);
3024
3132
  if (rows.length === 0) {
3025
- return /* @__PURE__ */ jsx27("div", { className: "p-3 text-center text-sm text-muted-foreground", children: "No deliveries" });
3133
+ return /* @__PURE__ */ jsx28("div", { className: "p-3 text-center text-sm text-muted-foreground", children: "No deliveries" });
3026
3134
  }
3027
- return /* @__PURE__ */ jsxs24("table", { className: "w-full text-sm", children: [
3028
- /* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3029
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Delivery" }),
3030
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
3031
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
3135
+ return /* @__PURE__ */ jsxs25("table", { className: "w-full text-sm", children: [
3136
+ /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3137
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Delivery" }),
3138
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
3139
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
3032
3140
  ] }) }),
3033
- /* @__PURE__ */ jsx27("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border", children: [
3034
- /* @__PURE__ */ jsx27("td", { className: "py-2 pe-4 font-mono text-foreground", children: row.id }),
3035
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-2 text-muted-foreground", children: row.status }),
3036
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-2 text-muted-foreground", children: formatDateTime6(row.createdAt) })
3141
+ /* @__PURE__ */ jsx28("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border", children: [
3142
+ /* @__PURE__ */ jsx28("td", { className: "py-2 pe-4 font-mono text-foreground", children: row.id }),
3143
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-2 text-muted-foreground", children: row.status }),
3144
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-2 text-muted-foreground", children: formatDateTime6(row.createdAt) })
3037
3145
  ] }, row.id)) })
3038
3146
  ] });
3039
3147
  }
@@ -3042,11 +3150,11 @@ function WebhookEndpointManager({
3042
3150
  className
3043
3151
  }) {
3044
3152
  const toast = useToast12();
3045
- const [url, setUrl] = useState13("");
3046
- const [events, setEvents] = useState13([]);
3047
- const [active, setActive] = useState13(true);
3048
- const [urlError, setUrlError] = useState13();
3049
- const [expandedId, setExpandedId] = useState13(null);
3153
+ const [url, setUrl] = useState14("");
3154
+ const [events, setEvents] = useState14([]);
3155
+ const [active, setActive] = useState14(true);
3156
+ const [urlError, setUrlError] = useState14();
3157
+ const [expandedId, setExpandedId] = useState14(null);
3050
3158
  const { data, isLoading, isError, refetch } = useApiQuery20(["webhook-endpoints"], (client) => client.get(`${basePath}/webhook-endpoints`));
3051
3159
  const create = useApiMutation13(
3052
3160
  (client, payload) => client.post(`${basePath}/webhook-endpoints`, payload),
@@ -3108,10 +3216,10 @@ function WebhookEndpointManager({
3108
3216
  remove.mutate(id);
3109
3217
  }
3110
3218
  };
3111
- const createForm = /* @__PURE__ */ jsxs24("form", { onSubmit: onCreate, className: "flex flex-col gap-3", noValidate: true, children: [
3112
- /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-1", children: [
3113
- /* @__PURE__ */ jsx27("label", { htmlFor: "webhook-url", className: "text-sm font-medium text-foreground", children: "Endpoint URL" }),
3114
- /* @__PURE__ */ jsx27(
3219
+ const createForm = /* @__PURE__ */ jsxs25("form", { onSubmit: onCreate, className: "flex flex-col gap-3", noValidate: true, children: [
3220
+ /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-1", children: [
3221
+ /* @__PURE__ */ jsx28("label", { htmlFor: "webhook-url", className: "text-sm font-medium text-foreground", children: "Endpoint URL" }),
3222
+ /* @__PURE__ */ jsx28(
3115
3223
  "input",
3116
3224
  {
3117
3225
  id: "webhook-url",
@@ -3123,19 +3231,19 @@ function WebhookEndpointManager({
3123
3231
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring"
3124
3232
  }
3125
3233
  ),
3126
- urlError && /* @__PURE__ */ jsx27("p", { id: "webhook-url-error", className: "text-xs text-destructive", children: urlError })
3234
+ urlError && /* @__PURE__ */ jsx28("p", { id: "webhook-url-error", className: "text-xs text-destructive", children: urlError })
3127
3235
  ] }),
3128
- /* @__PURE__ */ jsxs24("fieldset", { className: "flex flex-col gap-2", children: [
3129
- /* @__PURE__ */ jsx27("legend", { className: "text-sm font-medium text-foreground", children: "Events" }),
3130
- /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-3", children: EVENT_TYPES.map((evt) => {
3236
+ /* @__PURE__ */ jsxs25("fieldset", { className: "flex flex-col gap-2", children: [
3237
+ /* @__PURE__ */ jsx28("legend", { className: "text-sm font-medium text-foreground", children: "Events" }),
3238
+ /* @__PURE__ */ jsx28("div", { className: "flex flex-wrap gap-3", children: EVENT_TYPES.map((evt) => {
3131
3239
  const id = `webhook-event-${evt}`;
3132
- return /* @__PURE__ */ jsxs24(
3240
+ return /* @__PURE__ */ jsxs25(
3133
3241
  "label",
3134
3242
  {
3135
3243
  htmlFor: id,
3136
3244
  className: "flex items-center gap-2 text-sm text-foreground",
3137
3245
  children: [
3138
- /* @__PURE__ */ jsx27(
3246
+ /* @__PURE__ */ jsx28(
3139
3247
  "input",
3140
3248
  {
3141
3249
  id,
@@ -3152,8 +3260,8 @@ function WebhookEndpointManager({
3152
3260
  );
3153
3261
  }) })
3154
3262
  ] }),
3155
- /* @__PURE__ */ jsxs24("label", { htmlFor: "webhook-active", className: "flex items-center gap-2 text-sm text-foreground", children: [
3156
- /* @__PURE__ */ jsx27(
3263
+ /* @__PURE__ */ jsxs25("label", { htmlFor: "webhook-active", className: "flex items-center gap-2 text-sm text-foreground", children: [
3264
+ /* @__PURE__ */ jsx28(
3157
3265
  "input",
3158
3266
  {
3159
3267
  id: "webhook-active",
@@ -3165,7 +3273,7 @@ function WebhookEndpointManager({
3165
3273
  ),
3166
3274
  "Active"
3167
3275
  ] }),
3168
- /* @__PURE__ */ jsx27("div", { children: /* @__PURE__ */ jsx27(
3276
+ /* @__PURE__ */ jsx28("div", { children: /* @__PURE__ */ jsx28(
3169
3277
  "button",
3170
3278
  {
3171
3279
  type: "submit",
@@ -3177,14 +3285,14 @@ function WebhookEndpointManager({
3177
3285
  ] });
3178
3286
  let body;
3179
3287
  if (isLoading) {
3180
- body = /* @__PURE__ */ jsxs24("div", { role: "status", "aria-label": "Loading webhook endpoints", className: "flex flex-col gap-2 p-4", children: [
3181
- /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Loading webhook endpoints" }),
3182
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx27("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3288
+ body = /* @__PURE__ */ jsxs25("div", { role: "status", "aria-label": "Loading webhook endpoints", className: "flex flex-col gap-2 p-4", children: [
3289
+ /* @__PURE__ */ jsx28("span", { className: "sr-only", children: "Loading webhook endpoints" }),
3290
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx28("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3183
3291
  ] });
3184
3292
  } else if (isError) {
3185
- body = /* @__PURE__ */ jsxs24("div", { className: "flex flex-col items-start gap-3 p-4", children: [
3186
- /* @__PURE__ */ jsx27("p", { className: "text-sm text-foreground", children: "Failed to load webhook endpoints" }),
3187
- /* @__PURE__ */ jsx27(
3293
+ body = /* @__PURE__ */ jsxs25("div", { className: "flex flex-col items-start gap-3 p-4", children: [
3294
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-foreground", children: "Failed to load webhook endpoints" }),
3295
+ /* @__PURE__ */ jsx28(
3188
3296
  "button",
3189
3297
  {
3190
3298
  type: "button",
@@ -3197,26 +3305,26 @@ function WebhookEndpointManager({
3197
3305
  } else {
3198
3306
  const rows = normalizeEndpoints(data);
3199
3307
  if (rows.length === 0) {
3200
- body = /* @__PURE__ */ jsx27("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No webhook endpoints" });
3308
+ body = /* @__PURE__ */ jsx28("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No webhook endpoints" });
3201
3309
  } else {
3202
- body = /* @__PURE__ */ jsxs24("table", { className: "w-full text-sm", children: [
3203
- /* @__PURE__ */ jsx27("thead", { children: /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3204
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "URL" }),
3205
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Events" }),
3206
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Active" }),
3207
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
3208
- /* @__PURE__ */ jsx27("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx27("span", { className: "sr-only", children: "Actions" }) })
3310
+ body = /* @__PURE__ */ jsxs25("table", { className: "w-full text-sm", children: [
3311
+ /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3312
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "URL" }),
3313
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Events" }),
3314
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Active" }),
3315
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
3316
+ /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx28("span", { className: "sr-only", children: "Actions" }) })
3209
3317
  ] }) }),
3210
- /* @__PURE__ */ jsx27("tbody", { children: rows.map((row) => {
3318
+ /* @__PURE__ */ jsx28("tbody", { children: rows.map((row) => {
3211
3319
  const isExpanded = expandedId === row.id;
3212
- return /* @__PURE__ */ jsxs24(Fragment6, { children: [
3213
- /* @__PURE__ */ jsxs24("tr", { className: "border-b border-border", children: [
3214
- /* @__PURE__ */ jsx27("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.url }),
3215
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-muted-foreground", children: row.events.length > 0 ? row.events.join(", ") : "\u2014" }),
3216
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx27(StatusBadge5, { variant: row.active ? "success" : "neutral", appearance: "dot", children: row.active ? "active" : "inactive" }) }),
3217
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime6(row.createdAt) }),
3218
- /* @__PURE__ */ jsx27("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
3219
- /* @__PURE__ */ jsx27(
3320
+ return /* @__PURE__ */ jsxs25(Fragment6, { children: [
3321
+ /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border", children: [
3322
+ /* @__PURE__ */ jsx28("td", { className: "py-3 pe-4 font-mono text-foreground", children: row.url }),
3323
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-3 text-muted-foreground", children: row.events.length > 0 ? row.events.join(", ") : "\u2014" }),
3324
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx28(StatusBadge5, { variant: row.active ? "success" : "neutral", appearance: "dot", children: row.active ? "active" : "inactive" }) }),
3325
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime6(row.createdAt) }),
3326
+ /* @__PURE__ */ jsx28("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
3327
+ /* @__PURE__ */ jsx28(
3220
3328
  "button",
3221
3329
  {
3222
3330
  type: "button",
@@ -3226,7 +3334,7 @@ function WebhookEndpointManager({
3226
3334
  children: row.active ? "Disable" : "Enable"
3227
3335
  }
3228
3336
  ),
3229
- /* @__PURE__ */ jsx27(
3337
+ /* @__PURE__ */ jsx28(
3230
3338
  "button",
3231
3339
  {
3232
3340
  type: "button",
@@ -3236,7 +3344,7 @@ function WebhookEndpointManager({
3236
3344
  children: "Deliveries"
3237
3345
  }
3238
3346
  ),
3239
- /* @__PURE__ */ jsx27(
3347
+ /* @__PURE__ */ jsx28(
3240
3348
  "button",
3241
3349
  {
3242
3350
  type: "button",
@@ -3248,45 +3356,45 @@ function WebhookEndpointManager({
3248
3356
  )
3249
3357
  ] }) })
3250
3358
  ] }),
3251
- isExpanded && /* @__PURE__ */ jsx27("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx27("td", { colSpan: 5, className: "bg-muted px-4 py-3", children: /* @__PURE__ */ jsx27(WebhookDeliveries, { endpointId: row.id, basePath }) }) })
3359
+ isExpanded && /* @__PURE__ */ jsx28("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx28("td", { colSpan: 5, className: "bg-muted px-4 py-3", children: /* @__PURE__ */ jsx28(WebhookDeliveries, { endpointId: row.id, basePath }) }) })
3252
3360
  ] }, row.id);
3253
3361
  }) })
3254
3362
  ] });
3255
3363
  }
3256
3364
  }
3257
- return /* @__PURE__ */ jsxs24("section", { "aria-label": "Webhook endpoints", className: cn25("flex flex-col gap-4", className), children: [
3365
+ return /* @__PURE__ */ jsxs25("section", { "aria-label": "Webhook endpoints", className: cn26("flex flex-col gap-4", className), children: [
3258
3366
  createForm,
3259
3367
  body
3260
3368
  ] });
3261
3369
  }
3262
3370
 
3263
3371
  // src/operations-overview.tsx
3264
- import { cn as cn26, formatDateTime as formatDateTime7, StatusBadge as StatusBadge6 } from "@quanticjs/react-ui";
3372
+ import { cn as cn27, formatDateTime as formatDateTime7, StatusBadge as StatusBadge6 } from "@quanticjs/react-ui";
3265
3373
  import { useApiQuery as useApiQuery21 } from "@quanticjs/react-query";
3266
- import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
3374
+ import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
3267
3375
  function OperationsOverview({ basePath = "/api", className }) {
3268
3376
  const { data, isLoading, isError, refetch } = useApiQuery21(
3269
3377
  ["operations-overview"],
3270
3378
  (client) => client.get(`${basePath}/v1/admin/overview`)
3271
3379
  );
3272
3380
  if (isLoading) {
3273
- return /* @__PURE__ */ jsxs25(
3381
+ return /* @__PURE__ */ jsxs26(
3274
3382
  "div",
3275
3383
  {
3276
3384
  role: "status",
3277
3385
  "aria-label": "Loading operations overview",
3278
- className: cn26("flex flex-col gap-2 p-4", className),
3386
+ className: cn27("flex flex-col gap-2 p-4", className),
3279
3387
  children: [
3280
- /* @__PURE__ */ jsx28("span", { className: "sr-only", children: "Loading operations overview" }),
3281
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx28("div", { "aria-hidden": "true", className: "h-20 animate-pulse rounded bg-muted" }, i))
3388
+ /* @__PURE__ */ jsx29("span", { className: "sr-only", children: "Loading operations overview" }),
3389
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx29("div", { "aria-hidden": "true", className: "h-20 animate-pulse rounded bg-muted" }, i))
3282
3390
  ]
3283
3391
  }
3284
3392
  );
3285
3393
  }
3286
3394
  if (isError) {
3287
- return /* @__PURE__ */ jsxs25("div", { className: cn26("flex flex-col items-start gap-3 p-4", className), children: [
3288
- /* @__PURE__ */ jsx28("p", { className: "text-sm text-foreground", children: "Failed to load operations overview" }),
3289
- /* @__PURE__ */ jsx28(
3395
+ return /* @__PURE__ */ jsxs26("div", { className: cn27("flex flex-col items-start gap-3 p-4", className), children: [
3396
+ /* @__PURE__ */ jsx29("p", { className: "text-sm text-foreground", children: "Failed to load operations overview" }),
3397
+ /* @__PURE__ */ jsx29(
3290
3398
  "button",
3291
3399
  {
3292
3400
  type: "button",
@@ -3298,7 +3406,7 @@ function OperationsOverview({ basePath = "/api", className }) {
3298
3406
  ] });
3299
3407
  }
3300
3408
  if (!data) {
3301
- return /* @__PURE__ */ jsx28("div", { className: cn26("p-6 text-center text-sm text-muted-foreground", className), children: "No overview data" });
3409
+ return /* @__PURE__ */ jsx29("div", { className: cn27("p-6 text-center text-sm text-muted-foreground", className), children: "No overview data" });
3302
3410
  }
3303
3411
  const windowHours = data.windowHours;
3304
3412
  const channels = data.channels ?? [];
@@ -3308,40 +3416,40 @@ function OperationsOverview({ basePath = "/api", className }) {
3308
3416
  { label: `Delivered (${windowHours}h)`, value: data.totalDelivered },
3309
3417
  { label: `Failed (${windowHours}h)`, value: data.totalFailed }
3310
3418
  ];
3311
- return /* @__PURE__ */ jsxs25("section", { "aria-label": "Operations overview", className: cn26("flex flex-col gap-4", className), children: [
3312
- /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsxs25("div", { className: "rounded-md border border-border bg-card p-4", children: [
3313
- /* @__PURE__ */ jsx28("p", { className: "text-xs font-medium text-muted-foreground", children: card.label }),
3314
- /* @__PURE__ */ jsx28("p", { className: "mt-1 text-2xl font-semibold text-foreground", children: card.value })
3419
+ return /* @__PURE__ */ jsxs26("section", { "aria-label": "Operations overview", className: cn27("flex flex-col gap-4", className), children: [
3420
+ /* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: cards.map((card) => /* @__PURE__ */ jsxs26("div", { className: "rounded-md border border-border bg-card p-4", children: [
3421
+ /* @__PURE__ */ jsx29("p", { className: "text-xs font-medium text-muted-foreground", children: card.label }),
3422
+ /* @__PURE__ */ jsx29("p", { className: "mt-1 text-2xl font-semibold text-foreground", children: card.value })
3315
3423
  ] }, card.label)) }),
3316
- /* @__PURE__ */ jsxs25("div", { className: "flex flex-wrap items-center gap-4", children: [
3317
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
3318
- /* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: "DLQ pending" }),
3319
- /* @__PURE__ */ jsx28(StatusBadge6, { variant: dlqPending > 0 ? "destructive" : "success", children: dlqPending })
3424
+ /* @__PURE__ */ jsxs26("div", { className: "flex flex-wrap items-center gap-4", children: [
3425
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2", children: [
3426
+ /* @__PURE__ */ jsx29("span", { className: "text-sm text-muted-foreground", children: "DLQ pending" }),
3427
+ /* @__PURE__ */ jsx29(StatusBadge6, { variant: dlqPending > 0 ? "destructive" : "success", children: dlqPending })
3320
3428
  ] }),
3321
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
3322
- /* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: "Broadcasts in flight" }),
3323
- /* @__PURE__ */ jsx28("span", { className: "text-sm font-medium text-foreground", children: data.broadcastsInFlight })
3429
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2", children: [
3430
+ /* @__PURE__ */ jsx29("span", { className: "text-sm text-muted-foreground", children: "Broadcasts in flight" }),
3431
+ /* @__PURE__ */ jsx29("span", { className: "text-sm font-medium text-foreground", children: data.broadcastsInFlight })
3324
3432
  ] }),
3325
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
3326
- /* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: "Queue" }),
3327
- /* @__PURE__ */ jsx28(StatusBadge6, { variant: data.queueHealthy ? "success" : "destructive", children: data.queueHealthy ? "Healthy" : "Unhealthy" })
3433
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2", children: [
3434
+ /* @__PURE__ */ jsx29("span", { className: "text-sm text-muted-foreground", children: "Queue" }),
3435
+ /* @__PURE__ */ jsx29(StatusBadge6, { variant: data.queueHealthy ? "success" : "destructive", children: data.queueHealthy ? "Healthy" : "Unhealthy" })
3328
3436
  ] })
3329
3437
  ] }),
3330
- /* @__PURE__ */ jsxs25("table", { className: "w-full text-sm", children: [
3331
- /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3332
- /* @__PURE__ */ jsx28("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
3333
- /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Sends" }),
3334
- /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Delivered" }),
3335
- /* @__PURE__ */ jsx28("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Failed" })
3438
+ /* @__PURE__ */ jsxs26("table", { className: "w-full text-sm", children: [
3439
+ /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsxs26("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3440
+ /* @__PURE__ */ jsx29("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
3441
+ /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Sends" }),
3442
+ /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Delivered" }),
3443
+ /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Failed" })
3336
3444
  ] }) }),
3337
- /* @__PURE__ */ jsx28("tbody", { children: channels.length === 0 ? /* @__PURE__ */ jsx28("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx28("td", { colSpan: 4, className: "py-3 text-center text-muted-foreground", children: "No channel activity" }) }) : channels.map((row) => /* @__PURE__ */ jsxs25("tr", { className: "border-b border-border", children: [
3338
- /* @__PURE__ */ jsx28("td", { className: "py-3 pe-4 text-foreground", children: row.channel }),
3339
- /* @__PURE__ */ jsx28("td", { className: "px-4 py-3 text-muted-foreground", children: row.sends }),
3340
- /* @__PURE__ */ jsx28("td", { className: "px-4 py-3 text-muted-foreground", children: row.delivered }),
3341
- /* @__PURE__ */ jsx28("td", { className: "px-4 py-3 text-muted-foreground", children: row.failed })
3445
+ /* @__PURE__ */ jsx29("tbody", { children: channels.length === 0 ? /* @__PURE__ */ jsx29("tr", { className: "border-b border-border", children: /* @__PURE__ */ jsx29("td", { colSpan: 4, className: "py-3 text-center text-muted-foreground", children: "No channel activity" }) }) : channels.map((row) => /* @__PURE__ */ jsxs26("tr", { className: "border-b border-border", children: [
3446
+ /* @__PURE__ */ jsx29("td", { className: "py-3 pe-4 text-foreground", children: row.channel }),
3447
+ /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: row.sends }),
3448
+ /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: row.delivered }),
3449
+ /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: row.failed })
3342
3450
  ] }, row.channel)) })
3343
3451
  ] }),
3344
- /* @__PURE__ */ jsxs25("p", { className: "text-xs text-muted-foreground", children: [
3452
+ /* @__PURE__ */ jsxs26("p", { className: "text-xs text-muted-foreground", children: [
3345
3453
  "Generated ",
3346
3454
  formatDateTime7(data.generatedAt)
3347
3455
  ] })
@@ -3349,10 +3457,10 @@ function OperationsOverview({ basePath = "/api", className }) {
3349
3457
  }
3350
3458
 
3351
3459
  // src/delivery-log-explorer.tsx
3352
- import { useState as useState14 } from "react";
3353
- import { cn as cn27, formatDateTime as formatDateTime8, StatusBadge as StatusBadge7 } from "@quanticjs/react-ui";
3460
+ import { useState as useState15 } from "react";
3461
+ import { cn as cn28, formatDateTime as formatDateTime8, StatusBadge as StatusBadge7 } from "@quanticjs/react-ui";
3354
3462
  import { useApiQuery as useApiQuery22 } from "@quanticjs/react-query";
3355
- import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
3463
+ import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
3356
3464
  var LIMIT6 = 20;
3357
3465
  var EMPTY_FILTERS = {
3358
3466
  channel: "",
@@ -3373,9 +3481,9 @@ function channelVariant(channel) {
3373
3481
  }
3374
3482
  }
3375
3483
  function DeliveryLogExplorer({ basePath = "/api", className }) {
3376
- const [page, setPage] = useState14(1);
3377
- const [draft, setDraft] = useState14(EMPTY_FILTERS);
3378
- const [applied, setApplied] = useState14(EMPTY_FILTERS);
3484
+ const [page, setPage] = useState15(1);
3485
+ const [draft, setDraft] = useState15(EMPTY_FILTERS);
3486
+ const [applied, setApplied] = useState15(EMPTY_FILTERS);
3379
3487
  const queryString = (() => {
3380
3488
  const params = new URLSearchParams();
3381
3489
  params.set("page", String(page));
@@ -3405,10 +3513,10 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3405
3513
  });
3406
3514
  };
3407
3515
  const setField = (key, value) => setDraft((prev) => ({ ...prev, [key]: value }));
3408
- const filterForm = /* @__PURE__ */ jsxs26("form", { onSubmit: onApply, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
3409
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3410
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-channel", className: "text-sm font-medium text-foreground", children: "Channel" }),
3411
- /* @__PURE__ */ jsxs26(
3516
+ const filterForm = /* @__PURE__ */ jsxs27("form", { onSubmit: onApply, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
3517
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3518
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-channel", className: "text-sm font-medium text-foreground", children: "Channel" }),
3519
+ /* @__PURE__ */ jsxs27(
3412
3520
  "select",
3413
3521
  {
3414
3522
  id: "dle-channel",
@@ -3416,16 +3524,16 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3416
3524
  onChange: (e) => setField("channel", e.target.value),
3417
3525
  className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring",
3418
3526
  children: [
3419
- /* @__PURE__ */ jsx29("option", { value: "", children: "All" }),
3420
- /* @__PURE__ */ jsx29("option", { value: "email", children: "Email" }),
3421
- /* @__PURE__ */ jsx29("option", { value: "sms", children: "SMS" })
3527
+ /* @__PURE__ */ jsx30("option", { value: "", children: "All" }),
3528
+ /* @__PURE__ */ jsx30("option", { value: "email", children: "Email" }),
3529
+ /* @__PURE__ */ jsx30("option", { value: "sms", children: "SMS" })
3422
3530
  ]
3423
3531
  }
3424
3532
  )
3425
3533
  ] }),
3426
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3427
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-status", className: "text-sm font-medium text-foreground", children: "Status" }),
3428
- /* @__PURE__ */ jsx29(
3534
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3535
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-status", className: "text-sm font-medium text-foreground", children: "Status" }),
3536
+ /* @__PURE__ */ jsx30(
3429
3537
  "input",
3430
3538
  {
3431
3539
  id: "dle-status",
@@ -3436,9 +3544,9 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3436
3544
  }
3437
3545
  )
3438
3546
  ] }),
3439
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3440
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-recipient", className: "text-sm font-medium text-foreground", children: "Recipient" }),
3441
- /* @__PURE__ */ jsx29(
3547
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3548
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-recipient", className: "text-sm font-medium text-foreground", children: "Recipient" }),
3549
+ /* @__PURE__ */ jsx30(
3442
3550
  "input",
3443
3551
  {
3444
3552
  id: "dle-recipient",
@@ -3449,9 +3557,9 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3449
3557
  }
3450
3558
  )
3451
3559
  ] }),
3452
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3453
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-user", className: "text-sm font-medium text-foreground", children: "User ID" }),
3454
- /* @__PURE__ */ jsx29(
3560
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3561
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-user", className: "text-sm font-medium text-foreground", children: "User ID" }),
3562
+ /* @__PURE__ */ jsx30(
3455
3563
  "input",
3456
3564
  {
3457
3565
  id: "dle-user",
@@ -3462,9 +3570,9 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3462
3570
  }
3463
3571
  )
3464
3572
  ] }),
3465
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3466
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-from", className: "text-sm font-medium text-foreground", children: "From" }),
3467
- /* @__PURE__ */ jsx29(
3573
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3574
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-from", className: "text-sm font-medium text-foreground", children: "From" }),
3575
+ /* @__PURE__ */ jsx30(
3468
3576
  "input",
3469
3577
  {
3470
3578
  id: "dle-from",
@@ -3475,9 +3583,9 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3475
3583
  }
3476
3584
  )
3477
3585
  ] }),
3478
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-1", children: [
3479
- /* @__PURE__ */ jsx29("label", { htmlFor: "dle-to", className: "text-sm font-medium text-foreground", children: "To" }),
3480
- /* @__PURE__ */ jsx29(
3586
+ /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3587
+ /* @__PURE__ */ jsx30("label", { htmlFor: "dle-to", className: "text-sm font-medium text-foreground", children: "To" }),
3588
+ /* @__PURE__ */ jsx30(
3481
3589
  "input",
3482
3590
  {
3483
3591
  id: "dle-to",
@@ -3488,7 +3596,7 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3488
3596
  }
3489
3597
  )
3490
3598
  ] }),
3491
- /* @__PURE__ */ jsx29(
3599
+ /* @__PURE__ */ jsx30(
3492
3600
  "button",
3493
3601
  {
3494
3602
  type: "submit",
@@ -3499,14 +3607,14 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3499
3607
  ] });
3500
3608
  let body;
3501
3609
  if (isLoading) {
3502
- body = /* @__PURE__ */ jsxs26("div", { role: "status", "aria-label": "Loading delivery logs", className: "flex flex-col gap-2 p-4", children: [
3503
- /* @__PURE__ */ jsx29("span", { className: "sr-only", children: "Loading delivery logs" }),
3504
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx29("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3610
+ body = /* @__PURE__ */ jsxs27("div", { role: "status", "aria-label": "Loading delivery logs", className: "flex flex-col gap-2 p-4", children: [
3611
+ /* @__PURE__ */ jsx30("span", { className: "sr-only", children: "Loading delivery logs" }),
3612
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx30("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3505
3613
  ] });
3506
3614
  } else if (isError) {
3507
- body = /* @__PURE__ */ jsxs26("div", { className: "flex flex-col items-start gap-3 p-4", children: [
3508
- /* @__PURE__ */ jsx29("p", { className: "text-sm text-foreground", children: "Failed to load delivery logs" }),
3509
- /* @__PURE__ */ jsx29(
3615
+ body = /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-start gap-3 p-4", children: [
3616
+ /* @__PURE__ */ jsx30("p", { className: "text-sm text-foreground", children: "Failed to load delivery logs" }),
3617
+ /* @__PURE__ */ jsx30(
3510
3618
  "button",
3511
3619
  {
3512
3620
  type: "button",
@@ -3520,31 +3628,31 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3520
3628
  const rows = data?.items ?? [];
3521
3629
  const totalPages = data?.totalPages ?? 1;
3522
3630
  if (rows.length === 0) {
3523
- body = /* @__PURE__ */ jsx29("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No delivery logs" });
3631
+ body = /* @__PURE__ */ jsx30("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No delivery logs" });
3524
3632
  } else {
3525
- body = /* @__PURE__ */ jsxs26(Fragment7, { children: [
3526
- /* @__PURE__ */ jsxs26("table", { className: "w-full text-sm", children: [
3527
- /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsxs26("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3528
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
3529
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Recipient" }),
3530
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "User" }),
3531
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
3532
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Provider" }),
3533
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
3534
- /* @__PURE__ */ jsx29("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
3633
+ body = /* @__PURE__ */ jsxs27(Fragment7, { children: [
3634
+ /* @__PURE__ */ jsxs27("table", { className: "w-full text-sm", children: [
3635
+ /* @__PURE__ */ jsx30("thead", { children: /* @__PURE__ */ jsxs27("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3636
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Channel" }),
3637
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Recipient" }),
3638
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "User" }),
3639
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
3640
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Provider" }),
3641
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Attempts" }),
3642
+ /* @__PURE__ */ jsx30("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" })
3535
3643
  ] }) }),
3536
- /* @__PURE__ */ jsx29("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs26("tr", { className: "border-b border-border", children: [
3537
- /* @__PURE__ */ jsx29("td", { className: "py-3 pe-4", children: /* @__PURE__ */ jsx29(StatusBadge7, { variant: channelVariant(row.channel), appearance: "dot", children: row.channel }) }),
3538
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-foreground", children: row.recipient ?? "\u2014" }),
3539
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 font-mono text-foreground", children: row.userId }),
3540
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-foreground", children: row.status }),
3541
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: row.provider ?? "\u2014" }),
3542
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: row.attempts }),
3543
- /* @__PURE__ */ jsx29("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime8(row.createdAt) })
3644
+ /* @__PURE__ */ jsx30("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs27("tr", { className: "border-b border-border", children: [
3645
+ /* @__PURE__ */ jsx30("td", { className: "py-3 pe-4", children: /* @__PURE__ */ jsx30(StatusBadge7, { variant: channelVariant(row.channel), appearance: "dot", children: row.channel }) }),
3646
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 text-foreground", children: row.recipient ?? "\u2014" }),
3647
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 font-mono text-foreground", children: row.userId }),
3648
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 text-foreground", children: row.status }),
3649
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 text-muted-foreground", children: row.provider ?? "\u2014" }),
3650
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 text-muted-foreground", children: row.attempts }),
3651
+ /* @__PURE__ */ jsx30("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime8(row.createdAt) })
3544
3652
  ] }, row.id)) })
3545
3653
  ] }),
3546
- /* @__PURE__ */ jsxs26("nav", { "aria-label": "Delivery log pagination", className: "flex items-center justify-between", children: [
3547
- /* @__PURE__ */ jsx29(
3654
+ /* @__PURE__ */ jsxs27("nav", { "aria-label": "Delivery log pagination", className: "flex items-center justify-between", children: [
3655
+ /* @__PURE__ */ jsx30(
3548
3656
  "button",
3549
3657
  {
3550
3658
  type: "button",
@@ -3554,13 +3662,13 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3554
3662
  children: "Previous"
3555
3663
  }
3556
3664
  ),
3557
- /* @__PURE__ */ jsxs26("span", { className: "text-xs text-muted-foreground", children: [
3665
+ /* @__PURE__ */ jsxs27("span", { className: "text-xs text-muted-foreground", children: [
3558
3666
  "Page ",
3559
3667
  page,
3560
3668
  " of ",
3561
3669
  totalPages
3562
3670
  ] }),
3563
- /* @__PURE__ */ jsx29(
3671
+ /* @__PURE__ */ jsx30(
3564
3672
  "button",
3565
3673
  {
3566
3674
  type: "button",
@@ -3574,17 +3682,17 @@ function DeliveryLogExplorer({ basePath = "/api", className }) {
3574
3682
  ] });
3575
3683
  }
3576
3684
  }
3577
- return /* @__PURE__ */ jsxs26("section", { "aria-label": "Delivery log explorer", className: cn27("flex flex-col gap-4", className), children: [
3685
+ return /* @__PURE__ */ jsxs27("section", { "aria-label": "Delivery log explorer", className: cn28("flex flex-col gap-4", className), children: [
3578
3686
  filterForm,
3579
3687
  body
3580
3688
  ] });
3581
3689
  }
3582
3690
 
3583
3691
  // src/quiet-hours-form.tsx
3584
- import { useEffect as useEffect5, useState as useState15 } from "react";
3585
- import { cn as cn28, useToast as useToast13 } from "@quanticjs/react-ui";
3692
+ import { useEffect as useEffect6, useState as useState16 } from "react";
3693
+ import { cn as cn29, useToast as useToast13 } from "@quanticjs/react-ui";
3586
3694
  import { useApiMutation as useApiMutation14, useApiQuery as useApiQuery23 } from "@quanticjs/react-query";
3587
- import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
3695
+ import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
3588
3696
  var DEFAULTS = {
3589
3697
  enabled: false,
3590
3698
  start: "22:00",
@@ -3607,8 +3715,8 @@ function QuietHoursForm({ basePath = "/api", className }) {
3607
3715
  ["quiet-hours"],
3608
3716
  (client) => client.get(url)
3609
3717
  );
3610
- const [form, setForm] = useState15(DEFAULTS);
3611
- useEffect5(() => {
3718
+ const [form, setForm] = useState16(DEFAULTS);
3719
+ useEffect6(() => {
3612
3720
  if (data !== void 0) {
3613
3721
  setForm(normalize5(data));
3614
3722
  }
@@ -3625,23 +3733,23 @@ function QuietHoursForm({ basePath = "/api", className }) {
3625
3733
  save.mutate(form);
3626
3734
  };
3627
3735
  if (isLoading) {
3628
- return /* @__PURE__ */ jsxs27(
3736
+ return /* @__PURE__ */ jsxs28(
3629
3737
  "div",
3630
3738
  {
3631
3739
  role: "status",
3632
3740
  "aria-label": "Loading quiet hours",
3633
- className: cn28("flex flex-col gap-2 p-4", className),
3741
+ className: cn29("flex flex-col gap-2 p-4", className),
3634
3742
  children: [
3635
- /* @__PURE__ */ jsx30("span", { className: "sr-only", children: "Loading quiet hours" }),
3636
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx30("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3743
+ /* @__PURE__ */ jsx31("span", { className: "sr-only", children: "Loading quiet hours" }),
3744
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx31("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3637
3745
  ]
3638
3746
  }
3639
3747
  );
3640
3748
  }
3641
3749
  if (isError) {
3642
- return /* @__PURE__ */ jsxs27("div", { className: cn28("flex flex-col items-start gap-3 p-4", className), children: [
3643
- /* @__PURE__ */ jsx30("p", { className: "text-sm text-foreground", children: "Failed to load quiet hours" }),
3644
- /* @__PURE__ */ jsx30(
3750
+ return /* @__PURE__ */ jsxs28("div", { className: cn29("flex flex-col items-start gap-3 p-4", className), children: [
3751
+ /* @__PURE__ */ jsx31("p", { className: "text-sm text-foreground", children: "Failed to load quiet hours" }),
3752
+ /* @__PURE__ */ jsx31(
3645
3753
  "button",
3646
3754
  {
3647
3755
  type: "button",
@@ -3652,10 +3760,10 @@ function QuietHoursForm({ basePath = "/api", className }) {
3652
3760
  )
3653
3761
  ] });
3654
3762
  }
3655
- return /* @__PURE__ */ jsxs27("form", { onSubmit, className: cn28("flex flex-col gap-4", className), noValidate: true, children: [
3656
- /* @__PURE__ */ jsx30("h2", { className: "text-sm font-semibold text-foreground", children: "Quiet hours" }),
3657
- /* @__PURE__ */ jsxs27("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
3658
- /* @__PURE__ */ jsx30(
3763
+ return /* @__PURE__ */ jsxs28("form", { onSubmit, className: cn29("flex flex-col gap-4", className), noValidate: true, children: [
3764
+ /* @__PURE__ */ jsx31("h2", { className: "text-sm font-semibold text-foreground", children: "Quiet hours" }),
3765
+ /* @__PURE__ */ jsxs28("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
3766
+ /* @__PURE__ */ jsx31(
3659
3767
  "input",
3660
3768
  {
3661
3769
  type: "checkbox",
@@ -3666,10 +3774,10 @@ function QuietHoursForm({ basePath = "/api", className }) {
3666
3774
  ),
3667
3775
  "Enable quiet hours"
3668
3776
  ] }),
3669
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap gap-4", children: [
3670
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3671
- /* @__PURE__ */ jsx30("label", { htmlFor: "qh-start", className: "text-sm font-medium text-foreground", children: "Start" }),
3672
- /* @__PURE__ */ jsx30(
3777
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap gap-4", children: [
3778
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1", children: [
3779
+ /* @__PURE__ */ jsx31("label", { htmlFor: "qh-start", className: "text-sm font-medium text-foreground", children: "Start" }),
3780
+ /* @__PURE__ */ jsx31(
3673
3781
  "input",
3674
3782
  {
3675
3783
  id: "qh-start",
@@ -3680,9 +3788,9 @@ function QuietHoursForm({ basePath = "/api", className }) {
3680
3788
  }
3681
3789
  )
3682
3790
  ] }),
3683
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3684
- /* @__PURE__ */ jsx30("label", { htmlFor: "qh-end", className: "text-sm font-medium text-foreground", children: "End" }),
3685
- /* @__PURE__ */ jsx30(
3791
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1", children: [
3792
+ /* @__PURE__ */ jsx31("label", { htmlFor: "qh-end", className: "text-sm font-medium text-foreground", children: "End" }),
3793
+ /* @__PURE__ */ jsx31(
3686
3794
  "input",
3687
3795
  {
3688
3796
  id: "qh-end",
@@ -3693,9 +3801,9 @@ function QuietHoursForm({ basePath = "/api", className }) {
3693
3801
  }
3694
3802
  )
3695
3803
  ] }),
3696
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1", children: [
3697
- /* @__PURE__ */ jsx30("label", { htmlFor: "qh-tz", className: "text-sm font-medium text-foreground", children: "Timezone" }),
3698
- /* @__PURE__ */ jsx30(
3804
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1", children: [
3805
+ /* @__PURE__ */ jsx31("label", { htmlFor: "qh-tz", className: "text-sm font-medium text-foreground", children: "Timezone" }),
3806
+ /* @__PURE__ */ jsx31(
3699
3807
  "input",
3700
3808
  {
3701
3809
  id: "qh-tz",
@@ -3707,7 +3815,7 @@ function QuietHoursForm({ basePath = "/api", className }) {
3707
3815
  )
3708
3816
  ] })
3709
3817
  ] }),
3710
- /* @__PURE__ */ jsx30("div", { children: /* @__PURE__ */ jsx30(
3818
+ /* @__PURE__ */ jsx31("div", { children: /* @__PURE__ */ jsx31(
3711
3819
  "button",
3712
3820
  {
3713
3821
  type: "submit",
@@ -3720,10 +3828,10 @@ function QuietHoursForm({ basePath = "/api", className }) {
3720
3828
  }
3721
3829
 
3722
3830
  // src/frequency-cap-table.tsx
3723
- import { useEffect as useEffect6, useState as useState16 } from "react";
3724
- import { cn as cn29, useToast as useToast14 } from "@quanticjs/react-ui";
3831
+ import { useEffect as useEffect7, useState as useState17 } from "react";
3832
+ import { cn as cn30, useToast as useToast14 } from "@quanticjs/react-ui";
3725
3833
  import { useApiMutation as useApiMutation15, useApiQuery as useApiQuery24 } from "@quanticjs/react-query";
3726
- import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
3834
+ import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
3727
3835
  function normalize6(raw) {
3728
3836
  const list = Array.isArray(raw) ? raw : Array.isArray(raw?.caps) ? raw.caps : [];
3729
3837
  return list.map((entry) => {
@@ -3739,10 +3847,10 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3739
3847
  ["frequency-cap"],
3740
3848
  (client) => client.get(url)
3741
3849
  );
3742
- const [caps, setCaps] = useState16([]);
3743
- const [newType, setNewType] = useState16("");
3744
- const [newMax, setNewMax] = useState16(0);
3745
- useEffect6(() => {
3850
+ const [caps, setCaps] = useState17([]);
3851
+ const [newType, setNewType] = useState17("");
3852
+ const [newMax, setNewMax] = useState17(0);
3853
+ useEffect7(() => {
3746
3854
  if (data !== void 0) {
3747
3855
  setCaps(normalize6(data));
3748
3856
  }
@@ -3768,23 +3876,23 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3768
3876
  setNewMax(0);
3769
3877
  };
3770
3878
  if (isLoading) {
3771
- return /* @__PURE__ */ jsxs28(
3879
+ return /* @__PURE__ */ jsxs29(
3772
3880
  "div",
3773
3881
  {
3774
3882
  role: "status",
3775
3883
  "aria-label": "Loading frequency caps",
3776
- className: cn29("flex flex-col gap-2 p-4", className),
3884
+ className: cn30("flex flex-col gap-2 p-4", className),
3777
3885
  children: [
3778
- /* @__PURE__ */ jsx31("span", { className: "sr-only", children: "Loading frequency caps" }),
3779
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx31("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3886
+ /* @__PURE__ */ jsx32("span", { className: "sr-only", children: "Loading frequency caps" }),
3887
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx32("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
3780
3888
  ]
3781
3889
  }
3782
3890
  );
3783
3891
  }
3784
3892
  if (isError) {
3785
- return /* @__PURE__ */ jsxs28("div", { className: cn29("flex flex-col items-start gap-3 p-4", className), children: [
3786
- /* @__PURE__ */ jsx31("p", { className: "text-sm text-foreground", children: "Failed to load frequency caps" }),
3787
- /* @__PURE__ */ jsx31(
3893
+ return /* @__PURE__ */ jsxs29("div", { className: cn30("flex flex-col items-start gap-3 p-4", className), children: [
3894
+ /* @__PURE__ */ jsx32("p", { className: "text-sm text-foreground", children: "Failed to load frequency caps" }),
3895
+ /* @__PURE__ */ jsx32(
3788
3896
  "button",
3789
3897
  {
3790
3898
  type: "button",
@@ -3795,24 +3903,24 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3795
3903
  )
3796
3904
  ] });
3797
3905
  }
3798
- return /* @__PURE__ */ jsxs28("section", { "aria-label": "Frequency caps", className: cn29("flex flex-col gap-4", className), children: [
3799
- /* @__PURE__ */ jsx31("h2", { className: "text-sm font-semibold text-foreground", children: "Frequency caps" }),
3800
- /* @__PURE__ */ jsxs28("table", { className: "w-full text-sm", children: [
3801
- /* @__PURE__ */ jsx31("thead", { children: /* @__PURE__ */ jsxs28("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3802
- /* @__PURE__ */ jsx31("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Type" }),
3803
- /* @__PURE__ */ jsx31("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Max per day" }),
3804
- /* @__PURE__ */ jsx31("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx31("span", { className: "sr-only", children: "Actions" }) })
3906
+ return /* @__PURE__ */ jsxs29("section", { "aria-label": "Frequency caps", className: cn30("flex flex-col gap-4", className), children: [
3907
+ /* @__PURE__ */ jsx32("h2", { className: "text-sm font-semibold text-foreground", children: "Frequency caps" }),
3908
+ /* @__PURE__ */ jsxs29("table", { className: "w-full text-sm", children: [
3909
+ /* @__PURE__ */ jsx32("thead", { children: /* @__PURE__ */ jsxs29("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
3910
+ /* @__PURE__ */ jsx32("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Type" }),
3911
+ /* @__PURE__ */ jsx32("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Max per day" }),
3912
+ /* @__PURE__ */ jsx32("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx32("span", { className: "sr-only", children: "Actions" }) })
3805
3913
  ] }) }),
3806
- /* @__PURE__ */ jsx31("tbody", { children: caps.map((cap, index) => {
3914
+ /* @__PURE__ */ jsx32("tbody", { children: caps.map((cap, index) => {
3807
3915
  const inputId = `cap-${index}`;
3808
- return /* @__PURE__ */ jsxs28("tr", { className: "border-b border-border", children: [
3809
- /* @__PURE__ */ jsx31("td", { className: "py-3 pe-4 text-foreground", children: cap.type }),
3810
- /* @__PURE__ */ jsxs28("td", { className: "px-4 py-3", children: [
3811
- /* @__PURE__ */ jsxs28("label", { htmlFor: inputId, className: "sr-only", children: [
3916
+ return /* @__PURE__ */ jsxs29("tr", { className: "border-b border-border", children: [
3917
+ /* @__PURE__ */ jsx32("td", { className: "py-3 pe-4 text-foreground", children: cap.type }),
3918
+ /* @__PURE__ */ jsxs29("td", { className: "px-4 py-3", children: [
3919
+ /* @__PURE__ */ jsxs29("label", { htmlFor: inputId, className: "sr-only", children: [
3812
3920
  "Max per day for ",
3813
3921
  cap.type
3814
3922
  ] }),
3815
- /* @__PURE__ */ jsx31(
3923
+ /* @__PURE__ */ jsx32(
3816
3924
  "input",
3817
3925
  {
3818
3926
  id: inputId,
@@ -3824,7 +3932,7 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3824
3932
  }
3825
3933
  )
3826
3934
  ] }),
3827
- /* @__PURE__ */ jsx31("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx31(
3935
+ /* @__PURE__ */ jsx32("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx32(
3828
3936
  "button",
3829
3937
  {
3830
3938
  type: "button",
@@ -3836,10 +3944,10 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3836
3944
  ] }, `${cap.type}-${index}`);
3837
3945
  }) })
3838
3946
  ] }),
3839
- /* @__PURE__ */ jsxs28("form", { onSubmit: addRow, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
3840
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1", children: [
3841
- /* @__PURE__ */ jsx31("label", { htmlFor: "cap-new-type", className: "text-sm font-medium text-foreground", children: "New type" }),
3842
- /* @__PURE__ */ jsx31(
3947
+ /* @__PURE__ */ jsxs29("form", { onSubmit: addRow, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
3948
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-1", children: [
3949
+ /* @__PURE__ */ jsx32("label", { htmlFor: "cap-new-type", className: "text-sm font-medium text-foreground", children: "New type" }),
3950
+ /* @__PURE__ */ jsx32(
3843
3951
  "input",
3844
3952
  {
3845
3953
  id: "cap-new-type",
@@ -3850,9 +3958,9 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3850
3958
  }
3851
3959
  )
3852
3960
  ] }),
3853
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-1", children: [
3854
- /* @__PURE__ */ jsx31("label", { htmlFor: "cap-new-max", className: "text-sm font-medium text-foreground", children: "Max per day" }),
3855
- /* @__PURE__ */ jsx31(
3961
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-1", children: [
3962
+ /* @__PURE__ */ jsx32("label", { htmlFor: "cap-new-max", className: "text-sm font-medium text-foreground", children: "Max per day" }),
3963
+ /* @__PURE__ */ jsx32(
3856
3964
  "input",
3857
3965
  {
3858
3966
  id: "cap-new-max",
@@ -3864,7 +3972,7 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3864
3972
  }
3865
3973
  )
3866
3974
  ] }),
3867
- /* @__PURE__ */ jsx31(
3975
+ /* @__PURE__ */ jsx32(
3868
3976
  "button",
3869
3977
  {
3870
3978
  type: "submit",
@@ -3873,7 +3981,7 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3873
3981
  }
3874
3982
  )
3875
3983
  ] }),
3876
- /* @__PURE__ */ jsx31("div", { children: /* @__PURE__ */ jsx31(
3984
+ /* @__PURE__ */ jsx32("div", { children: /* @__PURE__ */ jsx32(
3877
3985
  "button",
3878
3986
  {
3879
3987
  type: "button",
@@ -3887,10 +3995,10 @@ function FrequencyCapTable({ basePath = "/api", className }) {
3887
3995
  }
3888
3996
 
3889
3997
  // src/tenant-config-form.tsx
3890
- import { useEffect as useEffect7, useState as useState17 } from "react";
3891
- import { cn as cn30, useToast as useToast15 } from "@quanticjs/react-ui";
3998
+ import { useEffect as useEffect8, useState as useState18 } from "react";
3999
+ import { cn as cn31, useToast as useToast15 } from "@quanticjs/react-ui";
3892
4000
  import { useApiMutation as useApiMutation16, useApiQuery as useApiQuery25 } from "@quanticjs/react-query";
3893
- import { jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
4001
+ import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
3894
4002
  function normalize7(raw) {
3895
4003
  const obj = raw ?? {};
3896
4004
  const toList = (value) => Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
@@ -3900,7 +4008,7 @@ function normalize7(raw) {
3900
4008
  };
3901
4009
  }
3902
4010
  function TagEditor({ id, label, values, onAdd, onRemove }) {
3903
- const [draft, setDraft] = useState17("");
4011
+ const [draft, setDraft] = useState18("");
3904
4012
  const add = (event) => {
3905
4013
  event.preventDefault();
3906
4014
  const value = draft.trim();
@@ -3908,15 +4016,15 @@ function TagEditor({ id, label, values, onAdd, onRemove }) {
3908
4016
  onAdd(value);
3909
4017
  setDraft("");
3910
4018
  };
3911
- return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-2", children: [
3912
- /* @__PURE__ */ jsx32("span", { className: "text-sm font-medium text-foreground", children: label }),
3913
- /* @__PURE__ */ jsx32("ul", { className: "flex flex-wrap gap-2", children: values.length === 0 ? /* @__PURE__ */ jsx32("li", { className: "text-sm text-muted-foreground", children: "None" }) : values.map((value) => /* @__PURE__ */ jsxs29(
4019
+ return /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-2", children: [
4020
+ /* @__PURE__ */ jsx33("span", { className: "text-sm font-medium text-foreground", children: label }),
4021
+ /* @__PURE__ */ jsx33("ul", { className: "flex flex-wrap gap-2", children: values.length === 0 ? /* @__PURE__ */ jsx33("li", { className: "text-sm text-muted-foreground", children: "None" }) : values.map((value) => /* @__PURE__ */ jsxs30(
3914
4022
  "li",
3915
4023
  {
3916
4024
  className: "flex items-center gap-1 rounded-md border border-border bg-card px-2 py-1 text-sm text-foreground",
3917
4025
  children: [
3918
4026
  value,
3919
- /* @__PURE__ */ jsx32(
4027
+ /* @__PURE__ */ jsx33(
3920
4028
  "button",
3921
4029
  {
3922
4030
  type: "button",
@@ -3930,13 +4038,13 @@ function TagEditor({ id, label, values, onAdd, onRemove }) {
3930
4038
  },
3931
4039
  value
3932
4040
  )) }),
3933
- /* @__PURE__ */ jsxs29("form", { onSubmit: add, className: "flex items-end gap-2", noValidate: true, children: [
3934
- /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-1", children: [
3935
- /* @__PURE__ */ jsxs29("label", { htmlFor: id, className: "sr-only", children: [
4041
+ /* @__PURE__ */ jsxs30("form", { onSubmit: add, className: "flex items-end gap-2", noValidate: true, children: [
4042
+ /* @__PURE__ */ jsxs30("div", { className: "flex flex-col gap-1", children: [
4043
+ /* @__PURE__ */ jsxs30("label", { htmlFor: id, className: "sr-only", children: [
3936
4044
  "Add to ",
3937
4045
  label
3938
4046
  ] }),
3939
- /* @__PURE__ */ jsx32(
4047
+ /* @__PURE__ */ jsx33(
3940
4048
  "input",
3941
4049
  {
3942
4050
  id,
@@ -3947,7 +4055,7 @@ function TagEditor({ id, label, values, onAdd, onRemove }) {
3947
4055
  }
3948
4056
  )
3949
4057
  ] }),
3950
- /* @__PURE__ */ jsx32(
4058
+ /* @__PURE__ */ jsx33(
3951
4059
  "button",
3952
4060
  {
3953
4061
  type: "submit",
@@ -3965,12 +4073,12 @@ function TenantConfigForm({ basePath = "/api", className }) {
3965
4073
  ["tenant-config"],
3966
4074
  (client) => client.get(url)
3967
4075
  );
3968
- const [config, setConfig] = useState17({
4076
+ const [config, setConfig] = useState18({
3969
4077
  notificationTypes: [],
3970
4078
  immediateEmailTypes: []
3971
4079
  });
3972
- const [subsetError, setSubsetError] = useState17(void 0);
3973
- useEffect7(() => {
4080
+ const [subsetError, setSubsetError] = useState18(void 0);
4081
+ useEffect8(() => {
3974
4082
  if (data !== void 0) {
3975
4083
  setConfig(normalize7(data));
3976
4084
  }
@@ -4012,23 +4120,23 @@ function TenantConfigForm({ basePath = "/api", className }) {
4012
4120
  save.mutate(config);
4013
4121
  };
4014
4122
  if (isLoading) {
4015
- return /* @__PURE__ */ jsxs29(
4123
+ return /* @__PURE__ */ jsxs30(
4016
4124
  "div",
4017
4125
  {
4018
4126
  role: "status",
4019
4127
  "aria-label": "Loading tenant configuration",
4020
- className: cn30("flex flex-col gap-2 p-4", className),
4128
+ className: cn31("flex flex-col gap-2 p-4", className),
4021
4129
  children: [
4022
- /* @__PURE__ */ jsx32("span", { className: "sr-only", children: "Loading tenant configuration" }),
4023
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx32("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4130
+ /* @__PURE__ */ jsx33("span", { className: "sr-only", children: "Loading tenant configuration" }),
4131
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx33("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4024
4132
  ]
4025
4133
  }
4026
4134
  );
4027
4135
  }
4028
4136
  if (isError) {
4029
- return /* @__PURE__ */ jsxs29("div", { className: cn30("flex flex-col items-start gap-3 p-4", className), children: [
4030
- /* @__PURE__ */ jsx32("p", { className: "text-sm text-foreground", children: "Failed to load tenant configuration" }),
4031
- /* @__PURE__ */ jsx32(
4137
+ return /* @__PURE__ */ jsxs30("div", { className: cn31("flex flex-col items-start gap-3 p-4", className), children: [
4138
+ /* @__PURE__ */ jsx33("p", { className: "text-sm text-foreground", children: "Failed to load tenant configuration" }),
4139
+ /* @__PURE__ */ jsx33(
4032
4140
  "button",
4033
4141
  {
4034
4142
  type: "button",
@@ -4040,17 +4148,17 @@ function TenantConfigForm({ basePath = "/api", className }) {
4040
4148
  ] });
4041
4149
  }
4042
4150
  const errorId = "tenant-config-subset-error";
4043
- return /* @__PURE__ */ jsxs29(
4151
+ return /* @__PURE__ */ jsxs30(
4044
4152
  "form",
4045
4153
  {
4046
4154
  onSubmit,
4047
- className: cn30("flex flex-col gap-5", className),
4155
+ className: cn31("flex flex-col gap-5", className),
4048
4156
  noValidate: true,
4049
4157
  "aria-invalid": subsetError ? "true" : void 0,
4050
4158
  "aria-describedby": subsetError ? errorId : void 0,
4051
4159
  children: [
4052
- /* @__PURE__ */ jsx32("h2", { className: "text-sm font-semibold text-foreground", children: "Notification configuration" }),
4053
- /* @__PURE__ */ jsx32(
4160
+ /* @__PURE__ */ jsx33("h2", { className: "text-sm font-semibold text-foreground", children: "Notification configuration" }),
4161
+ /* @__PURE__ */ jsx33(
4054
4162
  TagEditor,
4055
4163
  {
4056
4164
  id: "tc-notification-types",
@@ -4060,7 +4168,7 @@ function TenantConfigForm({ basePath = "/api", className }) {
4060
4168
  onRemove: removeType
4061
4169
  }
4062
4170
  ),
4063
- /* @__PURE__ */ jsx32(
4171
+ /* @__PURE__ */ jsx33(
4064
4172
  TagEditor,
4065
4173
  {
4066
4174
  id: "tc-immediate-email-types",
@@ -4070,8 +4178,8 @@ function TenantConfigForm({ basePath = "/api", className }) {
4070
4178
  onRemove: removeImmediate
4071
4179
  }
4072
4180
  ),
4073
- subsetError && /* @__PURE__ */ jsx32("p", { id: errorId, className: "text-xs text-destructive", children: subsetError }),
4074
- /* @__PURE__ */ jsx32("div", { children: /* @__PURE__ */ jsx32(
4181
+ subsetError && /* @__PURE__ */ jsx33("p", { id: errorId, className: "text-xs text-destructive", children: subsetError }),
4182
+ /* @__PURE__ */ jsx33("div", { children: /* @__PURE__ */ jsx33(
4075
4183
  "button",
4076
4184
  {
4077
4185
  type: "submit",
@@ -4086,10 +4194,10 @@ function TenantConfigForm({ basePath = "/api", className }) {
4086
4194
  }
4087
4195
 
4088
4196
  // src/tracking-config-form.tsx
4089
- import { useEffect as useEffect8, useState as useState18 } from "react";
4090
- import { cn as cn31, useToast as useToast16 } from "@quanticjs/react-ui";
4197
+ import { useEffect as useEffect9, useState as useState19 } from "react";
4198
+ import { cn as cn32, useToast as useToast16 } from "@quanticjs/react-ui";
4091
4199
  import { useApiMutation as useApiMutation17, useApiQuery as useApiQuery26 } from "@quanticjs/react-query";
4092
- import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
4200
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
4093
4201
  function normalize8(raw) {
4094
4202
  const obj = raw ?? {};
4095
4203
  const bool = (...keys) => {
@@ -4110,11 +4218,11 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4110
4218
  ["tracking-config"],
4111
4219
  (client) => client.get(url)
4112
4220
  );
4113
- const [form, setForm] = useState18({
4221
+ const [form, setForm] = useState19({
4114
4222
  openTrackingEnabled: false,
4115
4223
  clickTrackingEnabled: false
4116
4224
  });
4117
- useEffect8(() => {
4225
+ useEffect9(() => {
4118
4226
  if (data !== void 0) {
4119
4227
  setForm(normalize8(data));
4120
4228
  }
@@ -4134,23 +4242,23 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4134
4242
  save.mutate(form);
4135
4243
  };
4136
4244
  if (isLoading) {
4137
- return /* @__PURE__ */ jsxs30(
4245
+ return /* @__PURE__ */ jsxs31(
4138
4246
  "div",
4139
4247
  {
4140
4248
  role: "status",
4141
4249
  "aria-label": "Loading tracking configuration",
4142
- className: cn31("flex flex-col gap-2 p-4", className),
4250
+ className: cn32("flex flex-col gap-2 p-4", className),
4143
4251
  children: [
4144
- /* @__PURE__ */ jsx33("span", { className: "sr-only", children: "Loading tracking configuration" }),
4145
- [0, 1].map((i) => /* @__PURE__ */ jsx33("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4252
+ /* @__PURE__ */ jsx34("span", { className: "sr-only", children: "Loading tracking configuration" }),
4253
+ [0, 1].map((i) => /* @__PURE__ */ jsx34("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4146
4254
  ]
4147
4255
  }
4148
4256
  );
4149
4257
  }
4150
4258
  if (isError) {
4151
- return /* @__PURE__ */ jsxs30("div", { className: cn31("flex flex-col items-start gap-3 p-4", className), children: [
4152
- /* @__PURE__ */ jsx33("p", { className: "text-sm text-foreground", children: "Failed to load tracking configuration" }),
4153
- /* @__PURE__ */ jsx33(
4259
+ return /* @__PURE__ */ jsxs31("div", { className: cn32("flex flex-col items-start gap-3 p-4", className), children: [
4260
+ /* @__PURE__ */ jsx34("p", { className: "text-sm text-foreground", children: "Failed to load tracking configuration" }),
4261
+ /* @__PURE__ */ jsx34(
4154
4262
  "button",
4155
4263
  {
4156
4264
  type: "button",
@@ -4161,10 +4269,10 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4161
4269
  )
4162
4270
  ] });
4163
4271
  }
4164
- return /* @__PURE__ */ jsxs30("form", { onSubmit, className: cn31("flex flex-col gap-4", className), noValidate: true, children: [
4165
- /* @__PURE__ */ jsx33("h2", { className: "text-sm font-semibold text-foreground", children: "Tracking configuration" }),
4166
- /* @__PURE__ */ jsxs30("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
4167
- /* @__PURE__ */ jsx33(
4272
+ return /* @__PURE__ */ jsxs31("form", { onSubmit, className: cn32("flex flex-col gap-4", className), noValidate: true, children: [
4273
+ /* @__PURE__ */ jsx34("h2", { className: "text-sm font-semibold text-foreground", children: "Tracking configuration" }),
4274
+ /* @__PURE__ */ jsxs31("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
4275
+ /* @__PURE__ */ jsx34(
4168
4276
  "input",
4169
4277
  {
4170
4278
  type: "checkbox",
@@ -4175,8 +4283,8 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4175
4283
  ),
4176
4284
  "Open tracking"
4177
4285
  ] }),
4178
- /* @__PURE__ */ jsxs30("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
4179
- /* @__PURE__ */ jsx33(
4286
+ /* @__PURE__ */ jsxs31("label", { className: "flex items-center gap-2 text-sm text-foreground", children: [
4287
+ /* @__PURE__ */ jsx34(
4180
4288
  "input",
4181
4289
  {
4182
4290
  type: "checkbox",
@@ -4187,7 +4295,7 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4187
4295
  ),
4188
4296
  "Click tracking"
4189
4297
  ] }),
4190
- /* @__PURE__ */ jsx33("div", { children: /* @__PURE__ */ jsx33(
4298
+ /* @__PURE__ */ jsx34("div", { children: /* @__PURE__ */ jsx34(
4191
4299
  "button",
4192
4300
  {
4193
4301
  type: "submit",
@@ -4200,10 +4308,10 @@ function TrackingConfigForm({ basePath = "/api", className }) {
4200
4308
  }
4201
4309
 
4202
4310
  // src/api-key-manager.tsx
4203
- import { useState as useState19 } from "react";
4204
- import { cn as cn32, formatDateTime as formatDateTime9, StatusBadge as StatusBadge8, useToast as useToast17 } from "@quanticjs/react-ui";
4311
+ import { useState as useState20 } from "react";
4312
+ import { cn as cn33, formatDateTime as formatDateTime9, StatusBadge as StatusBadge8, useToast as useToast17 } from "@quanticjs/react-ui";
4205
4313
  import { useApiMutation as useApiMutation18, useApiQuery as useApiQuery27 } from "@quanticjs/react-query";
4206
- import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
4314
+ import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
4207
4315
  function normalize9(raw) {
4208
4316
  const list = Array.isArray(raw) ? raw : Array.isArray(raw?.items) ? raw.items : [];
4209
4317
  return list;
@@ -4215,8 +4323,8 @@ function ApiKeyManager({ basePath = "/api", className }) {
4215
4323
  ["api-keys"],
4216
4324
  (client) => client.get(url)
4217
4325
  );
4218
- const [name, setName] = useState19("");
4219
- const [applicationKey, setApplicationKey] = useState19("");
4326
+ const [name, setName] = useState20("");
4327
+ const [applicationKey, setApplicationKey] = useState20("");
4220
4328
  const onMutationError = (error) => toast.error(error.isServerError ? "Something went wrong" : error.title, {
4221
4329
  description: error.isServerError ? `Please try again. (ref: ${error.correlationId ?? "unknown"})` : `${error.detail ?? ""} (ref: ${error.correlationId ?? "unknown"})`
4222
4330
  });
@@ -4261,10 +4369,10 @@ function ApiKeyManager({ basePath = "/api", className }) {
4261
4369
  revoke.mutate(id);
4262
4370
  }
4263
4371
  };
4264
- const createForm = /* @__PURE__ */ jsxs31("form", { onSubmit: onCreate, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
4265
- /* @__PURE__ */ jsxs31("div", { className: "flex flex-col gap-1", children: [
4266
- /* @__PURE__ */ jsx34("label", { htmlFor: "api-key-name", className: "text-sm font-medium text-foreground", children: "New key name" }),
4267
- /* @__PURE__ */ jsx34(
4372
+ const createForm = /* @__PURE__ */ jsxs32("form", { onSubmit: onCreate, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
4373
+ /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
4374
+ /* @__PURE__ */ jsx35("label", { htmlFor: "api-key-name", className: "text-sm font-medium text-foreground", children: "New key name" }),
4375
+ /* @__PURE__ */ jsx35(
4268
4376
  "input",
4269
4377
  {
4270
4378
  id: "api-key-name",
@@ -4275,9 +4383,9 @@ function ApiKeyManager({ basePath = "/api", className }) {
4275
4383
  }
4276
4384
  )
4277
4385
  ] }),
4278
- /* @__PURE__ */ jsxs31("div", { className: "flex flex-col gap-1", children: [
4279
- /* @__PURE__ */ jsx34("label", { htmlFor: "api-key-app", className: "text-sm font-medium text-foreground", children: "Application (optional)" }),
4280
- /* @__PURE__ */ jsx34(
4386
+ /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
4387
+ /* @__PURE__ */ jsx35("label", { htmlFor: "api-key-app", className: "text-sm font-medium text-foreground", children: "Application (optional)" }),
4388
+ /* @__PURE__ */ jsx35(
4281
4389
  "input",
4282
4390
  {
4283
4391
  id: "api-key-app",
@@ -4289,7 +4397,7 @@ function ApiKeyManager({ basePath = "/api", className }) {
4289
4397
  }
4290
4398
  )
4291
4399
  ] }),
4292
- /* @__PURE__ */ jsx34(
4400
+ /* @__PURE__ */ jsx35(
4293
4401
  "button",
4294
4402
  {
4295
4403
  type: "submit",
@@ -4301,14 +4409,14 @@ function ApiKeyManager({ basePath = "/api", className }) {
4301
4409
  ] });
4302
4410
  let body;
4303
4411
  if (isLoading) {
4304
- body = /* @__PURE__ */ jsxs31("div", { role: "status", "aria-label": "Loading API keys", className: "flex flex-col gap-2 p-4", children: [
4305
- /* @__PURE__ */ jsx34("span", { className: "sr-only", children: "Loading API keys" }),
4306
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx34("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4412
+ body = /* @__PURE__ */ jsxs32("div", { role: "status", "aria-label": "Loading API keys", className: "flex flex-col gap-2 p-4", children: [
4413
+ /* @__PURE__ */ jsx35("span", { className: "sr-only", children: "Loading API keys" }),
4414
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx35("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4307
4415
  ] });
4308
4416
  } else if (isError) {
4309
- body = /* @__PURE__ */ jsxs31("div", { className: "flex flex-col items-start gap-3 p-4", children: [
4310
- /* @__PURE__ */ jsx34("p", { className: "text-sm text-foreground", children: "Failed to load API keys" }),
4311
- /* @__PURE__ */ jsx34(
4417
+ body = /* @__PURE__ */ jsxs32("div", { className: "flex flex-col items-start gap-3 p-4", children: [
4418
+ /* @__PURE__ */ jsx35("p", { className: "text-sm text-foreground", children: "Failed to load API keys" }),
4419
+ /* @__PURE__ */ jsx35(
4312
4420
  "button",
4313
4421
  {
4314
4422
  type: "button",
@@ -4321,26 +4429,26 @@ function ApiKeyManager({ basePath = "/api", className }) {
4321
4429
  } else {
4322
4430
  const rows = normalize9(data);
4323
4431
  if (rows.length === 0) {
4324
- body = /* @__PURE__ */ jsx34("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No API keys" });
4432
+ body = /* @__PURE__ */ jsx35("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No API keys" });
4325
4433
  } else {
4326
- body = /* @__PURE__ */ jsxs31("table", { className: "w-full text-sm", children: [
4327
- /* @__PURE__ */ jsx34("thead", { children: /* @__PURE__ */ jsxs31("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
4328
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Name" }),
4329
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Prefix" }),
4330
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Application" }),
4331
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
4332
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
4333
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Last used" }),
4334
- /* @__PURE__ */ jsx34("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx34("span", { className: "sr-only", children: "Actions" }) })
4434
+ body = /* @__PURE__ */ jsxs32("table", { className: "w-full text-sm", children: [
4435
+ /* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs32("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
4436
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "py-2 pe-4 font-medium", children: "Name" }),
4437
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Prefix" }),
4438
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Application" }),
4439
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Status" }),
4440
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Created" }),
4441
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: "Last used" }),
4442
+ /* @__PURE__ */ jsx35("th", { scope: "col", className: "px-4 py-2 font-medium", children: /* @__PURE__ */ jsx35("span", { className: "sr-only", children: "Actions" }) })
4335
4443
  ] }) }),
4336
- /* @__PURE__ */ jsx34("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs31("tr", { className: "border-b border-border", children: [
4337
- /* @__PURE__ */ jsx34("td", { className: "py-3 pe-4 text-foreground", children: row.name }),
4338
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3 font-mono text-muted-foreground", children: row.prefix ?? "\u2014" }),
4339
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3 font-mono text-muted-foreground", children: row.applicationKey ?? "\u2014" }),
4340
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx34(StatusBadge8, { variant: row.revoked ? "destructive" : "success", children: row.revoked ? "Revoked" : "Active" }) }),
4341
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime9(row.createdAt) }),
4342
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3 text-muted-foreground", children: row.lastUsedAt ? formatDateTime9(row.lastUsedAt) : "\u2014" }),
4343
- /* @__PURE__ */ jsx34("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx34(
4444
+ /* @__PURE__ */ jsx35("tbody", { children: rows.map((row) => /* @__PURE__ */ jsxs32("tr", { className: "border-b border-border", children: [
4445
+ /* @__PURE__ */ jsx35("td", { className: "py-3 pe-4 text-foreground", children: row.name }),
4446
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3 font-mono text-muted-foreground", children: row.prefix ?? "\u2014" }),
4447
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3 font-mono text-muted-foreground", children: row.applicationKey ?? "\u2014" }),
4448
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx35(StatusBadge8, { variant: row.revoked ? "destructive" : "success", children: row.revoked ? "Revoked" : "Active" }) }),
4449
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3 text-muted-foreground", children: formatDateTime9(row.createdAt) }),
4450
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3 text-muted-foreground", children: row.lastUsedAt ? formatDateTime9(row.lastUsedAt) : "\u2014" }),
4451
+ /* @__PURE__ */ jsx35("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx35(
4344
4452
  "button",
4345
4453
  {
4346
4454
  type: "button",
@@ -4354,17 +4462,17 @@ function ApiKeyManager({ basePath = "/api", className }) {
4354
4462
  ] });
4355
4463
  }
4356
4464
  }
4357
- return /* @__PURE__ */ jsxs31("section", { "aria-label": "API key management", className: cn32("flex flex-col gap-4", className), children: [
4465
+ return /* @__PURE__ */ jsxs32("section", { "aria-label": "API key management", className: cn33("flex flex-col gap-4", className), children: [
4358
4466
  createForm,
4359
4467
  body
4360
4468
  ] });
4361
4469
  }
4362
4470
 
4363
4471
  // src/application-registry-panel.tsx
4364
- import { useState as useState20 } from "react";
4365
- import { cn as cn33, formatDateTime as formatDateTime10, StatusBadge as StatusBadge9, useToast as useToast18 } from "@quanticjs/react-ui";
4472
+ import { useState as useState21 } from "react";
4473
+ import { cn as cn34, formatDateTime as formatDateTime10, StatusBadge as StatusBadge9, useToast as useToast18 } from "@quanticjs/react-ui";
4366
4474
  import { useApiMutation as useApiMutation19, useApiQuery as useApiQuery28 } from "@quanticjs/react-query";
4367
- import { jsx as jsx35, jsxs as jsxs32 } from "react/jsx-runtime";
4475
+ import { jsx as jsx36, jsxs as jsxs33 } from "react/jsx-runtime";
4368
4476
  function normalize10(raw) {
4369
4477
  const list = Array.isArray(raw) ? raw : Array.isArray(raw?.items) ? raw.items : [];
4370
4478
  return list;
@@ -4379,9 +4487,9 @@ function ApplicationRegistryPanel({
4379
4487
  ["applications"],
4380
4488
  (client) => client.get(url)
4381
4489
  );
4382
- const [key, setKey] = useState20("");
4383
- const [displayName, setDisplayName] = useState20("");
4384
- const [description, setDescription] = useState20("");
4490
+ const [key, setKey] = useState21("");
4491
+ const [displayName, setDisplayName] = useState21("");
4492
+ const [description, setDescription] = useState21("");
4385
4493
  const onMutationError = (error) => toast.error(error.isServerError ? "Something went wrong" : error.title, {
4386
4494
  description: error.isServerError ? `Please try again. (ref: ${error.correlationId ?? "unknown"})` : `${error.detail ?? ""} (ref: ${error.correlationId ?? "unknown"})`
4387
4495
  });
@@ -4410,10 +4518,10 @@ function ApplicationRegistryPanel({
4410
4518
  if (!k || !name) return;
4411
4519
  register.mutate({ key: k, displayName: name, description: description.trim() || void 0 });
4412
4520
  };
4413
- const registerForm = /* @__PURE__ */ jsxs32("form", { onSubmit: onRegister, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
4414
- /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
4415
- /* @__PURE__ */ jsx35("label", { htmlFor: "application-key", className: "text-sm font-medium text-foreground", children: "Key (slug)" }),
4416
- /* @__PURE__ */ jsx35(
4521
+ const registerForm = /* @__PURE__ */ jsxs33("form", { onSubmit: onRegister, className: "flex flex-wrap items-end gap-3", noValidate: true, children: [
4522
+ /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-1", children: [
4523
+ /* @__PURE__ */ jsx36("label", { htmlFor: "application-key", className: "text-sm font-medium text-foreground", children: "Key (slug)" }),
4524
+ /* @__PURE__ */ jsx36(
4417
4525
  "input",
4418
4526
  {
4419
4527
  id: "application-key",
@@ -4425,9 +4533,9 @@ function ApplicationRegistryPanel({
4425
4533
  }
4426
4534
  )
4427
4535
  ] }),
4428
- /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
4429
- /* @__PURE__ */ jsx35("label", { htmlFor: "application-name", className: "text-sm font-medium text-foreground", children: "Display name" }),
4430
- /* @__PURE__ */ jsx35(
4536
+ /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-1", children: [
4537
+ /* @__PURE__ */ jsx36("label", { htmlFor: "application-name", className: "text-sm font-medium text-foreground", children: "Display name" }),
4538
+ /* @__PURE__ */ jsx36(
4431
4539
  "input",
4432
4540
  {
4433
4541
  id: "application-name",
@@ -4439,9 +4547,9 @@ function ApplicationRegistryPanel({
4439
4547
  }
4440
4548
  )
4441
4549
  ] }),
4442
- /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
4443
- /* @__PURE__ */ jsx35("label", { htmlFor: "application-description", className: "text-sm font-medium text-foreground", children: "Description (optional)" }),
4444
- /* @__PURE__ */ jsx35(
4550
+ /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-1", children: [
4551
+ /* @__PURE__ */ jsx36("label", { htmlFor: "application-description", className: "text-sm font-medium text-foreground", children: "Description (optional)" }),
4552
+ /* @__PURE__ */ jsx36(
4445
4553
  "input",
4446
4554
  {
4447
4555
  id: "application-description",
@@ -4452,7 +4560,7 @@ function ApplicationRegistryPanel({
4452
4560
  }
4453
4561
  )
4454
4562
  ] }),
4455
- /* @__PURE__ */ jsx35(
4563
+ /* @__PURE__ */ jsx36(
4456
4564
  "button",
4457
4565
  {
4458
4566
  type: "submit",
@@ -4463,23 +4571,23 @@ function ApplicationRegistryPanel({
4463
4571
  )
4464
4572
  ] });
4465
4573
  if (isLoading) {
4466
- return /* @__PURE__ */ jsxs32(
4574
+ return /* @__PURE__ */ jsxs33(
4467
4575
  "div",
4468
4576
  {
4469
4577
  role: "status",
4470
4578
  "aria-label": "Loading applications",
4471
- className: cn33("flex flex-col gap-2 p-4", className),
4579
+ className: cn34("flex flex-col gap-2 p-4", className),
4472
4580
  children: [
4473
- /* @__PURE__ */ jsx35("span", { className: "sr-only", children: "Loading applications" }),
4474
- [0, 1, 2].map((i) => /* @__PURE__ */ jsx35("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4581
+ /* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Loading applications" }),
4582
+ [0, 1, 2].map((i) => /* @__PURE__ */ jsx36("div", { "aria-hidden": "true", className: "h-10 animate-pulse rounded bg-muted" }, i))
4475
4583
  ]
4476
4584
  }
4477
4585
  );
4478
4586
  }
4479
4587
  if (isError) {
4480
- return /* @__PURE__ */ jsxs32("div", { className: cn33("flex flex-col items-start gap-3 p-4", className), children: [
4481
- /* @__PURE__ */ jsx35("p", { className: "text-sm text-foreground", children: "Failed to load applications" }),
4482
- /* @__PURE__ */ jsx35(
4588
+ return /* @__PURE__ */ jsxs33("div", { className: cn34("flex flex-col items-start gap-3 p-4", className), children: [
4589
+ /* @__PURE__ */ jsx36("p", { className: "text-sm text-foreground", children: "Failed to load applications" }),
4590
+ /* @__PURE__ */ jsx36(
4483
4591
  "button",
4484
4592
  {
4485
4593
  type: "button",
@@ -4491,22 +4599,22 @@ function ApplicationRegistryPanel({
4491
4599
  ] });
4492
4600
  }
4493
4601
  const apps = normalize10(data);
4494
- return /* @__PURE__ */ jsxs32("section", { "aria-label": "Applications", className: cn33("flex flex-col gap-4 p-4", className), children: [
4602
+ return /* @__PURE__ */ jsxs33("section", { "aria-label": "Applications", className: cn34("flex flex-col gap-4 p-4", className), children: [
4495
4603
  registerForm,
4496
- apps.length === 0 ? /* @__PURE__ */ jsx35("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No applications registered" }) : /* @__PURE__ */ jsxs32("table", { className: "w-full text-sm", children: [
4497
- /* @__PURE__ */ jsx35("thead", { children: /* @__PURE__ */ jsxs32("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
4498
- /* @__PURE__ */ jsx35("th", { className: "py-2 font-medium", children: "Key" }),
4499
- /* @__PURE__ */ jsx35("th", { className: "py-2 font-medium", children: "Name" }),
4500
- /* @__PURE__ */ jsx35("th", { className: "py-2 font-medium", children: "Status" }),
4501
- /* @__PURE__ */ jsx35("th", { className: "py-2 font-medium", children: "Created" }),
4502
- /* @__PURE__ */ jsx35("th", { className: "py-2 font-medium", children: "Actions" })
4604
+ apps.length === 0 ? /* @__PURE__ */ jsx36("p", { className: "p-6 text-center text-sm text-muted-foreground", children: "No applications registered" }) : /* @__PURE__ */ jsxs33("table", { className: "w-full text-sm", children: [
4605
+ /* @__PURE__ */ jsx36("thead", { children: /* @__PURE__ */ jsxs33("tr", { className: "border-b border-border text-start text-muted-foreground", children: [
4606
+ /* @__PURE__ */ jsx36("th", { className: "py-2 font-medium", children: "Key" }),
4607
+ /* @__PURE__ */ jsx36("th", { className: "py-2 font-medium", children: "Name" }),
4608
+ /* @__PURE__ */ jsx36("th", { className: "py-2 font-medium", children: "Status" }),
4609
+ /* @__PURE__ */ jsx36("th", { className: "py-2 font-medium", children: "Created" }),
4610
+ /* @__PURE__ */ jsx36("th", { className: "py-2 font-medium", children: "Actions" })
4503
4611
  ] }) }),
4504
- /* @__PURE__ */ jsx35("tbody", { children: apps.map((app) => /* @__PURE__ */ jsxs32("tr", { className: "border-b border-border", children: [
4505
- /* @__PURE__ */ jsx35("td", { className: "py-2 font-mono text-foreground", children: app.key }),
4506
- /* @__PURE__ */ jsx35("td", { className: "py-2 text-foreground", children: app.displayName }),
4507
- /* @__PURE__ */ jsx35("td", { className: "py-2", children: /* @__PURE__ */ jsx35(StatusBadge9, { variant: app.status === "active" ? "success" : "neutral", children: app.status }) }),
4508
- /* @__PURE__ */ jsx35("td", { className: "py-2 text-muted-foreground", children: formatDateTime10(app.createdAt) }),
4509
- /* @__PURE__ */ jsx35("td", { className: "py-2", children: /* @__PURE__ */ jsx35(
4612
+ /* @__PURE__ */ jsx36("tbody", { children: apps.map((app) => /* @__PURE__ */ jsxs33("tr", { className: "border-b border-border", children: [
4613
+ /* @__PURE__ */ jsx36("td", { className: "py-2 font-mono text-foreground", children: app.key }),
4614
+ /* @__PURE__ */ jsx36("td", { className: "py-2 text-foreground", children: app.displayName }),
4615
+ /* @__PURE__ */ jsx36("td", { className: "py-2", children: /* @__PURE__ */ jsx36(StatusBadge9, { variant: app.status === "active" ? "success" : "neutral", children: app.status }) }),
4616
+ /* @__PURE__ */ jsx36("td", { className: "py-2 text-muted-foreground", children: formatDateTime10(app.createdAt) }),
4617
+ /* @__PURE__ */ jsx36("td", { className: "py-2", children: /* @__PURE__ */ jsx36(
4510
4618
  "button",
4511
4619
  {
4512
4620
  type: "button",
@@ -4539,6 +4647,7 @@ export {
4539
4647
  FunnelStats,
4540
4648
  MissingTranslationsPanel,
4541
4649
  NotificationBell,
4650
+ NotificationCenter,
4542
4651
  NotificationInbox,
4543
4652
  NotificationPreferences,
4544
4653
  NotificationProvider,