`;
});
resultsDisplay.innerHTML = html;
}
function renderConfiguration() {
criteriaList.innerHTML = state.criteria.map(c => `
${c.name} (Weight: ${c.weight})
`).join('');
}
// SECTION: Event Handlers & Logic
function handleTabClick(tabName) { state.activeTab = tabName; render(); }
function handleNavClick(dir) { const i = TABS.indexOf(state.activeTab); const newI = i + dir; if (newI >= 0 && newI < TABS.length) { state.activeTab = TABS[newI]; render(); } }
function handleAddCriterion(e) { e.preventDefault(); const name = criterionNameInput.value.trim(); const weight = parseInt(criterionWeightInput.value); if(name){ state.criteria.push({id: Date.now(), name, weight}); addCriterionForm.reset(); saveState(); render(); } }
function handleDelete(type, id) { if(confirm(`Delete this ${type}?`)){ state[type+'s'] = state[type+'s'].filter(item => item.id !== id); saveState(); render(); } }
function switchStep(step) {
[step1, step2, step3].forEach(s => s.classList.add('hidden'));
if (step === 1) step1.classList.remove('hidden');
if (step === 2) step2.classList.remove('hidden');
if (step === 3) step3.classList.remove('hidden');
}
function handleDefineDecision(e) {
e.preventDefault();
state.currentDecision = {
title: decisionTitleInput.value,
options: decisionOptionsInput.value.split(',').map(s => s.trim()).filter(Boolean),
};
if (state.currentDecision.options.length < 2) {
alert('Please provide at least two comma-separated options.');
return;
}
renderScoringMatrix();
switchStep(2);
}
function handleCalculate() {
const scores = {}; // { critId: [opt1_score, opt2_score], ... }
document.querySelectorAll('.score-input').forEach(input => {
const critId = parseInt(input.dataset.critId);
const optIndex = parseInt(input.dataset.optIndex);
if (!scores[critId]) scores[critId] = [];
scores[critId][optIndex] = parseInt(input.value) || 0;
});
let totalWeight = state.criteria.reduce((sum, c) => sum + c.weight, 0);
const finalScores = state.currentDecision.options.map((option, optIndex) => {
let totalScore = 0;
state.criteria.forEach(crit => {
totalScore += (scores[crit.id]?.[optIndex] || 0) * crit.weight;
});
return { option, totalScore, weightedScore: totalScore / totalWeight };
});
const winner = finalScores.sort((a, b) => b.totalScore - a.totalScore)[0];
renderResults({ winner: winner.option, scores: finalScores });
switchStep(3);
}
function handleSaveDecision() {
const decisionToSave = {
id: Date.now(),
...state.currentDecision,
date: new Date()
};
state.completedDecisions.push(decisionToSave);
saveState();
alert('Decision saved!');
defineDecisionForm.reset();
state.activeTab = 'dashboard';
render();
switchStep(1);
}
function generatePDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const decision = state.currentDecision;
doc.setFontSize(22); doc.text('Decision Analysis Report', 105, 20, { align: 'center' });
doc.setFontSize(16); doc.text(decision.title, 105, 30, { align: 'center' });
doc.setFontSize(14); doc.text('Recommendation', 14, 45);
doc.setFontSize(11); doc.text(`Based on the analysis, the recommended option is: ${decision.result.winner}`, 14, 52);
const tableBody = decision.result.scores.map(s => [s.option, s.weightedScore.toFixed(2)]);
doc.autoTable({
head: [['Option', 'Final Weighted Score']], body: tableBody, startY: 60, theme: 'grid',
headStyles: { fillColor: [37, 99, 235] },
});
doc.save(`Decision_Report_${decision.title.replace(/\s/g, '_')}.pdf`);
}
// SECTION: Event Listeners
Object.keys(tabButtons).forEach(id => tabButtons[id]?.addEventListener('click', () => handleTabClick(id)));
prevTabBtn?.addEventListener('click', () => handleNavClick(-1));
nextTabBtn?.addEventListener('click', () => handleNavClick(1));
defineDecisionForm?.addEventListener('submit', handleDefineDecision);
backToStep1Btn?.addEventListener('click', () => switchStep(1));
calculateDecisionBtn?.addEventListener('click', handleCalculate);
backToStep2Btn?.addEventListener('click', () => switchStep(2));
saveDecisionBtn?.addEventListener('click', handleSaveDecision);
downloadDecisionPdfBtn?.addEventListener('click', generatePDF);
addCriterionForm?.addEventListener('submit', handleAddCriterion);
criteriaList?.addEventListener('click', e => { if(e.target.classList.contains('delete-criterion-btn')) handleDelete('criteria', parseInt(e.target.dataset.id)); });
// SECTION: Initial Load
loadState();
render();
});
