' + body;
}
function weekPop(m) {
var items = [];
for (var i = 0; i < 7; i++) { var d = addD(m, i); evOf(d).forEach(function (e) { items.push({ d: d, e: e }); }); }
var body = items.length
? items.slice(0, 6).map(function (o) { return '
';
}).join('');
document.getElementById('act-scroll').innerHTML = html;
} catch (e) {
setError('act-scroll');
}
}
// ── 4) Anagrafica aziendale — dati reali da organizations/current ───────
var ENTITY_LABEL = { essential: 'Soggetto essenziale', important: 'Soggetto importante', not_applicable: 'Fuori ambito', voluntary: 'Adesione volontaria' };
function initials(name) {
return String(name || '').trim().split(/\s+/).map(function (w) { return w[0]; }).filter(Boolean).slice(0, 2).join('').toUpperCase() || '—';
}
async function loadAnag() {
var card = document.getElementById('anag-card'); if (!card) return;
try {
var r = await api.getCurrentOrg();
if (!r || !r.success || !r.data) { setEmpty('anag-card', 'Nessuna organizzazione', 'Completa l’onboarding per visualizzare l’anagrafica.', 'building-2'); return; }
var o = r.data;
var nis = ENTITY_LABEL[o.entity_type] || (o.entity_type ? esc(o.entity_type) : 'Da classificare');
var fields = [
['Settore', o.sector || o.nis2_sector || '—'],
['Partita IVA', o.vat_number || '—'],
['Sede legale', [o.city, o.country].filter(Boolean).join(', ') || o.legal_address || '—'],
['Dipendenti', (o.employee_count != null && o.employee_count !== '') ? o.employee_count : '—'],
['Codice fiscale', o.fiscal_code || '—'],
['Classificazione NIS2', nis]
];
var grid = fields.map(function (f) { return '
' + esc(f[0]) + '' + esc(f[1]) + '
'; }).join('');
card.innerHTML =
'
' + esc(initials(o.name)) + '
' +
'
' + esc(o.name || 'Organizzazione') + '
' +
'' + nis + '
' +
'
' + grid + '
';
} catch (e) {
setError('anag-card');
}
}
// ── 5) Documenti istituzionali — /api/institutional-docs (ticket #499) ──
// Le 5 voci standard sono SEMPRE presenti (Codice Etico, Mission, Vision,
// Statuto, Piano Sanzionatorio); ogni documento richiede una descrizione.
function canEditDocs() {
var r = (localStorage.getItem('nis2_user_role') || '').toLowerCase();
return r === 'org_admin' || r === 'compliance_manager' || r === 'super_admin';
}
function docRow(item, stdLabel) {
var filled = item && item.description && String(item.description).trim() !== '';
var title = esc((item && item.title) || stdLabel || 'Documento');
var editBtn = canEditDocs()
? '' : '';
var delBtn = (canEditDocs() && item && item.id && Number(item.is_standard) !== 1)
? '' : '';
var body = filled
? '' + esc(item.description) + ''
: 'Nessuna descrizione — ' + (canEditDocs() ? 'compila la voce.' : 'da compilare.') + '';
var fileLink = (item && item.file_url)
? ' documento' : '';
return '
' +
'
' + title + fileLink + '' + body + '
' +
'
' + editBtn + delBtn + '
';
}
function stdKeyOf(label, standards) {
for (var i = 0; i < standards.length; i++) if (standards[i].label === label) return standards[i].key;
return null;
}
// Le 5 voci standard DEVONO essere sempre presenti anche se l'API non risponde.
var STD_FALLBACK = [
{ key: 'codice_etico', label: 'Codice Etico' },
{ key: 'mission', label: 'Mission' },
{ key: 'vision', label: 'Vision' },
{ key: 'statuto', label: 'Statuto' },
{ key: 'piano_sanzionatorio', label: 'Piano Sanzionatorio' }
];
function renderDocsCard(docs, standards) {
var card = document.getElementById('doc-card'); if (!card) return;
standards = (standards && standards.length) ? standards : STD_FALLBACK;
docs = docs || [];
var byKey = {}; var customs = [];
docs.forEach(function (d) { if (d.doc_key) byKey[d.doc_key] = d; else customs.push(d); });
var html = '';
standards.forEach(function (s) {
var item = byKey[s.key] || { doc_key: s.key, title: s.label, is_standard: 1 };
html += docRow(item, s.label);
});
customs.forEach(function (d) { html += docRow(d, null); });
if (canEditDocs()) {
html += '';
}
card.innerHTML = '
' + html + '
';
refreshIcons();
wireDocEvents(card, standards);
}
function loadDocs() {
var card = document.getElementById('doc-card'); if (!card) return;
setLoading('doc-card');
api.request('GET', '/institutional-docs/list').then(function (res) {
var data = (res && res.data) || res || {};
renderDocsCard(data.docs || [], data.standards);
}).catch(function () {
// Anche in caso di errore mostriamo comunque le 5 voci standard.
renderDocsCard([], STD_FALLBACK);
});
}
function docModal(opts, standards) {
var isStd = !!opts.doc_key;
var titleField = isStd
? ''
: '';
var body =
'
' + titleField + '
' +
'
' +
'
' +
'
' +
'
';
var footer = '' +
'';
showModal(opts.id ? 'Modifica documento' : (isStd ? 'Compila: ' + (opts.title || '') : 'Aggiungi documento'), body, { footer: footer });
var saveBtn = document.getElementById('doc-f-save');
saveBtn.addEventListener('click', function () {
var title = document.getElementById('doc-f-title').value.trim();
var desc = document.getElementById('doc-f-desc').value.trim();
var file = document.getElementById('doc-f-file').value.trim();
if (!title) { showNotification('Il titolo è obbligatorio', 'error'); return; }
if (!desc) { showNotification('La descrizione è obbligatoria', 'error'); return; }
saveBtn.disabled = true;
api.request('POST', '/institutional-docs/save', {
id: opts.id || undefined, doc_key: opts.doc_key || undefined,
title: title, description: desc, file_url: file || undefined
}).then(function () {
closeModal(); showNotification('Documento salvato', 'success'); loadDocs();
}).catch(function (e) {
saveBtn.disabled = false;
showNotification((e && e.message) || 'Salvataggio non riuscito', 'error');
});
});
}
function wireDocEvents(card, standards) {
card.querySelectorAll('.doc-edit').forEach(function (btn) {
btn.addEventListener('click', function () {
var el = btn.closest('.doc-item');
docModal({
id: el.getAttribute('data-id') || null,
doc_key: el.getAttribute('data-key') || null,
title: el.querySelector('b') ? el.querySelector('b').childNodes[0].textContent.trim() : '',
description: el.querySelector('.doc-empty-desc') ? '' : (el.querySelector('.doc-desc') ? el.querySelector('.doc-desc').textContent : ''),
file_url: el.querySelector('.doc-file') ? el.querySelector('.doc-file').getAttribute('href') : ''
}, standards);
});
});
card.querySelectorAll('.doc-del').forEach(function (btn) {
btn.addEventListener('click', function () {
var el = btn.closest('.doc-item'); var id = el.getAttribute('data-id');
if (!id || !confirm('Eliminare questa voce?')) return;
api.request('DELETE', '/institutional-docs/' + id).then(function () {
showNotification('Documento eliminato', 'success'); loadDocs();
}).catch(function (e) { showNotification((e && e.message) || 'Eliminazione non riuscita', 'error'); });
});
});
var addBtn = card.querySelector('.doc-add');
if (addBtn) addBtn.addEventListener('click', function () { docModal({}, standards); });
}
// ── Init pubblico (chiamato dall'init pagina dopo checkAuth/loadSidebar) ─
function initDashboard() {
wireCalControls();
renderDaily(); renderWeekly(); // render iniziale (eventi reali arriveranno e ri-renderizzano)
loadStats();
loadDeadlines();
loadActivities();
loadAnag();
loadDocs();
}
window.initDashboard = initDashboard;
})();