"use client"; /** * T-178 — Notifications tab: delivery health for the org's workspaces. * * There is no delivery table, so the metrics are DERIVED: * - in-app: the bell volume (`inAppTotal`) + the unread backlog (`inAppUnread`); * - email: jobs on the shared `email` queue. `emailQueued` is a CLUSTER-wide * count (BullMQ is shared across orgs — a documented limitation); * `emailFailed` / `failedJobs` are org-scoped by correlating each * job's payload `notificationIds` to the org's notification rows * (no-leak: another org's failed emails never appear). */ import { useQuery } from "@tanstack/react-query"; import { MailCheck, MailX, Inbox } from "lucide-react"; import { orgAdminApi } from "@/lib/org-admin"; import { Section } from "@/components/settings/settings-shell"; function fmtTime(iso: string | null): string { if (!iso) return "—"; return new Date(iso).toLocaleString(); } function Stat({ icon: Icon, label, value, tone }: { icon: typeof Inbox; label: string; value: number | string; tone?: "bad" }) { return (
{label}
{value}
); } export function AdminNotificationsTab({ orgId }: { orgId: string }) { const health = useQuery({ queryKey: ["orgs", orgId, "admin", "notifications", "health"], queryFn: () => orgAdminApi.notificationsHealth(orgId), retry: false, refetchInterval: 15_000, }); if (health.isLoading) { return

Loading notification health…

; } if (health.isError) { return

Could not load the notification health.

; } const n = health.data!; const failed = n.failedJobs; return (
0 ? "bad" : undefined} /> 0 ? "bad" : undefined} />
{failed.length === 0 ? (

No failed email jobs for this org.

) : ( )}
); }