`;
// Savings Summary
if (isFinite(scenario1.months) && isFinite(scenario2.months) && scenario2.months < scenario1.months && !scenario1.warning && !scenario2.warning) {
const timeSavedMonths = scenario1.months - scenario2.months;
const interestSaved = scenario1.totalInterest - scenario2.totalInterest;
slrte_loanData.timeSavedFormatted = slrte_formatYearsMonths(timeSavedMonths);
slrte_loanData.interestSaved = interestSaved;
resultsHtml += `
`;
} else {
slrte_loanData.timeSavedFormatted = "N/A";
slrte_loanData.interestSaved = 0;
}
resultsHtml += ``;
if(slrte_domElements.resultsContainer) slrte_domElements.resultsContainer.innerHTML = resultsHtml;
if (slrte_domElements.pdfDownloadBtn) {
slrte_domElements.pdfDownloadBtn.classList.remove('slrte-hidden');
}
}
function slrte_hexToRgb(hex) {
if (!hex || typeof hex !== 'string') return null;
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; });
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null;
}
function slrte_generatePdf() {
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined' || typeof window.jspdf.jsPDF.API === 'undefined' || typeof window.jspdf.jsPDF.API.autoTable === 'undefined') {
alert("PDF generation library is not loaded. Please try again later."); return;
}
if (!slrte_validateTab1() || !slrte_validateTab2()) {
alert("Please ensure all inputs are correctly filled before generating PDF.");
if (!slrte_validateTab1()) slrte_navigateToTab('slrte-tab1');
else if (!slrte_validateTab2()) slrte_navigateToTab('slrte-tab2');
return;
}
slrte_calculateAndDisplayTimelines();
if (slrte_domElements.resultsContainer && slrte_domElements.resultsContainer.innerHTML.includes("slrte-error-message")) {
alert("Cannot generate PDF due to errors in input or calculation. Please correct them."); return;
}
const ActualJsPDF = window.jspdf.jsPDF;
const doc = new ActualJsPDF();
const { loanBalance, annualInterestRate, currentMonthlyPayment, extraMonthlyPayment,
totalNewMonthlyPayment, scenario1, scenario2, timeSavedFormatted, interestSaved } = slrte_loanData;
doc.setFontSize(18);
const primaryColorRGB = slrte_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--slrte-primary-color').trim());
const secondaryColorRGB = slrte_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--slrte-secondary-color').trim());
if (primaryColorRGB) doc.setTextColor(primaryColorRGB.r, primaryColorRGB.g, primaryColorRGB.b); else doc.setTextColor(44,62,80);
doc.text("Student Loan Repayment Timeline Estimate", 105, 22, null, null, "center");
doc.setFontSize(11);
doc.setTextColor(52,73,94); // --slrte-text-color
let startY = 35;
doc.text(`Loan Balance: ${slrte_formatCurrency(loanBalance)} | Interest Rate: ${annualInterestRate}%`, 14, startY);
startY += 10;
const tableHeadFillColor = secondaryColorRGB ? [secondaryColorRGB.r, secondaryColorRGB.g, secondaryColorRGB.b] : [26,37,47];
// Scenario 1
doc.setFontSize(13);
if (primaryColorRGB) doc.setTextColor(primaryColorRGB.r, primaryColorRGB.g, primaryColorRGB.b); else doc.setTextColor(44,62,80);
doc.text(`Scenario 1: Current Payment (${slrte_formatCurrency(currentMonthlyPayment)}/month)`, 14, startY); startY += 7;
doc.autoTable({
startY: startY, theme: 'grid', headStyles: { fillColor: tableHeadFillColor, textColor: 255, fontSize: 10},
body: [
["Est. Repayment Timeline:", slrte_formatYearsMonths(scenario1.months)],
["Est. Total Interest Paid:", isFinite(scenario1.totalInterest) ? slrte_formatCurrency(scenario1.totalInterest) : 'N/A'],
["Est. Total Amount Paid:", isFinite(scenario1.totalPaid) ? slrte_formatCurrency(scenario1.totalPaid) : 'N/A'],
[{content: scenario1.warning || " ", colSpan:2, styles: {textColor: [231,76,60], fontSize:8.5}}]
], margin: { left: 14, right: 14 }, styles: { fontSize: 9.5, cellPadding: 2.5 }, columnStyles: {0: {fontStyle:'bold'}}
});
startY = doc.autoTable.previous.finalY + 10;
// Scenario 2
doc.setFontSize(13);
const accentColorRGB = slrte_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--slrte-accent-color').trim());
if (accentColorRGB) doc.setTextColor(accentColorRGB.r, accentColorRGB.g, accentColorRGB.b); else doc.setTextColor(52,152,219);
doc.text(`Scenario 2: Accelerated Payment (${slrte_formatCurrency(totalNewMonthlyPayment)}/month)`, 14, startY); startY += 7;
doc.autoTable({
startY: startY, theme: 'grid', headStyles: { fillColor: tableHeadFillColor, textColor: 255, fontSize:10 },
body: [
["New Est. Repayment Timeline:", slrte_formatYearsMonths(scenario2.months)],
["New Est. Total Interest Paid:", isFinite(scenario2.totalInterest) ? slrte_formatCurrency(scenario2.totalInterest) : 'N/A'],
["New Est. Total Amount Paid:", isFinite(scenario2.totalPaid) ? slrte_formatCurrency(scenario2.totalPaid) : 'N/A'],
[{content: scenario2.warning || " ", colSpan:2, styles: {textColor: [231,76,60], fontSize:8.5}}]
], margin: { left: 14, right: 14 }, styles: { fontSize: 9.5, cellPadding: 2.5 }, columnStyles: {0: {fontStyle:'bold'}}
});
startY = doc.autoTable.previous.finalY + 10;
// Savings Summary
if (isFinite(scenario1.months) && isFinite(scenario2.months) && scenario2.months < scenario1.months && !scenario1.warning && !scenario2.warning) {
doc.setFontSize(13);
const positiveColorRGB = slrte_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--slrte-positive-color').trim());
if (positiveColorRGB) doc.setTextColor(positiveColorRGB.r, positiveColorRGB.g, positiveColorRGB.b); else doc.setTextColor(46,204,113);
doc.text("Potential Savings with Extra Payments:", 14, startY); startY += 7;
doc.autoTable({
startY: startY, theme: 'grid', headStyles: { fillColor: tableHeadFillColor, textColor: 255, fontSize:10 },
body: [
["Time Saved on Repayment:", timeSavedFormatted],
["Interest Saved:", slrte_formatCurrency(interestSaved)],
], margin: { left: 14, right: 14 }, styles: { fontSize: 9.5, cellPadding: 2.5 }, columnStyles: {0: {fontStyle:'bold'}}
});
startY = doc.autoTable.previous.finalY + 12;
}
doc.setFontSize(9);
doc.setTextColor(100);
doc.text(`Report generated on: ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`, 14, doc.internal.pageSize.height - 10);
doc.save("Student_Loan_Repayment_Timeline.pdf");
}
window.slrte_switchTab = slrte_switchTab;
window.slrte_navigateToTab = slrte_navigateToTab;
window.slrte_generatePdf = slrte_generatePdf;
window.slrte_updateNewTotalPaymentDisplay = slrte_updateNewTotalPaymentDisplay;
Potential Savings with Extra Payments:
Time Saved on Repayment: ${slrte_loanData.timeSavedFormatted}
Interest Saved: ${slrte_formatCurrency(slrte_loanData.interestSaved)}
Making even small additional payments can significantly reduce your loan term and the total interest paid. Consider what extra amount fits your budget.
