"use client"; import { useCallback, useEffect, useState } from "react"; import { listNotificationLog, type NotificationLogPage, type NotificationServicio, } from "@/lib/api"; import { formatDateTime, NOTIFICATION_SERVICIO_LABELS, NOTIFICATION_STATUS_COLORS, NOTIFICATION_STATUS_LABELS, NOTIFICATION_TYPE_LABELS, notificationLevelLabel, } from "@/lib/labels"; /** * "Registro de envíos" — the send history over `email_notification_log`. * * Every outbound email the platform sends writes to that one table (the four * bulk jobs and the renewal avisos alike), so this component is shared by * both /notificaciones tabs; each passes the `servicio` slice it owns. Rows * cover failures and skips too, which is the whole point: a notice that never * left is invisible everywhere else. */ const LOG_VIEWS = [ { key: "all", label: "Todos" }, { key: "sent", label: "Enviados" }, { key: "failed", label: "Fallidos" }, { key: "skipped", label: "Omitidos" }, ] as const; export type LogView = (typeof LOG_VIEWS)[number]["key"]; export function NotificationLogPanel({ servicio, emptyHint = "Sin envíos con el filtro actual.", /** Bump to force a reload — the parent raises it after a send. */ reloadToken = 0, }: { servicio: NotificationServicio[]; emptyHint?: string; reloadToken?: number; }) { const [log, setLog] = useState(null); const [error, setError] = useState(null); const [view, setView] = useState("all"); const [page, setPage] = useState(1); // `servicio` is a literal array at every call site, so a new identity each // render would re-fetch forever. Key the effect on its contents instead. const servicioKey = servicio.join(","); const refresh = useCallback(async () => { try { const data = await listNotificationLog({ page, pageSize: 50, servicio: servicioKey.split(",") as NotificationServicio[], view: view === "all" ? undefined : view, }); setLog(data); setError(null); } catch (e) { setError(e instanceof Error ? e.message : String(e)); } }, [page, view, servicioKey]); useEffect(() => { void refresh(); }, [refresh, reloadToken]); return (

Registro de envíos

{LOG_VIEWS.map((v) => ( ))}
{error && (
{error}
)}
{log?.items.map((row) => ( ))} {log && log.items.length === 0 && ( )}
Fecha Tipo Servicio Cliente Email Estado Asunto Provider
{formatDateTime(row.sendDate)} {NOTIFICATION_TYPE_LABELS[row.notificationType]} {notificationLevelLabel(row.notificationType, row.level)} {NOTIFICATION_SERVICIO_LABELS[row.servicio]} {row.customerName} {row.debug ? " · debug" : ""} {row.customerEmail || "—"} {NOTIFICATION_STATUS_LABELS[row.status]} {row.subject} {row.providerMessageId ?? row.error ?? "—"}
{emptyHint}
{log && log.pageCount > 1 && (
{log.total} fila{log.total === 1 ? "" : "s"} · página {log.page} de{" "} {log.pageCount}
)}
); }