[FEAT] Landing NIS2: accesso su invito + form lead request
- index.html: CTA "Registrati" → "Richiedi accesso" (anchor form) Badge hero "Accesso su invito — Richiedi il tuo codice per iniziare" Sezione #richiedi-accesso con form lead (nome, email, azienda, ruolo, dimensioni, messaggio) + JS submit asincrono + stato successo/errore CTA finale aggiornato con messaggio codice invito - ContactController.php: POST /api/contact/request-invite Validazione campi, rate limit 3/10min per IP, email a info@agile.software tramite EmailService con template HTML branded - index.php: route contact → ContactController + action requestInvite Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
6cf1cd7384
commit
0a194f6f12
+229
-11
@@ -74,6 +74,15 @@
|
||||
}
|
||||
.nav-name span { color: var(--cyan); }
|
||||
.nav-actions { display: flex; gap: 12px; align-items: center; }
|
||||
.btn-invite {
|
||||
background: var(--brand-gradient);
|
||||
color: white;
|
||||
box-shadow: 0 4px 16px rgba(6,182,212,0.25);
|
||||
}
|
||||
.btn-invite:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 8px 24px rgba(6,182,212,0.35);
|
||||
}
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -531,6 +540,89 @@
|
||||
}
|
||||
.norma-strip i { color: var(--cyan); }
|
||||
|
||||
/* ── BADGE INVITO ── */
|
||||
.invite-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: rgba(245,158,11,0.1);
|
||||
border: 1px solid rgba(245,158,11,0.25);
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
font-size: 13px;
|
||||
color: var(--orange);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.invite-badge i { font-size: 12px; }
|
||||
|
||||
/* ── FORM LEAD ── */
|
||||
#richiedi-accesso { background: var(--surface-dark); }
|
||||
.form-box {
|
||||
background: var(--brand-primary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 20px;
|
||||
padding: 48px;
|
||||
max-width: 680px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-group { display: flex; flex-direction: column; gap: 8px; }
|
||||
.form-group.full { grid-column: 1 / -1; }
|
||||
.form-group label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-light);
|
||||
}
|
||||
.form-group label span { color: var(--red); margin-left: 2px; }
|
||||
.form-group input,
|
||||
.form-group select,
|
||||
.form-group textarea {
|
||||
background: var(--surface-dark);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
font-size: 14px;
|
||||
color: var(--text-white);
|
||||
font-family: inherit;
|
||||
transition: border-color 0.2s;
|
||||
width: 100%;
|
||||
}
|
||||
.form-group input:focus,
|
||||
.form-group select:focus,
|
||||
.form-group textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--cyan);
|
||||
}
|
||||
.form-group input::placeholder,
|
||||
.form-group textarea::placeholder { color: var(--text-muted); }
|
||||
.form-group select option { background: #1E293B; }
|
||||
.form-group textarea { resize: vertical; min-height: 90px; }
|
||||
.form-submit { width: 100%; padding: 14px; font-size: 16px; margin-top: 8px; }
|
||||
.form-note { font-size: 12px; color: var(--text-muted); text-align: center; margin-top: 12px; }
|
||||
.form-success {
|
||||
display: none;
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
}
|
||||
.form-success i { font-size: 48px; color: var(--green); margin-bottom: 16px; display: block; }
|
||||
.form-success h3 { font-size: 22px; font-weight: 700; color: var(--text-white); margin-bottom: 8px; }
|
||||
.form-success p { color: var(--text-muted); font-size: 15px; }
|
||||
.form-error-msg {
|
||||
display: none;
|
||||
background: rgba(239,68,68,0.08);
|
||||
border: 1px solid rgba(239,68,68,0.2);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
font-size: 13px;
|
||||
color: var(--red);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* ── RESPONSIVE ── */
|
||||
@media (max-width: 900px) {
|
||||
nav { padding: 0 20px; }
|
||||
@@ -546,6 +638,8 @@
|
||||
.lg231-card { flex-direction: column; padding: 28px; }
|
||||
.footer-inner { flex-direction: column; align-items: flex-start; }
|
||||
.nav-actions .btn-ghost { display: none; }
|
||||
.form-grid { grid-template-columns: 1fr; }
|
||||
.form-box { padding: 28px 20px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -561,8 +655,8 @@
|
||||
<a href="/login.html" class="btn btn-ghost btn-sm">
|
||||
<i class="fa-solid fa-right-to-bracket"></i> Accedi
|
||||
</a>
|
||||
<a href="/register.html" class="btn btn-primary btn-sm">
|
||||
<i class="fa-solid fa-rocket"></i> Registrati
|
||||
<a href="#richiedi-accesso" class="btn btn-primary btn-sm">
|
||||
<i class="fa-solid fa-envelope"></i> Richiedi accesso
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -583,12 +677,16 @@
|
||||
<p class="hero-subtitle">
|
||||
Piattaforma SaaS multi-tenant per guidare la tua azienda alla conformità con la Direttiva NIS2 (EU 2022/2555). Gap analysis AI, risk management, incident response Art.23, policy e formazione — tutto integrato.
|
||||
</p>
|
||||
<div class="invite-badge">
|
||||
<i class="fa-solid fa-lock"></i>
|
||||
Accesso su invito — Richiedi il tuo codice per iniziare
|
||||
</div>
|
||||
<div class="hero-ctas">
|
||||
<a href="/register.html" class="btn btn-primary btn-lg">
|
||||
<i class="fa-solid fa-rocket"></i> Inizia gratuitamente
|
||||
<a href="#richiedi-accesso" class="btn btn-primary btn-lg">
|
||||
<i class="fa-solid fa-envelope"></i> Richiedi accesso
|
||||
</a>
|
||||
<a href="/login.html" class="btn btn-ghost btn-lg">
|
||||
<i class="fa-solid fa-right-to-bracket"></i> Accedi
|
||||
<i class="fa-solid fa-right-to-bracket"></i> Ho un codice — Accedi
|
||||
</a>
|
||||
</div>
|
||||
<div class="hero-stats">
|
||||
@@ -849,21 +947,95 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FORM RICHIESTA ACCESSO -->
|
||||
<section id="richiedi-accesso">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<div class="section-eyebrow"><i class="fa-solid fa-envelope"></i> Richiedi accesso</div>
|
||||
<h2 class="section-title">Ottieni il tuo <span class="gradient">codice invito</span></h2>
|
||||
<p class="section-desc">La piattaforma è ad accesso controllato. Compila il form e ti invieremo il codice invito entro 24 ore.</p>
|
||||
</div>
|
||||
<div class="form-box">
|
||||
<div class="form-error-msg" id="formError"></div>
|
||||
<form id="inviteForm">
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label>Nome e Cognome <span>*</span></label>
|
||||
<input type="text" name="nome" placeholder="Mario Rossi" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Email aziendale <span>*</span></label>
|
||||
<input type="email" name="email" placeholder="mario@azienda.it" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Azienda / Studio <span>*</span></label>
|
||||
<input type="text" name="azienda" placeholder="Nome azienda o studio" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Ruolo <span>*</span></label>
|
||||
<select name="ruolo" required>
|
||||
<option value="">Seleziona il tuo ruolo...</option>
|
||||
<option value="Responsabile Compliance / CISO">Responsabile Compliance / CISO</option>
|
||||
<option value="IT Manager / Responsabile Sicurezza">IT Manager / Responsabile Sicurezza</option>
|
||||
<option value="Consulente Cybersecurity / MSSP">Consulente Cybersecurity / MSSP</option>
|
||||
<option value="Direzione / CEO / CTO">Direzione / CEO / CTO</option>
|
||||
<option value="DPO / Legale">DPO / Legale</option>
|
||||
<option value="Altra figura">Altra figura</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full">
|
||||
<label>Dimensioni azienda</label>
|
||||
<select name="dimensioni">
|
||||
<option value="">Seleziona...</option>
|
||||
<option value="Micro (<10 dipendenti)">Micro (<10 dipendenti)</option>
|
||||
<option value="Piccola (10-49 dipendenti)">Piccola (10–49 dipendenti)</option>
|
||||
<option value="Media (50-249 dipendenti)">Media (50–249 dipendenti)</option>
|
||||
<option value="Grande (250+ dipendenti)">Grande (250+ dipendenti)</option>
|
||||
<option value="Studio / Consulente multi-cliente">Studio / Consulente multi-cliente</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group full">
|
||||
<label>Messaggio (opzionale)</label>
|
||||
<textarea name="messaggio" placeholder="Descrivi brevemente la tua esigenza o il settore di appartenenza NIS2..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary form-submit" id="submitBtn">
|
||||
<i class="fa-solid fa-paper-plane"></i> Invia richiesta
|
||||
</button>
|
||||
<p class="form-note">
|
||||
<i class="fa-solid fa-lock" style="color:var(--cyan);margin-right:4px;font-size:11px;"></i>
|
||||
I tuoi dati sono trattati nel rispetto del GDPR. Nessuna cessione a terzi.
|
||||
</p>
|
||||
</form>
|
||||
<div class="form-success" id="formSuccess">
|
||||
<i class="fa-solid fa-circle-check"></i>
|
||||
<h3>Richiesta inviata!</h3>
|
||||
<p>Ti contatteremo entro 24 ore all'indirizzo fornito con il tuo codice di accesso personalizzato.<br><br>
|
||||
<strong style="color:var(--text-white);">Hai già ricevuto un codice?</strong><br>
|
||||
<a href="/register.html" style="color:var(--cyan);text-decoration:none;">Registrati ora con il tuo codice invito →</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<p style="text-align:center;font-size:13px;color:var(--text-muted);margin-top:24px;">
|
||||
Hai già un account? <a href="/login.html" style="color:var(--cyan);text-decoration:none;">Accedi alla dashboard →</a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA FINALE -->
|
||||
<section id="cta-finale">
|
||||
<div class="container">
|
||||
<div class="cta-box">
|
||||
<h2>Inizia oggi la tua<br><span style="background: var(--brand-gradient); -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text;">compliance NIS2</span></h2>
|
||||
<p>Registrazione gratuita. Nessuna carta di credito richiesta. Operativo in 5 minuti.</p>
|
||||
<h2>La tua compliance NIS2<br><span style="background: var(--brand-gradient); -webkit-background-clip:text; -webkit-text-fill-color:transparent; background-clip:text;">inizia con un codice</span></h2>
|
||||
<p>Richiedi l'accesso oggi. Nessuna carta di credito richiesta. Operativo in 5 minuti dal ricevimento del codice.</p>
|
||||
<div class="cta-actions">
|
||||
<a href="/register.html" class="btn btn-primary btn-lg">
|
||||
<i class="fa-solid fa-rocket"></i> Registrati gratis
|
||||
<a href="#richiedi-accesso" class="btn btn-primary btn-lg">
|
||||
<i class="fa-solid fa-envelope"></i> Richiedi il codice invito
|
||||
</a>
|
||||
<a href="/login.html" class="btn btn-ghost btn-lg">
|
||||
<i class="fa-solid fa-right-to-bracket"></i> Accedi
|
||||
</a>
|
||||
</div>
|
||||
<p class="cta-note">Hai già una licenza ricevuta da un consulente? <a href="/register.html" style="color:var(--cyan);text-decoration:none;">Registrati con il tuo codice invito</a></p>
|
||||
<p class="cta-note">Sei un consulente o MSSP? Il form di richiesta ti permette di attivare accesso per il tuo intero portfolio clienti.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -877,8 +1049,8 @@
|
||||
<span style="color:var(--text-muted);font-size:12px;margin-left:8px;">by Agile Technology SRL</span>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<a href="#richiedi-accesso">Richiedi accesso</a>
|
||||
<a href="/login.html">Accedi</a>
|
||||
<a href="/register.html">Registrati</a>
|
||||
<a href="https://lg231.agile.software/" target="_blank">231 Agile</a>
|
||||
<a href="mailto:info@agile.software">info@agile.software</a>
|
||||
</div>
|
||||
@@ -888,5 +1060,51 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
document.getElementById('inviteForm').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
const btn = document.getElementById('submitBtn');
|
||||
const errEl = document.getElementById('formError');
|
||||
const successEl = document.getElementById('formSuccess');
|
||||
const form = e.target;
|
||||
|
||||
errEl.style.display = 'none';
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fa-solid fa-spinner fa-spin"></i> Invio in corso...';
|
||||
|
||||
const data = {
|
||||
nome: form.nome.value.trim(),
|
||||
email: form.email.value.trim(),
|
||||
azienda: form.azienda.value.trim(),
|
||||
ruolo: form.ruolo.value,
|
||||
dimensioni: form.dimensioni.value,
|
||||
messaggio: form.messaggio.value.trim()
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/contact/request-invite', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
const json = await res.json();
|
||||
|
||||
if (res.ok && json.success) {
|
||||
form.style.display = 'none';
|
||||
successEl.style.display = 'block';
|
||||
} else {
|
||||
errEl.textContent = json.message || 'Errore nell\'invio. Riprova o scrivici a info@agile.software.';
|
||||
errEl.style.display = 'block';
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i> Invia richiesta';
|
||||
}
|
||||
} catch {
|
||||
errEl.textContent = 'Errore di rete. Riprova o scrivici a info@agile.software.';
|
||||
errEl.style.display = 'block';
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fa-solid fa-paper-plane"></i> Invia richiesta';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user