Files
ipal-kit/src/globals/SiteIntegrations/components/TestEmailButton.tsx
T

86 lines
2.7 KiB
TypeScript

'use client'
import { useState } from 'react'
/**
* Admin UI: a small "send test email" tool for the SiteIntegrations email tab.
* Enter an address, click Send, and it POSTs to /api/ipal/test-email, which
* sends through the currently-selected transport (SMTP or Graph). Shows the
* result inline so you can confirm delivery — or read the exact error — without
* leaving the panel.
*
* Assigned via a `ui` field's admin.components.Field.
*/
export const TestEmailButton = () => {
const [to, setTo] = useState('')
const [status, setStatus] = useState<
| { kind: 'error'; msg: string }
| { kind: 'idle' }
| { kind: 'ok'; msg: string }
| { kind: 'sending' }
>({ kind: 'idle' })
const send = async () => {
if (!to.trim()) {
setStatus({ kind: 'error', msg: 'Enter a recipient address.' })
return
}
setStatus({ kind: 'sending' })
try {
const res = await fetch('/api/ipal/test-email', {
body: JSON.stringify({ to: to.trim() }),
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
method: 'POST',
})
const data = await res.json()
if (data.ok) {
setStatus({ kind: 'ok', msg: data.message ?? 'Test email sent.' })
} else {
setStatus({ kind: 'error', msg: data.error ?? 'Send failed.' })
}
} catch {
setStatus({ kind: 'error', msg: 'Request failed. Is the server running?' })
}
}
return (
<div className="field-type" style={{ marginTop: '1rem' }}>
<label className="field-label">Send a test email</label>
<p style={{ fontSize: '.85rem', marginTop: 0, opacity: 0.7 }}>
Sends through the transport selected above. Save your changes first.
</p>
<div style={{ alignItems: 'center', display: 'flex', flexWrap: 'wrap', gap: '.5rem' }}>
<input
onChange={(e) => setTo(e.target.value)}
placeholder="[email protected]"
style={{ flex: 1, minWidth: '220px' }}
type="email"
value={to}
/>
<button
className="btn btn--style-secondary"
disabled={status.kind === 'sending'}
onClick={send}
style={{ whiteSpace: 'nowrap' }}
type="button"
>
{status.kind === 'sending' ? 'Sending…' : 'Send test'}
</button>
</div>
{status.kind === 'ok' && (
<p style={{ color: 'var(--theme-success-500, green)', marginTop: '.5rem' }}>
✓ {status.msg}
</p>
)}
{status.kind === 'error' && (
<p style={{ color: 'var(--theme-error-500, crimson)', marginTop: '.5rem' }}>
✗ {status.msg}
</p>
)}
</div>
)
}
export default TestEmailButton