[FEAT] Ruolo Consulente + Wizard Registrazione v2

- register.html: step 0 scelta profilo (Azienda / Consulente)
- onboarding.html: wizard 4-step con P.IVA obbligatoria (auto-fetch CertiSource)
- companies.html: nuova dashboard consulente con cards aziende e compliance score
- common.js: org-switcher sidebar + role labels corretti per consulente
- login.html: routing post-login (consulente → companies.html)
- api.js: isConsultant(), setUserRole(), register con user_type
- AuthController: user_type=consultant → role=consultant in users table
- OnboardingController: multi-org per consulente, duplicate VAT check
- 005_consultant_support.sql: aggiunge 'consultant' a user_organizations.role ENUM

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile
2026-02-20 08:53:30 +01:00
co-authored by Claude Sonnet 4.6
parent ba21534e6a
commit 7080695d06
9 changed files with 976 additions and 323 deletions
+123 -227
View File
@@ -745,26 +745,21 @@
<div class="stepper" id="stepper">
<div class="stepper-step active" data-step="1">
<div class="stepper-number">1</div>
<span class="stepper-label">Benvenuto</span>
<span class="stepper-label">Partita IVA</span>
</div>
<div class="stepper-connector" data-after="1"></div>
<div class="stepper-step" data-step="2">
<div class="stepper-number">2</div>
<span class="stepper-label">Acquisizione Dati</span>
<span class="stepper-label">Dati Aziendali</span>
</div>
<div class="stepper-connector" data-after="2"></div>
<div class="stepper-step" data-step="3">
<div class="stepper-number">3</div>
<span class="stepper-label">Dati Aziendali</span>
<span class="stepper-label">Il Tuo Profilo</span>
</div>
<div class="stepper-connector" data-after="3"></div>
<div class="stepper-step" data-step="4">
<div class="stepper-number">4</div>
<span class="stepper-label">Il Tuo Profilo</span>
</div>
<div class="stepper-connector" data-after="4"></div>
<div class="stepper-step" data-step="5">
<div class="stepper-number">5</div>
<span class="stepper-label">Classificazione</span>
</div>
</div>
@@ -774,66 +769,48 @@
<div class="wizard-body">
<div class="wizard-content">
<!-- ═══ STEP 1: Benvenuto ═══ -->
<!-- ═══ STEP 1: Partita IVA ═══ -->
<div class="wizard-step active" id="step-1">
<h2 class="wizard-step-title">Configura il tuo ambiente NIS2</h2>
<p class="wizard-step-subtitle">Per iniziare, abbiamo bisogno dei dati della tua azienda. Puoi fornirli in tre modi:</p>
<h2 class="wizard-step-title">Inserisci la Partita IVA dell'azienda</h2>
<p class="wizard-step-subtitle">Inserisci la Partita IVA dell'azienda da configurare. I dati verranno recuperati automaticamente dal registro delle imprese.</p>
<div class="option-cards">
<!-- Carica Visura -->
<div class="option-card" data-method="visura" onclick="selectMethod('visura')">
<div class="option-card-check">
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
<div class="card" style="max-width:520px; margin:0 auto;">
<div class="card-body">
<div class="form-group">
<label class="form-label" for="s1-vat">Partita IVA <span class="required">*</span></label>
<div style="display:flex; gap:.5rem;">
<span style="display:flex;align-items:center;padding:0 12px;background:var(--gray-100);border:1px solid var(--gray-300);border-radius:var(--border-radius);font-weight:600;color:var(--gray-600);">IT</span>
<input type="text" id="s1-vat" class="form-input" placeholder="12345678901" maxlength="11"
style="flex:1;" oninput="this.value=this.value.replace(/\D/g,'')">
</div>
<div class="form-help">11 cifre numeriche senza prefisso IT</div>
</div>
<div class="option-card-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="12" y1="18" x2="12" y2="12"/>
<line x1="9" y1="15" x2="15" y2="15"/>
</svg>
</div>
<div class="option-card-title">Carica Visura Camerale</div>
<div class="option-card-desc">Carica il PDF della visura camerale e i dati verranno estratti automaticamente con l'AI</div>
</div>
<!-- CertiSource -->
<div class="option-card" data-method="certisource" onclick="selectMethod('certisource')">
<div class="option-card-check">
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
</div>
<div class="option-card-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"/>
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
<path d="M11 8v6"/>
<path d="M8 11h6"/>
</svg>
</div>
<div class="option-card-title">Recupera con CertiSource</div>
<div class="option-card-desc">Inserisci la Partita IVA e recupereremo automaticamente i dati aziendali tramite CertiSource</div>
</div>
<div id="s1-result" style="display:none; padding:.75rem; border-radius:8px; margin-bottom:1rem;"></div>
<!-- Manuale -->
<div class="option-card" data-method="manual" onclick="selectMethod('manual')">
<div class="option-card-check">
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg>
</div>
<div class="option-card-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
</svg>
</div>
<div class="option-card-title">Inserisci Manualmente</div>
<div class="option-card-desc">Compila tu stesso i dati dell'azienda</div>
<button class="btn btn-primary btn-lg w-full" id="s1-fetch-btn" onclick="step1FetchCompany()">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"/></svg>
Cerca Azienda
</button>
</div>
</div>
<div class="wizard-actions" id="step1-actions" style="display:none;">
<div class="wizard-loading" id="s1-loading">
<div class="spinner spinner-lg"></div>
<div class="wizard-loading-text">Ricerca in corso...</div>
<div class="wizard-loading-subtext">Interrogazione registro imprese</div>
</div>
<div style="text-align:center; margin-top:1.5rem;">
<button class="btn btn-link" onclick="step1ManualEntry()" style="color:var(--gray-500);font-size:.85rem;">
Non trovi l'azienda? Inserisci manualmente
</button>
</div>
<div class="wizard-actions" style="margin-top:2rem;">
<div></div>
<div class="wizard-actions-right">
<button class="btn btn-primary btn-lg" onclick="goToStep(2)">
<button class="btn btn-primary btn-lg" id="s1-continue-btn" onclick="goToStep(2)" style="display:none;">
Continua
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</button>
@@ -841,100 +818,8 @@
</div>
</div>
<!-- ═══ STEP 2: Acquisizione Dati ═══ -->
<div class="wizard-step" id="step-2">
<!-- 2a: Visura Upload -->
<div id="step2-visura" style="display:none;">
<h2 class="wizard-step-title">Carica la Visura Camerale</h2>
<p class="wizard-step-subtitle">Carica il file PDF della visura camerale. I dati aziendali verranno estratti automaticamente tramite intelligenza artificiale.</p>
<div class="upload-area" id="upload-area">
<input type="file" id="visura-file" accept=".pdf" />
<div class="upload-area-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="17 8 12 3 7 8"/>
<line x1="12" y1="3" x2="12" y2="15"/>
</svg>
</div>
<div class="upload-area-title">Trascina qui il file PDF oppure clicca per selezionarlo</div>
<div class="upload-area-hint">Rilascia il file per caricarlo</div>
<div class="upload-area-formats">Formato accettato: PDF - Dimensione massima: 10 MB</div>
<div class="upload-file-info" id="upload-file-info">
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
<span id="upload-file-name"></span>
</div>
</div>
<div style="margin-top:24px; text-align:center;" id="visura-upload-btn-area">
<button class="btn btn-primary btn-lg" id="analyze-visura-btn" disabled onclick="analyzeVisura()">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path d="M5 2a1 1 0 011 1v1h1a1 1 0 010 2H6v1a1 1 0 01-2 0V6H3a1 1 0 010-2h1V3a1 1 0 011-1zm0 10a1 1 0 011 1v1h1a1 1 0 110 2H6v1a1 1 0 11-2 0v-1H3a1 1 0 110-2h1v-1a1 1 0 011-1zm7-10a1 1 0 01.967.744L14.146 7.2 17.5 8.512a1 1 0 010 1.836l-3.354 1.311-1.18 4.456a1 1 0 01-1.932 0L9.854 11.66 6.5 10.348a1 1 0 010-1.836l3.354-1.311 1.18-4.456A1 1 0 0112 2z"/></svg>
Analizza Visura
</button>
</div>
<!-- Loading -->
<div class="wizard-loading" id="visura-loading">
<div class="spinner spinner-lg"></div>
<div class="wizard-loading-text">Analisi AI in corso...</div>
<div class="wizard-loading-subtext">Stiamo estraendo i dati dalla visura camerale</div>
</div>
<div class="wizard-actions">
<button class="btn btn-secondary" onclick="goToStep(1)">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/></svg>
Indietro
</button>
<div></div>
</div>
</div>
<!-- 2b: CertiSource -->
<div id="step2-certisource" style="display:none;">
<h2 class="wizard-step-title">Recupera Dati con CertiSource</h2>
<p class="wizard-step-subtitle">Inserisci la Partita IVA dell'azienda e recupereremo automaticamente i dati aziendali dal registro delle imprese.</p>
<div class="card" style="max-width:520px; margin:0 auto;">
<div class="card-body">
<div class="form-group">
<label class="form-label" for="cs-vat">Partita IVA <span class="required">*</span></label>
<input type="text" id="cs-vat" class="form-input" placeholder="Es. 12345678901 o IT12345678901" maxlength="16">
<div class="form-help">Inserisci la Partita IVA con o senza prefisso paese</div>
</div>
<button class="btn btn-primary btn-lg w-full" id="fetch-company-btn" onclick="fetchCompany()">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"/></svg>
Recupera Dati
</button>
</div>
</div>
<!-- Loading -->
<div class="wizard-loading" id="certisource-loading">
<div class="spinner spinner-lg"></div>
<div class="wizard-loading-text">Recupero dati da CertiSource...</div>
<div class="wizard-loading-subtext">Stiamo interrogando il registro delle imprese</div>
</div>
<div style="text-align:center; margin-top:24px;">
<div class="certisource-badge">
<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M2.166 4.999A11.954 11.954 0 0010 1.944 11.954 11.954 0 0017.834 5c.11.65.166 1.32.166 2 0 5.225-3.34 9.67-8 11.317C5.34 16.67 2 12.225 2 7c0-.682.057-1.35.166-2.001zm11.541 3.708a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>
Powered by CertiSource
</div>
</div>
<div class="wizard-actions">
<button class="btn btn-secondary" onclick="goToStep(1)">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/></svg>
Indietro
</button>
<div></div>
</div>
</div>
</div>
<!-- ═══ STEP 3: Dati Aziendali ═══ -->
<div class="wizard-step" id="step-3">
<div class="wizard-step" id="step-2">
<h2 class="wizard-step-title">Verifica e Completa i Dati Aziendali</h2>
<p class="wizard-step-subtitle">Controlla i dati qui sotto e completa le informazioni mancanti.</p>
@@ -1044,7 +929,7 @@
</div>
<div class="wizard-actions">
<button class="btn btn-secondary" onclick="goToStep(wizardState.method === 'manual' ? 1 : 2)">
<button class="btn btn-secondary" onclick="goToStep(1)">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/></svg>
Indietro
</button>
@@ -1058,7 +943,7 @@
</div>
<!-- ═══ STEP 4: Il Tuo Profilo ═══ -->
<div class="wizard-step" id="step-4">
<div class="wizard-step" id="step-3">
<h2 class="wizard-step-title">Completa il tuo profilo</h2>
<p class="wizard-step-subtitle">Inserisci le informazioni sul tuo ruolo in azienda.</p>
@@ -1096,7 +981,7 @@
</div>
<div class="wizard-actions">
<button class="btn btn-secondary" onclick="goToStep(3)">
<button class="btn btn-secondary" onclick="goToStep(2)">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/></svg>
Indietro
</button>
@@ -1110,7 +995,7 @@
</div>
<!-- ═══ STEP 5: Classificazione NIS2 e Riepilogo ═══ -->
<div class="wizard-step" id="step-5">
<div class="wizard-step" id="step-4">
<h2 class="wizard-step-title">Classificazione NIS2</h2>
<p class="wizard-step-subtitle">In base ai dati forniti, ecco la classificazione della tua organizzazione secondo la Direttiva NIS2.</p>
@@ -1175,7 +1060,7 @@
</div>
<div class="wizard-actions">
<button class="btn btn-secondary" onclick="goToStep(4)">
<button class="btn btn-secondary" onclick="goToStep(3)">
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clip-rule="evenodd"/></svg>
Indietro
</button>
@@ -1259,35 +1144,78 @@
return parseInt(str) || '';
}
// ── Step 1: Method selection ────────────────────────────────────
function selectMethod(method) {
wizardState.method = method;
// ── Step 1: P.IVA Fetch ─────────────────────────────────────────
async function step1FetchCompany() {
const vat = document.getElementById('s1-vat').value.trim();
if (!vat || vat.length !== 11) {
showNotification('Inserisci una Partita IVA valida (11 cifre numeriche).', 'warning');
return;
}
// Update UI
document.querySelectorAll('.option-card').forEach(card => {
card.classList.toggle('selected', card.dataset.method === method);
});
const btn = document.getElementById('s1-fetch-btn');
const loading = document.getElementById('s1-loading');
const resultDiv = document.getElementById('s1-result');
// Show continue button
document.getElementById('step1-actions').style.display = 'flex';
btn.disabled = true;
loading.classList.add('active');
resultDiv.style.display = 'none';
try {
const result = await api.fetchCompany(vat);
if (result.success && result.data) {
const d = result.data;
wizardState.company.name = d.company_name || d.ragione_sociale || d.name || '';
wizardState.company.vat_number = vat;
wizardState.company.fiscal_code = d.fiscal_code || d.codice_fiscale || '';
wizardState.company.address = d.address || d.indirizzo || '';
wizardState.company.city = d.city || d.citta || '';
wizardState.company.website = d.website || d.sito_web || '';
wizardState.company.email = d.email || d.pec || '';
wizardState.company.phone = d.phone || d.telefono || '';
wizardState.company.sector = d.suggested_sector || d.sector || '';
wizardState.company.employee_count = parseEmployeesRange(d.employees_range) || d.employee_count || d.employees || '';
wizardState.company.annual_turnover = '';
wizardState.dataSource = 'Dati precompilati da CertiSource';
wizardState.autoFilledFields.clear();
if (wizardState.company.name) wizardState.autoFilledFields.add('company-name');
if (wizardState.company.vat_number) wizardState.autoFilledFields.add('vat-number');
if (wizardState.company.fiscal_code) wizardState.autoFilledFields.add('fiscal-code');
if (wizardState.company.address) wizardState.autoFilledFields.add('address');
if (wizardState.company.city) wizardState.autoFilledFields.add('city');
if (wizardState.company.email) wizardState.autoFilledFields.add('company-email');
if (wizardState.company.phone) wizardState.autoFilledFields.add('company-phone');
if (wizardState.company.sector) wizardState.autoFilledFields.add('sector');
if (wizardState.company.employee_count) wizardState.autoFilledFields.add('employee-count');
resultDiv.style.cssText = 'display:block; padding:.75rem; border-radius:8px; background:var(--success-bg); color:var(--secondary);';
resultDiv.innerHTML = '<strong>✓ ' + (wizardState.company.name || 'Azienda trovata') + '</strong><br><small>' + (d.address || d.city || '') + '</small>';
document.getElementById('s1-continue-btn').style.display = 'inline-flex';
showNotification('Azienda trovata: ' + (wizardState.company.name || vat), 'success');
} else {
resultDiv.style.cssText = 'display:block; padding:.75rem; border-radius:8px; background:var(--warning-bg,#fff3cd); color:#856404;';
resultDiv.textContent = 'Azienda non trovata. Puoi inserire i dati manualmente.';
step1ManualEntry(vat);
}
} catch (err) {
showNotification('Errore di connessione al server.', 'error');
} finally {
btn.disabled = false;
loading.classList.remove('active');
}
}
function step1ManualEntry(vat) {
wizardState.company.vat_number = vat || document.getElementById('s1-vat').value.trim();
wizardState.dataSource = null;
wizardState.autoFilledFields.clear();
document.getElementById('s1-continue-btn').style.display = 'inline-flex';
showNotification('Inserisci i dati aziendali manualmente.', 'info');
}
// ── Step navigation ─────────────────────────────────────────────
function goToStep(step) {
const prevStep = wizardState.currentStep;
// If going from step 1 to step 2, handle method routing
if (prevStep === 1 && step === 2) {
if (!wizardState.method) {
showNotification('Seleziona un metodo per procedere.', 'warning');
return;
}
if (wizardState.method === 'manual') {
// Skip step 2, go directly to step 3
step = 3;
}
}
wizardState.currentStep = step;
// Hide all steps
@@ -1297,24 +1225,18 @@
const targetStep = document.getElementById('step-' + step);
if (targetStep) targetStep.classList.add('active');
// If step 2, show the appropriate sub-panel
// Step 2: populate company form from wizard state
if (step === 2) {
document.getElementById('step2-visura').style.display = wizardState.method === 'visura' ? 'block' : 'none';
document.getElementById('step2-certisource').style.display = wizardState.method === 'certisource' ? 'block' : 'none';
}
// If step 3, populate form from state
if (step === 3) {
populateCompanyForm();
}
// If step 4, load user profile
if (step === 4) {
// Step 3: load user profile
if (step === 3) {
loadUserProfile();
}
// If step 5, run classification and populate summary
if (step === 5) {
// Step 4: run classification and populate summary
if (step === 4) {
runClassificationAndSummary();
}
@@ -1349,34 +1271,7 @@
});
}
// ── Step 2a: Visura Upload ──────────────────────────────────────
const uploadArea = document.getElementById('upload-area');
const visuraFileInput = document.getElementById('visura-file');
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('dragover');
});
uploadArea.addEventListener('dragleave', (e) => {
e.preventDefault();
uploadArea.classList.remove('dragover');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files.length > 0) {
handleVisuraFile(files[0]);
}
});
visuraFileInput.addEventListener('change', (e) => {
if (e.target.files.length > 0) {
handleVisuraFile(e.target.files[0]);
}
});
// ── Step 2a: Visura Upload (legacy, kept for API completeness) ──
function handleVisuraFile(file) {
// Validate type
@@ -1509,7 +1404,7 @@
showNotification('Dati aziendali recuperati con successo!', 'success');
// Auto-advance to step 3
setTimeout(() => goToStep(3), 600);
setTimeout(() => goToStep(2), 600);
} else {
showNotification(result.message || 'Impossibile recuperare i dati. Verifica la Partita IVA.', 'error');
}
@@ -1556,7 +1451,7 @@
// Apply auto-fill visual indicators
const autoFields = wizardState.autoFilledFields;
document.querySelectorAll('#step-3 .form-input, #step-3 .form-select').forEach(el => {
document.querySelectorAll('#step-2 .form-input, #step-2 .form-select').forEach(el => {
const wrapper = el.closest('.form-group');
if (!wrapper) return;
@@ -1569,7 +1464,7 @@
wrapper.classList.add('auto-filled');
const badge = document.createElement('span');
badge.className = 'auto-fill-badge';
badge.textContent = 'da visura';
badge.textContent = wizardState.dataSource ? 'auto-compilato' : 'da visura';
const label = wrapper.querySelector('.form-label');
if (label) label.appendChild(badge);
}
@@ -1618,7 +1513,7 @@
wizardState.company.employee_count = parseInt(employees);
wizardState.company.annual_turnover = parseInt(turnover);
goToStep(4);
goToStep(3);
}
// ── Step 4: User Profile ────────────────────────────────────────
@@ -1650,7 +1545,7 @@
wizardState.profile.role = role;
wizardState.profile.phone = document.getElementById('user-phone').value.trim();
goToStep(5);
goToStep(4);
}
// ── Step 5: Classification & Summary ────────────────────────────
@@ -1835,7 +1730,8 @@
showNotification('Configurazione completata con successo!', 'success');
setTimeout(() => {
window.location.href = 'dashboard.html';
const dest = api.isConsultant() ? 'companies.html' : 'dashboard.html';
window.location.href = dest;
}, 1000);
} else {
showNotification(result.message || 'Errore nel completamento.', 'error');
@@ -1849,11 +1745,11 @@
}
}
// ── Allow CertiSource VAT input to submit with Enter ────────────
document.getElementById('cs-vat').addEventListener('keypress', (e) => {
// ── Allow P.IVA input to submit with Enter ───────────────────────
document.getElementById('s1-vat').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
fetchCompany();
step1FetchCompany();
}
});
</script>