Project Charter Document Builder

Project Charter Document Builder

1. Project Overview
2. Business Case
3. Project Objectives
4. Project Scope
5. Key Stakeholders
6. Key Milestones & Timeline
7. Budget Summary
8. Risks & Assumptions

____________________________________________
${data['charter-pm'] || 'Project Manager'}

____________________________________________
${data['charter-sponsor'] || 'Project Sponsor'}

`; } function downloadPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const data = getFormData(); const pageHeight = doc.internal.pageSize.height; const pageWidth = doc.internal.pageSize.width; const margin = 20; const maxWidth = pageWidth - (margin * 2); let currentY = margin; const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > pageHeight - margin) { doc.addPage(); currentY = margin; } }; const addSection = (title, text, isSubSection = false) => { checkPageBreak(isSubSection ? 8 : 16); // Space for title doc.setFontSize(isSubSection ? 12 : 14); doc.setFont(undefined, 'bold'); doc.text(title, margin + (isSubSection ? 5 : 0), currentY); currentY += isSubSection ? 6 : 8; if (!isSubSection) { doc.setLineWidth(0.5); doc.line(margin, currentY, maxWidth + margin, currentY); currentY += 8; } doc.setFontSize(11); doc.setFont(undefined, 'normal'); const lines = doc.splitTextToSize(text || 'Not provided.', maxWidth - (isSubSection ? 5 : 0)); checkPageBreak(lines.length * 5 + 10); // Space for text + padding doc.text(lines, margin + (isSubSection ? 5 : 0), currentY); currentY += (lines.length * 5) + (isSubSection ? 5 : 10); // Add padding after section }; // --- PDF Content --- doc.setFontSize(20); doc.setFont(undefined, 'bold'); doc.text("Project Charter", pageWidth / 2, currentY, { align: 'center' }); currentY += 10; doc.setFontSize(16); doc.setTextColor(100); doc.text(data['charter-title'], pageWidth / 2, currentY, { align: 'center' }); currentY += 15; doc.setTextColor(0); addSection("Project Overview", `Project Manager: ${data['charter-pm']}\nProject Sponsor: ${data['charter-sponsor']}\nDate Prepared: ${data['charter-date']}`); addSection("Business Case", data['charter-business-case']); addSection("Project Objectives", data['charter-objectives']); // Scope Section checkPageBreak(20); doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.text("Project Scope", margin, currentY); currentY += 8; doc.setLineWidth(0.5); doc.line(margin, currentY, maxWidth + margin, currentY); currentY += 8; addSection("In-Scope", data['charter-scope-in'], true); addSection("Out-of-Scope", data['charter-scope-out'], true); currentY += 5; // Extra padding after the section addSection("Key Stakeholders", data['charter-stakeholders']); addSection("Key Milestones & Timeline", data['charter-milestones']); addSection("Budget Summary", data['charter-budget']); // Risks & Assumptions Section checkPageBreak(20); doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.text("Risks & Assumptions", margin, currentY); currentY += 8; doc.setLineWidth(0.5); doc.line(margin, currentY, maxWidth + margin, currentY); currentY += 8; addSection("Initial High-Level Risks", data['charter-risks'], true); addSection("Project Assumptions", data['charter-assumptions'], true); currentY += 5; // Approvals addSection("Approvals", ""); checkPageBreak(40); doc.text("__________________________________", margin, currentY + 15); doc.text(data['charter-pm'] || 'Project Manager', margin, currentY + 22); doc.text("__________________________________", margin + 100, currentY + 15); doc.text(data['charter-sponsor'] || 'Project Sponsor', margin + 100, currentY + 22); doc.save('project-charter.pdf'); } // --- 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(); } 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 --- generateBtn.addEventListener('click', () => { // IV.D.1: This is type="button" renderReviewSheet(); switchTab(1); // Switch to review tab }); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- Initial Setup --- setInitialDate(); updateNavButtons(); // Pre-fill review sheet with default data for first load renderReviewSheet(); });
Scroll to Top