'use client'; import { useState } from 'react'; import { Send, CheckCircle2, AlertCircle } from 'lucide-react'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { apiFetch } from '@/lib/api/client'; /** * SMTP connectivity test card. Distinct from the branding-page "Send a * test" affordance: * - This one isolates SMTP - plaintext + minimal HTML, no logo, no * branded shell - so the failure mode is pure transport. * - The branding-preview send exercises the full rendering pipeline. * * Surfaces the SMTP error inline (under the input) instead of toasting, * because the whole point is to read it. ENOTFOUND, EAUTH, connection * refused, etc. land here as a useful diagnostic. */ export function SmtpTestSendCard() { const [recipient, setRecipient] = useState(''); const [sending, setSending] = useState(false); const [result, setResult] = useState< | { kind: 'ok'; recipient: string; messageId: string | null } | { kind: 'err'; message: string } | null >(null); async function send() { if (!recipient) return; setSending(true); setResult(null); try { const res = await apiFetch<{ data: { sent: boolean; recipient: string; messageId: string | null }; }>('/api/v1/admin/email/test-send', { method: 'POST', body: { recipient }, }); setResult({ kind: 'ok', recipient: res.data.recipient, messageId: res.data.messageId, }); toast.success(`Test email accepted by SMTP for ${res.data.recipient}`); } catch (err) { const message = err instanceof Error ? err.message : 'SMTP send failed'; setResult({ kind: 'err', message }); } finally { setSending(false); } } return ( SMTP test send Fires a minimal plaintext email through the configured SMTP host. Use this to confirm credentials reach the wire before a real notification flow depends on them. Errors land inline below so you can read the SMTP response (auth failure, connection refused, etc.).
setRecipient(e.target.value)} placeholder="you@example.com" className="flex-1 min-w-[240px]" />
{result?.kind === 'ok' && (
Accepted by SMTP for {result.recipient}.
{result.messageId ? (
Message-ID: {result.messageId}
) : null}
Acceptance doesn't guarantee inbox delivery. Check the recipient's mailbox (and spam folder) to confirm.
)} {result?.kind === 'err' && (
SMTP send failed
{result.message}
)}
); }