@quanticjs/notification-ui 9.0.1 → 9.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +120 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +120 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3572,11 +3572,8 @@ function OperationsOverview({ basePath = "/api", className }) {
|
|
|
3572
3572
|
const windowHours = data.windowHours;
|
|
3573
3573
|
const channels = data.channels ?? [];
|
|
3574
3574
|
const dlqPending = data.dlqPending;
|
|
3575
|
-
const
|
|
3576
|
-
|
|
3577
|
-
{ label: `Delivered (${windowHours}h)`, value: data.totalDelivered },
|
|
3578
|
-
{ label: `Failed (${windowHours}h)`, value: data.totalFailed }
|
|
3579
|
-
];
|
|
3575
|
+
const deliveryRate = ratePct(data.totalDelivered, data.totalSends);
|
|
3576
|
+
const failureRate = ratePct(data.totalFailed, data.totalSends);
|
|
3580
3577
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("section", { "aria-label": "Operations overview", className: (0, import_react_ui29.cn)("flex flex-col gap-5", className), children: [
|
|
3581
3578
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-baseline justify-between gap-2", children: [
|
|
3582
3579
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
@@ -3592,7 +3589,29 @@ function OperationsOverview({ basePath = "/api", className }) {
|
|
|
3592
3589
|
(0, import_react_ui29.formatDateTime)(data.generatedAt)
|
|
3593
3590
|
] })
|
|
3594
3591
|
] }),
|
|
3595
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.
|
|
3592
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-3", children: [
|
|
3593
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_ui29.StatCard, { label: `Sent (${windowHours}h)`, value: data.totalSends, icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(SendIcon, {}) }),
|
|
3594
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3595
|
+
import_react_ui29.StatCard,
|
|
3596
|
+
{
|
|
3597
|
+
label: "Delivery rate",
|
|
3598
|
+
value: deliveryRate,
|
|
3599
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CheckIcon, {}),
|
|
3600
|
+
delta: `${data.totalDelivered} delivered`,
|
|
3601
|
+
trend: "up"
|
|
3602
|
+
}
|
|
3603
|
+
),
|
|
3604
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3605
|
+
import_react_ui29.StatCard,
|
|
3606
|
+
{
|
|
3607
|
+
label: "Failure rate",
|
|
3608
|
+
value: failureRate,
|
|
3609
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(AlertIcon4, {}),
|
|
3610
|
+
delta: `${data.totalFailed} failed`,
|
|
3611
|
+
trend: data.totalFailed > 0 ? "down" : "flat"
|
|
3612
|
+
}
|
|
3613
|
+
)
|
|
3614
|
+
] }),
|
|
3596
3615
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_ui29.Card, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_ui29.CardContent, { className: "flex flex-wrap items-center gap-x-8 gap-y-3 p-5", children: [
|
|
3597
3616
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
3598
3617
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-sm text-muted-foreground", children: "DLQ pending" }),
|
|
@@ -3608,31 +3627,104 @@ function OperationsOverview({ basePath = "/api", className }) {
|
|
|
3608
3627
|
] })
|
|
3609
3628
|
] }) }),
|
|
3610
3629
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_ui29.Card, { children: [
|
|
3611
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.
|
|
3612
|
-
|
|
3613
|
-
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3630
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_ui29.CardHeader, { children: [
|
|
3631
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_ui29.CardTitle, { children: "Channel health" }),
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-sm text-muted-foreground", children: "Delivery success by channel" })
|
|
3633
|
+
] }),
|
|
3634
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_ui29.CardContent, { className: "p-0", children: channels.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "px-5 py-8 text-center text-sm text-muted-foreground", children: "No channel activity" }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("ul", { className: "divide-y divide-border", children: channels.map((row) => {
|
|
3635
|
+
const success = ratePct(row.delivered, row.sends);
|
|
3636
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("li", { className: "flex items-center gap-3 px-5 py-3.5", children: [
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3638
|
+
"span",
|
|
3639
|
+
{
|
|
3640
|
+
"aria-hidden": "true",
|
|
3641
|
+
className: "grid size-9 shrink-0 place-items-center rounded-md bg-primary/10 text-primary [&_svg]:size-4",
|
|
3642
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(ChannelIcon, { channel: row.channel })
|
|
3643
|
+
}
|
|
3644
|
+
),
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
3646
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3647
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "flex items-center gap-2 text-sm font-medium capitalize text-foreground", children: [
|
|
3648
|
+
row.channel,
|
|
3649
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_react_ui29.StatusBadge, { variant: row.failed > 0 ? "warning" : "success", appearance: "dot", children: [
|
|
3650
|
+
success,
|
|
3651
|
+
" success"
|
|
3652
|
+
] })
|
|
3653
|
+
] }),
|
|
3654
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: [
|
|
3655
|
+
row.sends,
|
|
3656
|
+
" sent"
|
|
3657
|
+
] })
|
|
3658
|
+
] }),
|
|
3659
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "mt-2 flex h-1.5 overflow-hidden rounded-full bg-muted", children: [
|
|
3660
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "bg-success", style: { width: `${barPct(row.delivered, row.sends)}%` } }),
|
|
3661
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "bg-destructive", style: { width: `${barPct(row.failed, row.sends)}%` } })
|
|
3662
|
+
] }),
|
|
3663
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "mt-1.5 text-xs tabular-nums text-muted-foreground", children: [
|
|
3664
|
+
row.delivered,
|
|
3665
|
+
" delivered \xB7 ",
|
|
3666
|
+
row.failed,
|
|
3667
|
+
" failed"
|
|
3668
|
+
] })
|
|
3669
|
+
] })
|
|
3670
|
+
] }, row.channel);
|
|
3671
|
+
}) }) })
|
|
3633
3672
|
] })
|
|
3634
3673
|
] });
|
|
3635
3674
|
}
|
|
3675
|
+
function ratePct(n, total) {
|
|
3676
|
+
if (total <= 0) return "\u2014";
|
|
3677
|
+
return `${(n / total * 100).toFixed(2)}%`;
|
|
3678
|
+
}
|
|
3679
|
+
function barPct(n, total) {
|
|
3680
|
+
if (total <= 0) return 0;
|
|
3681
|
+
return Math.min(100, n / total * 100);
|
|
3682
|
+
}
|
|
3683
|
+
function SendIcon() {
|
|
3684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3685
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z" }),
|
|
3686
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m21.854 2.147-10.94 10.939" })
|
|
3687
|
+
] });
|
|
3688
|
+
}
|
|
3689
|
+
function CheckIcon() {
|
|
3690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3691
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M21.801 10A10 10 0 1 1 17 3.335" }),
|
|
3692
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m9 11 3 3L22 4" })
|
|
3693
|
+
] });
|
|
3694
|
+
}
|
|
3695
|
+
function AlertIcon4() {
|
|
3696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3697
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
3698
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m15 9-6 6" }),
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m9 9 6 6" })
|
|
3700
|
+
] });
|
|
3701
|
+
}
|
|
3702
|
+
function ChannelIcon({ channel }) {
|
|
3703
|
+
switch (channel) {
|
|
3704
|
+
case "email":
|
|
3705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3706
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }),
|
|
3707
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" })
|
|
3708
|
+
] });
|
|
3709
|
+
case "sms":
|
|
3710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" }) });
|
|
3711
|
+
case "push":
|
|
3712
|
+
case "inapp":
|
|
3713
|
+
case "in-app":
|
|
3714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3715
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M10.268 21a2 2 0 0 0 3.464 0" }),
|
|
3716
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" })
|
|
3717
|
+
] });
|
|
3718
|
+
case "webhook":
|
|
3719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M10 6.5a3.5 3.5 0 1 1 6 2.45" }),
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M6 10.5a3.5 3.5 0 1 0 5 3.15" }),
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M14 17.5a3.5 3.5 0 1 0 1-6.85" })
|
|
3723
|
+
] });
|
|
3724
|
+
default:
|
|
3725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "12", r: "4" }) });
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3636
3728
|
|
|
3637
3729
|
// src/delivery-log-explorer.tsx
|
|
3638
3730
|
var import_react18 = require("react");
|