Deliverables:
${getValue('deliverables')}
Pricing:
| Item | Qty | Cost |
${pricingData.map(i => `| ${i.desc} | ${i.qty} | $${(i.qty * i.cost).toFixed(2)} |
`).join('')}
| Total: | $${totalPriceEl.textContent} |
`;
};
// --- PDF Download Logic ---
downloadPdfBtn.addEventListener('click', () => {
if (typeof window.jspdf === 'undefined') { return; }
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'letter' });
const getValue = id => document.getElementById(id).value;
const page = { width: doc.internal.pageSize.getWidth(), margin: 40 };
page.contentWidth = page.width - page.margin * 2;
let y = page.margin;
// Header
doc.setFont('helvetica', 'bold');
doc.setFontSize(24);
doc.text('Business Proposal', page.width / 2, y, { align: 'center' });
y += 40;
// Info Blocks
doc.setFontSize(10);
doc.setFont('helvetica', 'bold');
doc.text('PREPARED FOR:', page.margin, y);
doc.text('PREPARED BY:', page.width / 2, y);
y += 15;
doc.setFont('helvetica', 'normal');
doc.text(getValue('clientCompany'), page.margin, y);
doc.text(getValue('providerName'), page.width / 2, y);
y += 12;
doc.text(getValue('clientName'), page.margin, y);
doc.text(getValue('providerContact'), page.width / 2, y);
y += 12;
doc.text(getValue('clientContact'), page.margin, y);
doc.text(`Date: ${getValue('proposalDate')}`, page.width / 2, y);
y += 50;
// Section Helper
const addSection = (title, content) => {
if (y > doc.internal.pageSize.getHeight() - 100) { doc.addPage(); y = page.margin; }
doc.setFontSize(14);
doc.setFont('helvetica', 'bold');
doc.text(title, page.margin, y);
doc.setLineWidth(1.5);
doc.line(page.margin, y + 3, page.margin + 80, y + 3);
y += 25;
doc.setFontSize(11);
doc.setFont('helvetica', 'normal');
const textLines = doc.splitTextToSize(content, page.contentWidth);
doc.text(textLines, page.margin, y);
y += textLines.length * 12 + 20;
};
addSection('Problem Statement', getValue('problemStatement'));
addSection('Proposed Solution', getValue('proposedSolution'));
addSection('Scope of Work & Deliverables', getValue('deliverables'));
// Pricing Section
if (y > doc.internal.pageSize.getHeight() - 150) { doc.addPage(); y = page.margin; }
doc.setFontSize(14); doc.setFont('helvetica', 'bold');
doc.text('Investment', page.margin, y);
doc.setLineWidth(1.5); doc.line(page.margin, y + 3, page.margin + 80, y + 3);
y += 25;
// Pricing Table Header
doc.setFontSize(10); doc.setFont('helvetica', 'bold');
doc.text('DESCRIPTION', page.margin, y);
doc.text('QTY', page.margin + 300, y);
doc.text('UNIT COST', page.margin + 360, y);
doc.text('TOTAL', page.width - page.margin, y, { align: 'right' });
y += 15;
// Pricing Table Rows
doc.setFontSize(10); doc.setFont('helvetica', 'normal');
document.querySelectorAll('#pricingItems > div').forEach(item => {
const desc = item.querySelector('.price-desc').value;
const qty = parseFloat(item.querySelector('.price-qty').value) || 0;
const cost = parseFloat(item.querySelector('.price-cost').value) || 0;
doc.text(desc, page.margin, y);
doc.text(qty.toString(), page.margin + 300, y);
doc.text(`$${cost.toFixed(2)}`, page.margin + 360, y);
doc.text(`$${(qty * cost).toFixed(2)}`, page.width - page.margin, y, { align: 'right' });
y += 15;
});
// Total
doc.setLineWidth(1); doc.line(page.margin + 350, y, page.width - page.margin, y);
y += 15;
doc.setFontSize(12); doc.setFont('helvetica', 'bold');
doc.text('Total Investment:', page.margin + 350, y);
doc.text(`$${totalPriceEl.textContent}`, page.width - page.margin, y, { align: 'right' });
doc.save(`Proposal-for-${getValue('clientCompany') || 'Client'}.pdf`);
});
// --- Initial Setup ---
document.getElementById('proposalDate').valueAsDate = new Date();
addPricingItem();
switchTab('client');
});