Gestisce errori email del form contatti senza 500 opaco. (#18)
Invia via fetch/JSON, cattura fallimenti Cloudflare Email (con retry senza Reply-To) e reindirizza a #contatti. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
/** Modulo contatti in pagina (#contatti): mailto o POST Formspree. */
|
||||
/** Modulo contatti in pagina (#contatti): mailto o POST /api/contact. */
|
||||
interface ContactFormCfg {
|
||||
actionUrl: string;
|
||||
mailto: string;
|
||||
@ -52,11 +52,18 @@ function readCfg(): ContactFormCfg {
|
||||
return JSON.parse(raw) as ContactFormCfg;
|
||||
}
|
||||
|
||||
function showError(message: string): void {
|
||||
const err = document.getElementById('nx-contact-form-error');
|
||||
if (!err) return;
|
||||
err.textContent = message;
|
||||
err.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function bind(): void {
|
||||
const form = document.getElementById('nx-contact-form') as HTMLFormElement | null;
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', (e) => {
|
||||
form.addEventListener('submit', async (e) => {
|
||||
const cfg = readCfg();
|
||||
const err = document.getElementById('nx-contact-form-error');
|
||||
if (err) err.classList.add('hidden');
|
||||
@ -69,17 +76,44 @@ function bind(): void {
|
||||
)?.value;
|
||||
if (!token) {
|
||||
e.preventDefault();
|
||||
if (err) {
|
||||
err.textContent = cfg.turnstileError;
|
||||
err.classList.remove('hidden');
|
||||
}
|
||||
showError(cfg.turnstileError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.actionUrl) {
|
||||
e.preventDefault();
|
||||
const submitBtn = form.querySelector<HTMLButtonElement>('button[type="submit"]');
|
||||
if (submitBtn) submitBtn.disabled = true;
|
||||
try {
|
||||
const res = await fetch(cfg.actionUrl, {
|
||||
method: 'POST',
|
||||
headers: { Accept: 'application/json' },
|
||||
body: new FormData(form),
|
||||
});
|
||||
const data = (await res.json().catch(() => null)) as
|
||||
| { ok?: boolean; error?: string; redirect?: string }
|
||||
| null;
|
||||
if (!res.ok) {
|
||||
showError(
|
||||
(data && typeof data.error === 'string' && data.error) ||
|
||||
'Invio non riuscito. Riprova tra poco.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
const target =
|
||||
(data && typeof data.redirect === 'string' && data.redirect) ||
|
||||
cfg.successRedirect ||
|
||||
`${window.location.pathname}${window.location.search}#contatti`;
|
||||
window.location.assign(target);
|
||||
} catch {
|
||||
showError('Errore di rete. Controlla la connessione e riprova.');
|
||||
} finally {
|
||||
if (submitBtn) submitBtn.disabled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
const fd = new FormData(form);
|
||||
const name = String(fd.get(cfg.fieldName) ?? '').trim();
|
||||
@ -101,10 +135,7 @@ function bind(): void {
|
||||
window.location.href = `mailto:${cfg.mailto}?subject=${subject}&body=${body}`;
|
||||
return;
|
||||
}
|
||||
if (err) {
|
||||
err.textContent = cfg.configError;
|
||||
err.classList.remove('hidden');
|
||||
}
|
||||
showError(cfg.configError);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user