[UI] V2 (Bootstrap Italia/AGID) completata: migrate architecture+workflow (sidebar V2) + integrazioniext+mktg-api-doc (CSS BI); rimossa setup-org morta; v1.23.10
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
81282af35a
commit
7ad5d685b6
@@ -4,6 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>Architettura - NIS2 Agile</title>
|
||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN), PRIMA di style.css cosi' il design system esistente resta autorevole -->
|
||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||
<link rel="stylesheet" href="css/style.css?v=20260618">
|
||||
<style>
|
||||
/* ── Architecture Page Styles ────────────────────────────────── */
|
||||
@@ -1090,6 +1092,8 @@
|
||||
|
||||
<script src="js/api.js?v=20260631"></script>
|
||||
<script src="js/common.js?v=20260631"></script>
|
||||
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
|
||||
<script src="/js/common-bi.js?v=20260631"></script>
|
||||
<script src="js/i18n.js?v=20260631"></script>
|
||||
<script src="js/help.js?v=20260618p2"></script>
|
||||
<script>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>NIS2 Agile — Integrazioni Esterne</title>
|
||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN), PRIMA di style.css cosi' il design system esistente resta autorevole -->
|
||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||
<link rel="stylesheet" href="css/style.css?v=20260618">
|
||||
<style>
|
||||
/* ── Page-specific overrides ── */
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>NIS2 Agile — License API · Documentazione Marketing</title>
|
||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN), PRIMA di style.css cosi' il design system esistente resta autorevole -->
|
||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||
<link rel="stylesheet" href="css/style.css?v=20260618">
|
||||
<style>
|
||||
.doc-layout { max-width: 860px; margin: 0 auto; padding: 2rem 1.5rem; }
|
||||
|
||||
@@ -1,390 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>Configura Organizzazione - NIS2 Agile</title>
|
||||
<link rel="stylesheet" href="css/style.css?v=20260618">
|
||||
<!-- PWA:start -->
|
||||
<link rel="manifest" href="/manifest.webmanifest">
|
||||
<meta name="theme-color" content="#0066CC">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||
<meta name="apple-mobile-web-app-title" content="NIS2 Agile">
|
||||
<meta name="application-name" content="NIS2 Agile">
|
||||
<script src="/js/pwa.js?v=20260614" defer></script>
|
||||
<!-- PWA:end -->
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-layout">
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar" id="sidebar"></aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="main-content">
|
||||
<header class="content-header">
|
||||
<h2>Configurazione Organizzazione</h2>
|
||||
</header>
|
||||
|
||||
<div class="content-body">
|
||||
<div class="grid-2" style="max-width:960px;">
|
||||
<!-- Form -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Dati Aziendali</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="org-form" novalidate>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="company-name">Ragione Sociale <span class="required">*</span></label>
|
||||
<input type="text" id="company-name" class="form-input"
|
||||
placeholder="Es. Acme S.r.l." required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="vat-number">Partita IVA</label>
|
||||
<input type="text" id="vat-number" class="form-input"
|
||||
placeholder="IT12345678901" maxlength="16">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="sector">Settore <span class="required">*</span></label>
|
||||
<select id="sector" class="form-select" required>
|
||||
<option value="">-- Seleziona settore --</option>
|
||||
<optgroup label="Settori ad Alta Criticita' (Allegato I)">
|
||||
<option value="energy_electricity">Energia - Elettricita'</option>
|
||||
<option value="energy_district_heating">Energia - Teleriscaldamento</option>
|
||||
<option value="energy_oil">Energia - Petrolio</option>
|
||||
<option value="energy_gas">Energia - Gas</option>
|
||||
<option value="energy_hydrogen">Energia - Idrogeno</option>
|
||||
<option value="transport_air">Trasporti - Aereo</option>
|
||||
<option value="transport_rail">Trasporti - Ferroviario</option>
|
||||
<option value="transport_water">Trasporti - Marittimo/Fluviale</option>
|
||||
<option value="transport_road">Trasporti - Stradale</option>
|
||||
<option value="banking">Banche</option>
|
||||
<option value="financial_markets">Infrastrutture Mercati Finanziari</option>
|
||||
<option value="health">Sanita'</option>
|
||||
<option value="drinking_water">Acqua Potabile</option>
|
||||
<option value="waste_water">Acque Reflue</option>
|
||||
<option value="digital_infrastructure">Infrastruttura Digitale</option>
|
||||
<option value="ict_service_management">Gestione Servizi ICT (B2B)</option>
|
||||
<option value="public_administration">Pubblica Amministrazione</option>
|
||||
<option value="space">Spazio</option>
|
||||
</optgroup>
|
||||
<optgroup label="Altri Settori Critici (Allegato II)">
|
||||
<option value="postal_courier">Servizi Postali e Corrieri</option>
|
||||
<option value="waste_management">Gestione Rifiuti</option>
|
||||
<option value="chemicals">Fabbricazione Prodotti Chimici</option>
|
||||
<option value="food">Produzione e Distribuzione Alimentare</option>
|
||||
<option value="manufacturing_medical">Fabbricazione - Dispositivi Medici</option>
|
||||
<option value="manufacturing_computers">Fabbricazione - Computer/Elettronica</option>
|
||||
<option value="manufacturing_electrical">Fabbricazione - Apparecchiature Elettriche</option>
|
||||
<option value="manufacturing_machinery">Fabbricazione - Macchinari</option>
|
||||
<option value="manufacturing_vehicles">Fabbricazione - Autoveicoli</option>
|
||||
<option value="manufacturing_transport">Fabbricazione - Altri Mezzi di Trasporto</option>
|
||||
<option value="digital_providers">Fornitori Servizi Digitali</option>
|
||||
<option value="research">Organizzazioni di Ricerca</option>
|
||||
</optgroup>
|
||||
<optgroup label="Altro">
|
||||
<option value="other">Altro Settore</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="employee-count">Numero Dipendenti <span class="required">*</span></label>
|
||||
<input type="number" id="employee-count" class="form-input"
|
||||
placeholder="Es. 150" min="1" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="annual-turnover">Fatturato Annuo (EUR) <span class="required">*</span></label>
|
||||
<input type="number" id="annual-turnover" class="form-input"
|
||||
placeholder="Es. 15000000" min="0" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg w-full mt-16" id="save-btn">
|
||||
Salva e Continua
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Classification Preview -->
|
||||
<div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Classificazione NIS2</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="classification-preview not-applicable" id="classification-preview">
|
||||
<div class="classification-label">In Attesa</div>
|
||||
<p class="classification-desc">
|
||||
Compila i dati aziendali per ottenere la classificazione automatica
|
||||
secondo i criteri della Direttiva NIS2 (UE) 2022/2555.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mt-24" id="classification-details" style="display:none;">
|
||||
<h4 style="font-size:0.875rem; margin-bottom:12px; color:var(--gray-700);">Dettagli Classificazione</h4>
|
||||
<div id="classification-info" style="font-size:0.8125rem; color:var(--gray-600); line-height:1.7;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-24">
|
||||
<div class="card-header">
|
||||
<h3>Criteri di Classificazione</h3>
|
||||
</div>
|
||||
<div class="card-body" style="font-size:0.8125rem; color:var(--gray-600); line-height:1.7;">
|
||||
<p><strong>Soggetti Essenziali:</strong></p>
|
||||
<ul style="padding-left:20px; margin-bottom:12px;">
|
||||
<li>Settori Allegato I con ≥ 250 dipendenti o fatturato ≥ 50M EUR</li>
|
||||
<li>Alcuni soggetti designati indipendentemente dalle dimensioni</li>
|
||||
</ul>
|
||||
<p><strong>Soggetti Importanti:</strong></p>
|
||||
<ul style="padding-left:20px; margin-bottom:12px;">
|
||||
<li>Settori Allegato I/II con ≥ 50 dipendenti o fatturato ≥ 10M EUR</li>
|
||||
<li>Non qualificati come essenziali</li>
|
||||
</ul>
|
||||
<p><strong>Non Applicabile:</strong></p>
|
||||
<ul style="padding-left:20px;">
|
||||
<li>Organizzazioni sotto le soglie minime</li>
|
||||
<li>Settori non coperti dalla direttiva</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="js/api.js?v=20260631"></script>
|
||||
<script src="js/common.js?v=20260631"></script>
|
||||
<script>
|
||||
// ── Auth check ───────────────────────────────────────────
|
||||
if (!checkAuth()) throw new Error('Not authenticated');
|
||||
loadSidebar();
|
||||
|
||||
// ── Auto-classify on input change ────────────────────────
|
||||
const sectorSelect = document.getElementById('sector');
|
||||
const employeeInput = document.getElementById('employee-count');
|
||||
const turnoverInput = document.getElementById('annual-turnover');
|
||||
|
||||
const debouncedClassify = debounce(autoClassify, 500);
|
||||
|
||||
sectorSelect.addEventListener('change', debouncedClassify);
|
||||
employeeInput.addEventListener('input', debouncedClassify);
|
||||
turnoverInput.addEventListener('input', debouncedClassify);
|
||||
|
||||
async function autoClassify() {
|
||||
const sector = sectorSelect.value;
|
||||
const employees = parseInt(employeeInput.value) || 0;
|
||||
const turnover = parseInt(turnoverInput.value) || 0;
|
||||
|
||||
if (!sector || employees <= 0) {
|
||||
resetClassification();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await api.classifyEntity({
|
||||
sector: sector,
|
||||
employee_count: employees,
|
||||
annual_turnover_eur: turnover
|
||||
});
|
||||
|
||||
if (result.success && result.data) {
|
||||
updateClassificationUI(result.data);
|
||||
} else {
|
||||
// Fallback: classificazione locale
|
||||
const localResult = classifyLocally(sector, employees, turnover);
|
||||
updateClassificationUI(localResult);
|
||||
}
|
||||
} catch (e) {
|
||||
// Fallback: classificazione locale
|
||||
const localResult = classifyLocally(sector, employees, turnover);
|
||||
updateClassificationUI(localResult);
|
||||
}
|
||||
}
|
||||
|
||||
function classifyLocally(sector, employees, turnover) {
|
||||
// Settori Allegato I (alta criticita')
|
||||
const annexI = [
|
||||
'energy_electricity', 'energy_district_heating', 'energy_oil', 'energy_gas',
|
||||
'energy_hydrogen', 'transport_air', 'transport_rail', 'transport_water',
|
||||
'transport_road', 'banking', 'financial_markets', 'health', 'drinking_water',
|
||||
'waste_water', 'digital_infrastructure', 'ict_service_management',
|
||||
'public_administration', 'space'
|
||||
];
|
||||
|
||||
// Settori Allegato II
|
||||
const annexII = [
|
||||
'postal_courier', 'waste_management', 'chemicals', 'food',
|
||||
'manufacturing_medical', 'manufacturing_computers', 'manufacturing_electrical',
|
||||
'manufacturing_machinery', 'manufacturing_vehicles', 'manufacturing_transport',
|
||||
'digital_providers', 'research'
|
||||
];
|
||||
|
||||
const isAnnexI = annexI.includes(sector);
|
||||
const isAnnexII = annexII.includes(sector);
|
||||
const isLarge = employees >= 250 || turnover >= 50000000;
|
||||
const isMedium = employees >= 50 || turnover >= 10000000;
|
||||
|
||||
if (isAnnexI && isLarge) {
|
||||
return {
|
||||
classification: 'essential',
|
||||
label: 'Soggetto Essenziale',
|
||||
description: 'La vostra organizzazione rientra tra i soggetti essenziali ai sensi della Direttiva NIS2, in quanto opera in un settore ad alta criticita\' (Allegato I) e supera le soglie dimensionali per la classificazione come grande impresa.'
|
||||
};
|
||||
} else if ((isAnnexI || isAnnexII) && isMedium) {
|
||||
return {
|
||||
classification: 'important',
|
||||
label: 'Soggetto Importante',
|
||||
description: 'La vostra organizzazione rientra tra i soggetti importanti ai sensi della Direttiva NIS2. Siete tenuti a rispettare gli obblighi di sicurezza e di notifica degli incidenti, con un regime di vigilanza ex post.'
|
||||
};
|
||||
} else if (sector === 'other' || (!isAnnexI && !isAnnexII)) {
|
||||
return {
|
||||
classification: 'not_applicable',
|
||||
label: 'Non Applicabile',
|
||||
description: 'In base ai dati forniti, la vostra organizzazione non sembra rientrare nell\'ambito di applicazione della Direttiva NIS2. Consigliamo comunque di verificare con le autorita\' competenti.'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
classification: 'not_applicable',
|
||||
label: 'Sotto le Soglie',
|
||||
description: 'La vostra organizzazione opera in un settore coperto dalla NIS2 ma non raggiunge le soglie dimensionali minime (50 dipendenti o 10M EUR di fatturato). Potreste comunque essere designati dalle autorita\' nazionali.'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function updateClassificationUI(data) {
|
||||
const preview = document.getElementById('classification-preview');
|
||||
const details = document.getElementById('classification-details');
|
||||
const info = document.getElementById('classification-info');
|
||||
|
||||
const classification = data.classification || data.type || 'not_applicable';
|
||||
const label = data.label || classification;
|
||||
const description = data.description || data.explanation || '';
|
||||
|
||||
// Reset classes
|
||||
preview.className = 'classification-preview';
|
||||
|
||||
if (classification === 'essential' || classification === 'essenziale') {
|
||||
preview.classList.add('essential');
|
||||
preview.innerHTML = `
|
||||
<div class="classification-label">Soggetto Essenziale</div>
|
||||
<p class="classification-desc">${escapeHtml(description) || 'Obblighi completi NIS2 - Vigilanza ex ante.'}</p>
|
||||
`;
|
||||
} else if (classification === 'important' || classification === 'importante') {
|
||||
preview.classList.add('important');
|
||||
preview.innerHTML = `
|
||||
<div class="classification-label">Soggetto Importante</div>
|
||||
<p class="classification-desc">${escapeHtml(description) || 'Obblighi NIS2 - Vigilanza ex post.'}</p>
|
||||
`;
|
||||
} else {
|
||||
preview.classList.add('not-applicable');
|
||||
preview.innerHTML = `
|
||||
<div class="classification-label">${escapeHtml(label)}</div>
|
||||
<p class="classification-desc">${escapeHtml(description) || 'Non rientra nell\'ambito NIS2.'}</p>
|
||||
`;
|
||||
}
|
||||
|
||||
if (data.details || data.obligations) {
|
||||
details.style.display = 'block';
|
||||
let detailsHtml = '';
|
||||
if (data.obligations && data.obligations.length > 0) {
|
||||
detailsHtml += '<p><strong>Obblighi principali:</strong></p><ul style="padding-left:20px;">';
|
||||
data.obligations.forEach(o => {
|
||||
detailsHtml += `<li>${escapeHtml(o)}</li>`;
|
||||
});
|
||||
detailsHtml += '</ul>';
|
||||
}
|
||||
if (data.details) {
|
||||
detailsHtml += `<p>${escapeHtml(data.details)}</p>`;
|
||||
}
|
||||
info.innerHTML = detailsHtml;
|
||||
}
|
||||
}
|
||||
|
||||
function resetClassification() {
|
||||
const preview = document.getElementById('classification-preview');
|
||||
preview.className = 'classification-preview not-applicable';
|
||||
preview.innerHTML = `
|
||||
<div class="classification-label">In Attesa</div>
|
||||
<p class="classification-desc">
|
||||
Compila i dati aziendali per ottenere la classificazione automatica
|
||||
secondo i criteri della Direttiva NIS2 (UE) 2022/2555.
|
||||
</p>
|
||||
`;
|
||||
document.getElementById('classification-details').style.display = 'none';
|
||||
}
|
||||
|
||||
// ── Form Submit ──────────────────────────────────────────
|
||||
document.getElementById('org-form').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const companyName = document.getElementById('company-name').value.trim();
|
||||
const vatNumber = document.getElementById('vat-number').value.trim();
|
||||
const sector = sectorSelect.value;
|
||||
const employees = parseInt(employeeInput.value) || 0;
|
||||
const turnover = parseInt(turnoverInput.value) || 0;
|
||||
|
||||
// Validazione
|
||||
if (!companyName) {
|
||||
showNotification('Inserisci la ragione sociale.', 'warning');
|
||||
return;
|
||||
}
|
||||
if (!sector) {
|
||||
showNotification('Seleziona un settore.', 'warning');
|
||||
return;
|
||||
}
|
||||
if (employees <= 0) {
|
||||
showNotification('Inserisci il numero di dipendenti.', 'warning');
|
||||
return;
|
||||
}
|
||||
if (turnover <= 0) {
|
||||
showNotification('Inserisci il fatturato annuo.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const saveBtn = document.getElementById('save-btn');
|
||||
saveBtn.disabled = true;
|
||||
saveBtn.textContent = 'Salvataggio in corso...';
|
||||
|
||||
try {
|
||||
const result = await api.createOrganization({
|
||||
name: companyName,
|
||||
vat_number: vatNumber,
|
||||
sector: sector,
|
||||
employee_count: employees,
|
||||
annual_turnover_eur: turnover
|
||||
});
|
||||
|
||||
if (result.success && result.data) {
|
||||
// Imposta l'organizzazione come attiva
|
||||
api.setOrganization(result.data.id || result.data.organization_id);
|
||||
showNotification('Organizzazione creata con successo!', 'success');
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = 'dashboard.html';
|
||||
}, 1000);
|
||||
} else {
|
||||
showNotification(result.message || 'Errore nella creazione.', 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showNotification('Errore di connessione al server.', 'error');
|
||||
} finally {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = 'Salva e Continua';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version": "1.23.9", "build": "2026-06-18-v1.23.9", "date": "2026-06-18", "changelog": "Ticket #384 - rifinitura help contestuale. Aggiunta alla guida della pagina Policy la sezione 'Matrice RACI sulla policy' (significato di R/A/C/I, regola di prodotto che richiede almeno una R e una A per approvare - non un obbligo normativo, ruoli definiti nell'Organigramma) e la sezione 'Collegamento con Misure e Requisiti' (Procedure e Policy unificate, link bidirezionali tra le due pagine). Completa la coda di polish del punto 6. I testi dinamici del pannello RACI seguono la convenzione italiana della pagina. Nessuna migrazione."}
|
||||
{"version": "1.23.10", "build": "2026-06-19-v1.23.10", "date": "2026-06-19", "changelog": "UI V2 (Bootstrap Italia / AGID) completata su tutte le pagine: migrate architecture.html e workflow.html (CSS Bootstrap Italia + bundle JS + common-bi.js per la sidebar V2 coerente con il resto dell'app) e i documenti integrazioniext.html e mktg-api-doc.html (CSS Bootstrap Italia, design system style.css resta autorevole). Rimossa la pagina morta setup-org.html (sostituita da onboarding.html). Il funnel login/register/onboarding era gia' su Bootstrap Italia. Nessuna modifica di funzionalita', nessuna migrazione DB."}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>Compliance Journey - NIS2 Agile</title>
|
||||
<!-- Bootstrap Italia v2.18.1 self-hostato (regola: MAI CDN), PRIMA di style.css cosi' il design system esistente resta autorevole -->
|
||||
<link rel="stylesheet" href="/vendor/bootstrap-italia/dist/css/bootstrap-italia.min.css">
|
||||
<link rel="stylesheet" href="css/style.css?v=20260618">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
<style>
|
||||
@@ -321,6 +323,8 @@
|
||||
|
||||
<script src="js/api.js?v=20260631"></script>
|
||||
<script src="js/common.js?v=20260631"></script>
|
||||
<script src="/vendor/bootstrap-italia/dist/js/bootstrap-italia.bundle.min.js"></script>
|
||||
<script src="/js/common-bi.js?v=20260631"></script>
|
||||
<script src="js/i18n.js?v=20260631"></script>
|
||||
<script>
|
||||
if (!checkAuth()) throw new Error('Not authenticated');
|
||||
|
||||
Reference in New Issue
Block a user