Project Manager: ${reportData.projectManager || 'N/A'}
Report Date: ${reportData.reportDate || 'N/A'}
Overall Status: ${reportData.overallStatus}
Executive Summary
${reportData.summary || 'No summary provided.'}
`;
if (reportData.accomplishments.length > 0) {
previewHTML += `
Key Accomplishments
`;
reportData.accomplishments.forEach(item => previewHTML += `- ${item}
`);
previewHTML += `
`;
}
if (reportData.milestones.length > 0) {
previewHTML += `
Upcoming Milestones
`;
reportData.milestones.forEach(item => previewHTML += `- ${item}
`);
previewHTML += `
`;
}
if (reportData.risks.length > 0) {
previewHTML += `
Potential Risks
`;
reportData.risks.forEach(item => previewHTML += `- ${item}
`);
previewHTML += `
`;
}
if (reportData.issues.length > 0) {
previewHTML += `
Current Issues
`;
reportData.issues.forEach(item => previewHTML += `- ${item}
`);
previewHTML += `
`;
}
previewContent.innerHTML = previewHTML;
}
// --- PDF Generation ---
function downloadPDF() {
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
alert('Error: jsPDF library not loaded.'); return;
}
if (typeof window.jspdf.jsPDF.autoTable === 'undefined') {
alert('Error: jsPDF-AutoTable library not loaded.'); return;
}
updateReportData(); // Ensure latest data
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const margin = 40;
const pageWidth = doc.internal.pageSize.getWidth();
let currentY = margin;
// --- Header ---
doc.setFontSize(18);
doc.setFont('helvetica', 'bold');
doc.text("Project Status Report", pageWidth / 2, currentY, { align: 'center' });
currentY += 25;
// --- Project Details Table ---
doc.setFontSize(10);
doc.setFont('helvetica', 'normal');
const projectDetailsData = [
["Project Name:", reportData.projectName || 'N/A'],
["Project Manager:", reportData.projectManager || 'N/A'],
["Report Date:", reportData.reportDate || 'N/A'],
["Overall Status:", reportData.overallStatus],
];
doc.autoTable({
startY: currentY,
body: projectDetailsData,
theme: 'plain',
styles: { cellPadding: 2, fontSize: 10 },
columnStyles: { 0: { fontStyle: 'bold' } }
});
currentY = doc.autoTable.previous.finalY + 15;
// --- Summary ---
doc.setFontSize(12);
doc.setFont('helvetica', 'bold');
doc.text("Executive Summary", margin, currentY);
currentY += 15;
doc.setFontSize(10);
doc.setFont('helvetica', 'normal');
const summaryLines = doc.splitTextToSize(reportData.summary || 'N/A', pageWidth - margin * 2);
doc.text(summaryLines, margin, currentY);
currentY += summaryLines.length * 12 + 15; // Approx line height
// --- Helper for List Sections ---
function addListSection(title, list) {
if (list.length > 0) {
// Check for page break
const estimatedHeight = 20 + list.length * 15;
if (currentY + estimatedHeight > doc.internal.pageSize.getHeight() - margin) {
doc.addPage();
currentY = margin;
}
doc.setFontSize(12);
doc.setFont('helvetica', 'bold');
doc.text(title, margin, currentY);
currentY += 15;
doc.setFontSize(10);
doc.setFont('helvetica', 'normal');
list.forEach(item => {
doc.text(`• ${item}`, margin + 10, currentY, { maxWidth: pageWidth - margin * 2 - 10 });
currentY += 15; // Adjust spacing as needed
});
currentY += 10; // Space after section
}
}
// --- Sections ---
addListSection("Key Accomplishments", reportData.accomplishments);
addListSection("Upcoming Milestones", reportData.milestones);
addListSection("Potential Risks", reportData.risks);
addListSection("Current Issues", reportData.issues);
doc.save(`${reportData.projectName || 'project'}-status-report.pdf`);
}
// --- Event Listeners ---
addAccomplishmentBtn.addEventListener('click', () => addItem('accomplishments', accomplishmentInput, accomplishmentsList));
addMilestoneBtn.addEventListener('click', () => addItem('milestones', milestoneInput, milestonesList));
addRiskBtn.addEventListener('click', () => addItem('risks', riskInput, risksList));
addIssueBtn.addEventListener('click', () => addItem('issues', issueInput, issuesList));
// Add item on Enter press
accomplishmentInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); addItem('accomplishments', accomplishmentInput, accomplishmentsList); }});
milestoneInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); addItem('milestones', milestoneInput, milestonesList); }});
riskInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); addItem('risks', riskInput, risksList); }});
issueInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { e.preventDefault(); addItem('issues', issueInput, issuesList); }});
pdfBtn.addEventListener('click', downloadPDF);
// --- Initial Load ---
// Set default report date to today
const today = new Date().toISOString().split('T')[0];
reportDateInput.value = today;
// Initial render of empty lists
renderList('accomplishments', accomplishmentsList);
renderList('milestones', milestonesList);
renderList('risks', risksList);
renderList('issues', issuesList);
psrgShowTab(0); // Show first tab initially
});