/** * Email settings page * * Shows current email pipeline status, provider info, and allows * sending a test email through the full pipeline. */ import { Button, Input, Loader } from "@cloudflare/kumo"; import { useLingui } from "@lingui/react/macro"; import { CheckCircle, Envelope, PaperPlaneTilt, PlugsConnected, WarningCircle, } from "@phosphor-icons/react"; import { useMutation, useQuery } from "@tanstack/react-query"; import * as React from "react"; import { fetchEmailSettings, sendTestEmail, type EmailSettings as EmailSettingsData, } from "../../lib/api/email-settings.js"; import { getMutationError } from "../DialogError.js"; import { BackToSettingsLink } from "./BackToSettingsLink.js"; export function EmailSettings() { const { t } = useLingui(); const [testEmail, setTestEmail] = React.useState(""); const [status, setStatus] = React.useState<{ type: "success" | "error"; message: string; } | null>(null); // Clear status after 5 seconds React.useEffect(() => { if (!status) return; const timer = setTimeout(setStatus, 5000, null); return () => clearTimeout(timer); }, [status]); const { data: settings, isLoading, error: fetchError, } = useQuery({ queryKey: ["email-settings"], queryFn: fetchEmailSettings, }); const testMutation = useMutation({ mutationFn: (to: string) => sendTestEmail(to), onSuccess: (result) => { setStatus({ type: "success", message: result.message }); setTestEmail(""); }, onError: (error) => { setStatus({ type: "error", message: getMutationError(error) || t`Failed to send test email`, }); }, }); const handleTestSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!testEmail) return; testMutation.mutate(testEmail); }; if (isLoading) { return (
); } if (fetchError) { return (

{t`Email Settings`}

{getMutationError(fetchError) || t`Failed to load email settings`}
); } return (
{/* Header */}

{t`Email Settings`}

{/* Status banner */} {status && (
{status.type === "success" ? ( ) : ( )} {status.message}
)} {/* Pipeline status */}

{t`Email Pipeline`}

{/* Test email */} {settings?.available && (

{t`Send Test Email`}

{t`Send a test email through the full pipeline to verify your email configuration.`}

setTestEmail(e.target.value)} placeholder={t`test@example.com`} required />
)}
); } // ============================================================================= // Pipeline status display // ============================================================================= function PipelineStatus({ settings }: { settings: EmailSettingsData | undefined }) { const { t } = useLingui(); if (!settings) return null; if (!settings.available) { return (

{t`No email provider configured`}

{t`Install and activate an email provider plugin to enable email features like invitations, magic links, and password recovery.`}

{t`Without an email provider, invite links must be shared manually.`}

); } return (
{/* Provider */}

{t`Email provider active`}

{t`Provider:`}{" "} {settings.selectedProviderId || "default"}

{/* Middleware */} {(settings.middleware.beforeSend.length > 0 || settings.middleware.afterSend.length > 0) && (

{t`Email Middleware`}

{settings.middleware.beforeSend.length > 0 && (

{t`Before send:`} {settings.middleware.beforeSend.join(", ")}

)} {settings.middleware.afterSend.length > 0 && (

{t`After send:`} {settings.middleware.afterSend.join(", ")}

)}
)} {/* Available providers (if multiple) */} {settings.providers.length > 1 && (

{t`Available Providers`}

{settings.providers.map((p) => p.pluginId).join(", ")}

)}
); }