"use client"; import { useActionState } from "react"; import { Mail } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Pill } from "@/components/mockup-ui"; import { sendTestMail, type TestMailState } from "@/server/actions/mail"; /** * SEC1 §9 — Betriebsanzeige der Mail-Strecke + Testversand. * * Der Testversand geht immer an die eigene Adresse des angemeldeten * Plattform-Admins (siehe src/server/actions/mail.ts) — deshalb gibt es hier * bewusst kein Empfängerfeld. */ type MailStatus = { configured: boolean; reason?: string; host?: string; from?: string; queue: "bullmq" | "inline"; recent: { id: string; to: string; template: string; status: string; error: string | null; createdAt: Date; }[]; }; const STATUS_TONE: Record = { sent: "ok", pending: "warn", failed: "risk", bounced: "risk", suppressed: "mut", }; export function MailStatusPanel({ status }: { status: MailStatus }) { const [state, action, pending] = useActionState( async () => sendTestMail(), { status: "idle" }, ); return (

E-Mail-Versand

{status.configured ? `SMTP ${status.host} · Absender ${status.from} · ${ status.queue === "bullmq" ? "asynchron über die Queue (Worker)" : "inline (kein Redis konfiguriert — kein Retry)" }` : (status.reason ?? "SMTP ist nicht konfiguriert.")}

{status.configured ? "Konfiguriert" : "Nicht konfiguriert"}
{state.status !== "idle" && (

{state.message}

)} {status.recent.length > 0 && (
{status.recent.map((row) => ( ))}
Zeitpunkt Empfänger Template Status
{new Intl.DateTimeFormat("de-DE", { dateStyle: "short", timeStyle: "short", }).format(new Date(row.createdAt))} {row.to} {row.template} {row.status} {row.error && ( {row.error.slice(0, 60)} {row.error.length > 60 ? "…" : ""} )}
)}
); }