`;
document.getElementById('pdf-invoice-content').innerHTML = contentHTML;
const pdfContainer = document.getElementById('pdf-container');
const { jsPDF } = window.jspdf;
const button = document.getElementById('downloadPdfBtn');
button.textContent = 'Generating...';
button.disabled = true;
pdfContainer.classList.remove('invisible');
try {
const canvas = await html2canvas(pdfContainer, { scale: 2 });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgProps = pdf.getImageProperties(imgData);
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 0, 0, pdfWidth, imgHeight);
pdf.save(`Invoice_${invoiceNumber}_${client.name}.pdf`);
// Mark entries as invoiced
currentInvoiceData.timeEntries.forEach(e => { const entry = state.entries.find(se => se.id === e.id); if(entry) entry.invoiced = true; });
currentInvoiceData.expenseEntries.forEach(e => { const entry = state.entries.find(se => se.id === e.id); if(entry) entry.invoiced = true; });
renderDashboard();
showToast('Invoice downloaded and entries marked as billed.');
} catch(error) {
console.error("PDF generation error:", error);
showToast('Failed to generate PDF.', false);
} finally {
button.textContent = 'Download Invoice as PDF';
button.disabled = false;
pdfContainer.classList.add('invisible');
document.getElementById('invoice-preview-container').innerHTML = `
Invoice has been processed. Generate a new one.
`; document.getElementById('download-btn-container').style.display = 'none'; currentInvoiceData = null; } } // --- INITIALIZATION --- nextBtn.addEventListener('click', () => changeTab(currentTab + 1)); prevBtn.addEventListener('click', () => changeTab(currentTab - 1)); tabButtons.forEach(button => button.addEventListener('click', () => changeTab(parseInt(button.dataset.tab)))); renderAll(); renderConfigForm(); // Populate config form on load updateTabDisplay(); });