Private Debt Portfolio Management Tool
Add New Debt Instrument
Your Debt Instruments
| Loan Name | Principal | Interest Rate | Term (M) | Orig. Date | Frequency | Actions |
|---|
Portfolio Summary
Upcoming Payments Overview
| Loan Name | Next Payment Date | Payment Amount | Remaining Principal |
|---|
Amortization Schedule
| Payment # | Payment Date | Starting Balance ($) | Payment ($) | Interest ($) | Principal ($) | Ending Balance ($) |
|---|
No upcoming payments found.
'; } else { upcomingPayments.sort((a, b) => a.nextPaymentDate - b.nextPaymentDate); upcomingPaymentsHtml += `| Loan Name | Next Payment Date | Payment Amount | Remaining Principal |
|---|---|---|---|
| ${payment.loanName} | ${formatDate(payment.nextPaymentDate)} | ${formatCurrency(payment.paymentAmount)} | ${formatCurrency(payment.remainingPrincipal)} |
No upcoming payments data.
`; } // 4. Amortization Schedule (if one is selected/displayed) const selectedAmortizationLoanId = amortizationLoanSelect.value; if (selectedAmortizationLoanId) { const selectedDebt = portfolioData.find(debt => debt.id === parseInt(selectedAmortizationLoanId)); if (selectedDebt) { pdfHtml += `Amortization Schedule for: ${selectedDebt.loanName}
`; const schedule = calculateAmortization(selectedDebt); if (schedule.length > 0) { pdfHtml += `| Payment # | Payment Date | Starting Balance ($) | Payment ($) | Interest ($) | Principal ($) | Ending Balance ($) |
|---|---|---|---|---|---|---|
| ${payment.paymentNumber} | ${formatDate(payment.paymentDate)} | ${formatCurrency(payment.startingBalance)} | ${formatCurrency(payment.paymentAmount)} | ${formatCurrency(payment.interestPayment)} | ${formatCurrency(payment.principalPayment)} | ${formatCurrency(payment.endingBalance)} |
No amortization schedule available for this loan.
`; } } } pdfContentContainer.innerHTML = pdfHtml; // Temporarily make the container visible (but off-screen) for html2canvas pdfContentContainer.style.display = 'block'; // Use html2canvas to render the content container into a canvas image const canvas = await html2canvas(pdfContentContainer, { scale: 2, // Increase scale for better resolution logging: false, // Disable logging useCORS: true // Allow cross-origin images if any (though none expected here) }); // Hide the container again immediately after rendering to canvas pdfContentContainer.style.display = 'none'; // Get the image data from the canvas const imgData = canvas.toDataURL('image/png'); // Initialize jsPDF const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); // 'p' for portrait, 'mm' for millimeters, 'a4' for A4 size const imgWidth = 210; // A4 width in mm const pageHeight = 297; // A4 height in mm const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; // Add the image to the PDF doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; // Handle multiple pages if content is too long while (heightLeft >= 0) { position = heightLeft - imgHeight; doc.addPage(); doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; } doc.save('Private_Debt_Portfolio_Report.pdf'); // Save the PDF // Clean up: hide the content container again (redundant if already hidden above, but safe) pdfContentContainer.innerHTML = ''; } // --- Initial Render and Setup --- renderDebtTable(); // Render empty table on load showTab(0); // Show the first tab by default });