`;
};
const renderDataTable = () => {
dataTableBody.innerHTML = '';
const sortedResponses = [...state.responses].sort((a, b) => b.id - a.id);
sortedResponses.forEach(r => {
const row = `
${r.department}
${r.satisfaction}
${r.engagement}
${r.enps}
`;
dataTableBody.innerHTML += row;
});
};
const renderCharts = () => {
// Satisfaction by Department
const satisfactionByDept = state.responses.reduce((acc, r) => {
if (!acc[r.department]) acc[r.department] = { total: 0, count: 0 };
acc[r.department].total += r.satisfaction;
acc[r.department].count++;
return acc;
}, {});
const deptLabels = Object.keys(satisfactionByDept);
const deptData = deptLabels.map(label => satisfactionByDept[label].total / satisfactionByDept[label].count);
if (departmentChart) departmentChart.destroy();
departmentChart = new Chart(departmentCanvas.getContext('2d'), {
type: 'bar',
data: {
labels: deptLabels,
datasets: [{
label: 'Average Satisfaction',
data: deptData,
backgroundColor: 'rgba(99, 102, 241, 0.7)',
}]
},
options: {
responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true, max: 10 } }
}
});
// eNPS Chart
const promoters = state.responses.filter(r => r.enps >= 9).length;
const passives = state.responses.filter(r => r.enps >= 7 && r.enps <= 8).length;
const detractors = state.responses.filter(r => r.enps <= 6).length;
if (enpsChart) enpsChart.destroy();
enpsChart = new Chart(enpsCanvas.getContext('2d'), {
type: 'doughnut',
data: {
labels: ['Promoters', 'Passives', 'Detractors'],
datasets: [{ data: [promoters, passives, detractors], backgroundColor: ['#22c55e', '#f59e0b', '#ef4444'] }]
},
options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'top' } } }
});
};
const renderConfigRows = () => {
configRowsContainer.innerHTML = '';
const sortedResponses = [...state.responses].sort((a,b) => b.id - a.id);
sortedResponses.forEach(r => {
configRowsContainer.innerHTML += `
`.replaceAll('class="config-input"', 'class="config-input w-full border-gray-300 rounded-md shadow-sm"');
});
addConfigEventListeners();
};
// --- EVENT HANDLERS ---
const handleConfigChange = (e) => {
const id = parseInt(e.target.dataset.id);
const field = e.target.dataset.field;
const value = (e.target.type === 'number') ? parseFloat(e.target.value) || 0 : e.target.value;
const response = state.responses.find(r => r.id === id);
if (response) response[field] = value;
renderAll();
};
const handleAddResponse = () => {
const newId = state.responses.length > 0 ? Math.max(...state.responses.map(r => r.id)) + 1 : 1;
state.responses.push({ id: newId, department: "New Dept", satisfaction: 5, engagement: 5, enps: 5 });
renderAll();
};
const handleRemoveResponse = (e) => {
const id = parseInt(e.target.dataset.id);
state.responses = state.responses.filter(r => r.id !== id);
renderAll();
};
const addConfigEventListeners = () => {
document.querySelectorAll('.config-input').forEach(input => input.addEventListener('change', handleConfigChange));
document.querySelectorAll('.remove-btn').forEach(button => button.addEventListener('click', handleRemoveResponse));
};
const handleDownloadPdf = () => {
const { jsPDF } = window.jspdf;
const pdfContent = document.getElementById('pdf-content');
document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'hidden');
Chart.defaults.animation = false;
html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(canvas => {
document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'visible');
Chart.defaults.animation = true;
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgWidth = pdfWidth - 20;
const imgHeight = canvas.height * imgWidth / canvas.width;
pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight);
pdf.save('Organizational-Culture-Dashboard.pdf');
});
};
// --- TABBING LOGIC ---
let currentTabIndex = 0;
const updateTabButtons = () => {
prevTabBtn.disabled = currentTabIndex === 0;
nextTabBtn.disabled = currentTabIndex === tabContents.length - 1;
};
const switchTab = (index) => {
tabButtons.forEach(btn => btn.classList.remove('active'));
tabContents.forEach(content => content.classList.remove('active'));
tabButtons[index].classList.add('active');
tabContents[index].classList.add('active');
currentTabIndex = index;
updateTabButtons();
};
tabButtons.forEach((button, index) => button.addEventListener('click', () => switchTab(index)));
prevTabBtn.addEventListener('click', () => { if (currentTabIndex > 0) switchTab(currentTabIndex - 1); });
nextTabBtn.addEventListener('click', () => { if (currentTabIndex < tabContents.length - 1) switchTab(currentTabIndex + 1); });
// --- INITIALIZATION ---
if (kpiContainer && addResponseBtn && downloadPdfBtn) {
addResponseBtn.addEventListener('click', handleAddResponse);
downloadPdfBtn.addEventListener('click', handleDownloadPdf);
renderAll();
updateTabButtons();
} else {
console.error("Essential dashboard elements could not be found.");
}
});
