feat: layout base con header, footer e 404

This commit is contained in:
2026-07-02 00:48:14 +02:00
parent ac75720bd9
commit 2fdd1b9a7f
6 changed files with 187 additions and 2 deletions
+42
View File
@@ -0,0 +1,42 @@
---
interface Props { variant?: 'full' | 'footer' }
const { variant = 'full' } = Astro.props;
---
<form class:list={['cform', `cform--${variant}`]} method="post" action="/api/contact" novalidate>
<input class="field" name="firstName" placeholder="Nome" required maxlength="100" />
{variant === 'full' && <input class="field" name="lastName" placeholder="Cognome" maxlength="100" />}
{variant === 'full' && <input class="field" name="phone" placeholder="Telefono" maxlength="40" />}
<input class="field" type="email" name="email" placeholder="E-mail" required maxlength="200" />
<textarea class="field" name="message" placeholder="Messaggio" required maxlength="5000"></textarea>
<input class="hp" type="text" name="website" tabindex="-1" autocomplete="off" />
<button class="btn" type="submit">Invia messaggio</button>
<p class="form-msg" hidden></p>
</form>
<script>
document.querySelectorAll<HTMLFormElement>('.cform').forEach((form) => {
form.addEventListener('submit', async (e) => {
e.preventDefault();
const msg = form.querySelector<HTMLParagraphElement>('.form-msg')!;
const btn = form.querySelector<HTMLButtonElement>('button')!;
btn.disabled = true;
msg.hidden = true;
try {
const res = await fetch('/api/contact', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(Object.fromEntries(new FormData(form))),
});
const data = await res.json();
msg.textContent = res.ok ? 'Messaggio inviato, ti ricontatteremo al più presto.' : (data.error ?? 'Errore di invio, riprova più tardi.');
msg.className = `form-msg ${res.ok ? 'form-msg--ok' : 'form-msg--err'}`;
if (res.ok) form.reset();
} catch {
msg.textContent = 'Errore di rete, riprova più tardi.';
msg.className = 'form-msg form-msg--err';
}
msg.hidden = false;
btn.disabled = false;
});
});
</script>