1. Survey Baseline and Target Goals (Scale 1-5)
| Domain |
Baseline Score |
Target Goal |
Target Lift |
`;
surveyDomains.forEach(domain => {
const lift = (domain.target - domain.baseline).toFixed(1);
const liftColor = lift >= 0.5 ? 'var(--success-color)' : 'var(--danger-color)';
html += `
| ${domain.name} |
${domain.baseline.toFixed(1)} |
${domain.target.toFixed(1)} |
+${lift} |
`;
});
html += `
`;
reviewArea.innerHTML = html;
// Manually build the action table for the review area
const actionTableContainer = document.getElementById('review-action-table-container');
let actionTableHTML = `
| Domain |
Action |
Responsible |
Deadline |
Status |
`;
actionPlan.forEach(action => {
let statusColor = 'var(--secondary-color)';
if (action.status === 'Complete') statusColor = 'var(--success-color)';
if (action.status === 'Delayed') statusColor = 'var(--danger-color)';
if (action.status === 'In Progress') statusColor = 'var(--primary-color)';
actionTableHTML += `
| ${action.domain} |
${action.description} |
${action.responsible} |
${action.deadline} |
${action.status} |
`;
});
actionTableHTML += `
`;
actionTableContainer.innerHTML = actionTableHTML;
}
/**
* PDF Generation Function (Ensuring professional formatting)
*/
function downloadPDF() {
const data = getFormData();
if (actionPlan.length === 0) return;
const { jsPDF } = window.jspdf;
const doc = new jsPDF('p', 'pt', 'a4');
let currentY = 40;
const margin = 40;
const pageWidth = doc.internal.pageSize.width;
const maxWidth = pageWidth - (margin * 2);
const checkPageBreak = (spaceNeeded) => {
if (currentY + spaceNeeded > doc.internal.pageSize.height - margin) {
doc.addPage();
currentY = margin;
}
};
const addSectionHeader = (title) => {
checkPageBreak(30);
doc.setFontSize(16);
doc.setFont('Helvetica', 'bold');
doc.setTextColor(44, 62, 80); /* Secondary color */
doc.text(title, margin, currentY);
currentY += 10;
doc.setLineWidth(0.5);
doc.setDrawColor(200);
doc.line(margin, currentY, pageWidth - margin, currentY);
currentY += 15;
doc.setTextColor(0);
};
// --- PDF Content ---
// Title Block
doc.setFontSize(22);
doc.setFont('Helvetica', 'bold');
doc.setTextColor(52, 152, 219);
doc.text("School Climate Survey Action Plan", pageWidth / 2, currentY, { align: 'center' });
currentY += 15;
doc.setFontSize(12);
doc.setFont('Helvetica', 'normal');
doc.setTextColor(108, 117, 125);
doc.text(`${data.school_name} | Period: ${data.plan_period}`, pageWidth / 2, currentY, { align: 'center' });
currentY += 30;
doc.setTextColor(0);
// 1. Goal Setting Table
addSectionHeader("1. Survey Baseline and Target Goals (Scale 1-5)");
const goalsHead = [["Domain", "Baseline Score", "Target Goal", "Target Lift", "Focus Area"]];
const goalsBody = surveyDomains.map(domain => {
const lift = (domain.target - domain.baseline).toFixed(1);
return [
domain.name,
domain.baseline.toFixed(1),
domain.target.toFixed(1),
`+${lift}`,
domain.notes
];
});
doc.autoTable({
startY: currentY,
head: goalsHead,
body: goalsBody,
theme: 'grid',
headStyles: { fillColor: [230, 230, 230], textColor: [44, 62, 80], fontStyle: 'bold' },
styles: { fontSize: 10, cellPadding: 4, font: 'Helvetica' },
columnStyles: { 0: { fontStyle: 'bold' }, 3: { fontStyle: 'bold', halign: 'center' } }
});
currentY = doc.autoTable.previous.finalY + 20;
// 2. Action Plan Table
addSectionHeader("2. Detailed Action Plan");
const actionHead = [["Domain", "Action Description", "Responsible", "Deadline", "Status"]];
const actionBody = actionPlan.map(action => [
action.domain,
action.description,
action.responsible,
action.deadline,
action.status
]);
doc.autoTable({
startY: currentY,
head: actionHead,
body: actionBody,
theme: 'grid',
headStyles: { fillColor: [52, 152, 219], textColor: [255, 255, 255] },
styles: { fontSize: 10, cellPadding: 5, font: 'Helvetica' },
columnStyles: {
1: { cellWidth: 150 }, // Make action description wider
4: { fontStyle: 'bold' } // Highlight status
},
didDrawCell: (data) => {
if (data.column.index === 4 && data.cell.section === 'body') {
let color;
switch (data.cell.raw) {
case 'Complete': color = [46, 204, 113]; break;
case 'Delayed': color = [231, 76, 60]; break;
case 'In Progress': color = [52, 152, 219]; break;
default: color = [100, 100, 100];
}
doc.setTextColor(color[0], color[1], color[2]);
}
}
});
currentY = doc.autoTable.previous.finalY + 10;
doc.save('school_climate_action_plan.pdf');
}
function getFormData() {
// Collect Project Details
const data = {};
data.school_name = schoolNameInput.value;
data.plan_period = planPeriodInput.value;
return data;
}
// --- Tab Navigation ---
function switchTab(tabIndex) {
tabs.forEach((tab, index) => {
tab.classList.toggle('active', index === tabIndex);
contents[index].classList.toggle('active', index === tabIndex);
});
currentTab = tabIndex;
updateNavButtons();
if (tabIndex === 2) { // Review tab
generateActionPlan();
}
}
function updateNavButtons() {
prevBtn.disabled = currentTab === 0;
nextBtn.disabled = currentTab === tabs.length - 1;
}
tabs.forEach((tab, index) => {
tab.addEventListener('click', () => switchTab(index));
});
nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); });
prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); });
// --- Event Listeners ---
document.getElementById('action-add-update-btn').addEventListener('click', (e) => { e.preventDefault(); actionForm.dispatchEvent(new Event('submit')); });
document.getElementById('pdf-download-btn').addEventListener('click', downloadPDF);
document.querySelector('.school-tab-button[data-tab="review"]').addEventListener('click', generateActionPlan);
// --- Initial Setup ---
setInitialDate();
renderGoalSetting();
populateActionDomainSelect();
renderActionTable();
updateNavButtons();
});