Loan-Based Study Abroad Budgeting Tool
1. Program & Core Costs
2. Living & Travel
3. Funding & Loan
4. Budget Summary
Program & Core Academic Costs
Please enter all estimated costs in US Dollars ($). Convert if necessary.
Next: Living & Travel »
Estimated Living & Travel Expenses (Total for Program Duration)
Enter total estimated costs for the entire program duration in US Dollars ($).
Sub-Total (Living & Travel Expenses): $0.00
« Previous
Next: Funding & Loan »
Available Funds & Loan Preview
Total Available Funds: $0.00
Estimated Loan Amount Needed: $0.00
Optional: Loan Repayment Preview (for estimated loan amount)
« Previous
View Budget Summary »
Budget Summary
Please complete all previous tabs to view your budget summary.
Download Budget (PDF)
« Previous
Please complete all previous tabs to view your budget summary.
';
}
if(sablt_domElements.pdfDownloadBtn) sablt_domElements.pdfDownloadBtn.classList.add('sablt-hidden');
}
}
function sablt_navigateToTab(targetTabId) {
const currentActiveTabLink = document.querySelector('.sablt-tab-link.sablt-active');
if (!currentActiveTabLink) { console.error("Current active tab link not found."); return; }
const currentTabId = currentActiveTabLink.getAttribute('data-tab');
let proceed = true;
if (currentTabId === 'sablt-tab1') {
proceed = sablt_validateTab1();
} else if (currentTabId === 'sablt-tab2') {
if (!sablt_validateTab1()) {
const tab1Button = document.querySelector('.sablt-tab-link[data-tab="sablt-tab1"]');
if (tab1Button) tab1Button.click(); return;
}
proceed = sablt_validateTab2();
} else if (currentTabId === 'sablt-tab3') {
if (!sablt_validateTab1()) {
const tab1Button = document.querySelector('.sablt-tab-link[data-tab="sablt-tab1"]');
if (tab1Button) tab1Button.click(); return;
}
if (!sablt_validateTab2()) {
const tab2Button = document.querySelector('.sablt-tab-link[data-tab="sablt-tab2"]');
if (tab2Button) tab2Button.click(); return;
}
proceed = sablt_validateTab3();
}
if (proceed) {
const targetTabButton = document.querySelector(`.sablt-tab-link[data-tab="${targetTabId}"]`);
if (targetTabButton) targetTabButton.click();
}
}
function sablt_calculateAndDisplaySummary() {
if (!sablt_domElements.resultsContainer) return;
if (!sablt_validateTab1() || !sablt_validateTab2() || !sablt_validateTab3()) {
sablt_domElements.resultsContainer.innerHTML = '
Please correct errors in the previous tabs to view the summary.
';
if(sablt_domElements.pdfDownloadBtn) sablt_domElements.pdfDownloadBtn.classList.add('sablt-hidden');
return;
}
// Ensure final calculations are run for loan if needed
sablt_updateFundingSummaryAndLoanPreview();
const { coreCosts, livingTravelCosts, totalExpenses, availableFunds, estimatedLoanNeeded, loanPreview, programDurationMonths, destinationCountry } = sablt_budget;
let summaryHTML = `
Program Overview
Destination Country: ${destinationCountry || 'Not Specified'}
Program Duration: ${programDurationMonths > 0 ? programDurationMonths + ' months' : 'N/A'}
Estimated Expenses (Total for Program)
Tuition Fees: ${sablt_formatCurrency(coreCosts.tuition)}
Other Program Fees: ${sablt_formatCurrency(coreCosts.program)}
Books & Supplies: ${sablt_formatCurrency(coreCosts.books)}
Subtotal Core Costs: ${sablt_formatCurrency(coreCosts.total)}
Accommodation: ${sablt_formatCurrency(livingTravelCosts.accommodation)}
Food & Groceries: ${sablt_formatCurrency(livingTravelCosts.food)}
Local Transportation: ${sablt_formatCurrency(livingTravelCosts.localTransport)}
Utilities: ${sablt_formatCurrency(livingTravelCosts.utilities)}
Health Insurance: ${sablt_formatCurrency(livingTravelCosts.healthInsurance)}
Round-trip Airfare: ${sablt_formatCurrency(livingTravelCosts.airfare)}
Visa & Related Costs: ${sablt_formatCurrency(livingTravelCosts.visa)}
Initial Setup & Personal Spending: ${sablt_formatCurrency(livingTravelCosts.personalSetupSpending)}
Subtotal Living & Travel: ${sablt_formatCurrency(livingTravelCosts.total)}
TOTAL ESTIMATED EXPENSES: ${sablt_formatCurrency(totalExpenses)}
Available Funds & Loan Estimation
Personal Savings: ${sablt_formatCurrency(availableFunds.savings)}
Scholarships/Grants: ${sablt_formatCurrency(availableFunds.scholarships)}
Family Contributions: ${sablt_formatCurrency(availableFunds.family)}
Total Available Funds: ${sablt_formatCurrency(availableFunds.total)}
ESTIMATED LOAN AMOUNT NEEDED: ${sablt_formatCurrency(estimatedLoanNeeded)}
${estimatedLoanNeeded <= 0 ? '
Congratulations! Your available funds appear to cover your estimated expenses.
' : ''}
`;
if (loanPreview.active && estimatedLoanNeeded > 0) {
summaryHTML += `
Loan Repayment Preview (for Estimated Loan Amount)
Assumed Loan Interest Rate: ${sablt_formatPercent(loanPreview.interestRate,2)}
Assumed Loan Term: ${loanPreview.termYears} years
Estimated Monthly Payment: ${sablt_formatCurrency(loanPreview.monthlyPayment)}
Estimated Total Interest Paid: ${sablt_formatCurrency(loanPreview.totalInterest)}
Estimated Total Repayment: ${sablt_formatCurrency(loanPreview.totalRepaid)}
`;
}
summaryHTML += `
Remember: This is an estimated budget. Actual costs can vary. Research specific costs for your chosen program and destination thoroughly. Look for additional scholarships or funding opportunities to minimize borrowing.
`;
sablt_domElements.resultsContainer.innerHTML = summaryHTML;
if (sablt_domElements.pdfDownloadBtn) {
sablt_domElements.pdfDownloadBtn.classList.remove('sablt-hidden');
}
}
function sablt_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 sablt_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 (!sablt_validateTab1() || !sablt_validateTab2() || !sablt_validateTab3()) {
alert("Please ensure all inputs are correctly filled before generating PDF.");
// Try to navigate to the first invalid tab
if (!sablt_validateTab1()) sablt_navigateToTab('sablt-tab1');
else if (!sablt_validateTab2()) sablt_navigateToTab('sablt-tab2');
else if (!sablt_validateTab3()) sablt_navigateToTab('sablt-tab3');
return;
}
sablt_calculateAndDisplaySummary();
if (sablt_domElements.resultsContainer && sablt_domElements.resultsContainer.innerHTML.includes("sablt-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 { coreCosts, livingTravelCosts, totalExpenses, availableFunds, estimatedLoanNeeded, loanPreview, programDurationMonths, destinationCountry } = sablt_budget;
doc.setFontSize(18);
const primaryColorRGB = sablt_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--sablt-primary-color').trim()) || {r:0,g:121,b:107};
const secondaryColorRGB = sablt_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--sablt-secondary-color').trim()) || {r:0,g:77,b:64};
const accentColorRGB = sablt_hexToRgb(getComputedStyle(document.documentElement).getPropertyValue('--sablt-accent-color').trim()) || {r:255,g:143,b:0};
doc.setTextColor(primaryColorRGB.r, primaryColorRGB.g, primaryColorRGB.b);
doc.text("Study Abroad Budget Summary", 105, 20, null, null, "center");
doc.setFontSize(10);
doc.setTextColor(38,50,56);
let startY = 30;
doc.text(`Destination: ${destinationCountry || 'Not Specified'} | Program Duration: ${programDurationMonths > 0 ? programDurationMonths + ' months' : 'N/A'}`, 14, startY);
startY += 10;
const tableHeadFillColor = [secondaryColorRGB.r, secondaryColorRGB.g, secondaryColorRGB.b];
const bodyStyles = { fontSize: 9, cellPadding: 2 };
const headStyles = { fillColor: tableHeadFillColor, textColor: 255, fontSize: 9.5, fontStyle: 'bold', cellPadding: 2.5 };
const boldStyle = { fontStyle: 'bold' };
doc.setFontSize(12);
doc.setTextColor(secondaryColorRGB.r, secondaryColorRGB.g, secondaryColorRGB.b);
doc.text("Estimated Expenses (Total for Program)", 14, startY); startY += 6;
const expenseBody = [
["Tuition Fees:", sablt_formatCurrency(coreCosts.tuition)],
["Other Program Fees:", sablt_formatCurrency(coreCosts.program)],
["Books & Supplies:", sablt_formatCurrency(coreCosts.books)],
[{content: "Subtotal Core Costs:", styles: boldStyle}, {content: sablt_formatCurrency(coreCosts.total), styles: boldStyle}],
["Accommodation:", sablt_formatCurrency(livingTravelCosts.accommodation)],
["Food & Groceries:", sablt_formatCurrency(livingTravelCosts.food)],
["Local Transportation:", sablt_formatCurrency(livingTravelCosts.localTransport)],
["Utilities:", sablt_formatCurrency(livingTravelCosts.utilities)],
["Health Insurance:", sablt_formatCurrency(livingTravelCosts.healthInsurance)],
["Round-trip Airfare:", sablt_formatCurrency(livingTravelCosts.airfare)],
["Visa & Related Costs:", sablt_formatCurrency(livingTravelCosts.visa)],
["Initial Setup & Personal Spending:", sablt_formatCurrency(livingTravelCosts.personalSetupSpending)],
[{content: "Subtotal Living & Travel:", styles: boldStyle}, {content: sablt_formatCurrency(livingTravelCosts.total), styles: boldStyle}],
[{content: "TOTAL ESTIMATED EXPENSES:", styles: {fontStyle:'bold', fillColor: [236,239,241]}}, {content: sablt_formatCurrency(totalExpenses), styles: {fontStyle:'bold', fillColor: [236,239,241]}}],
];
doc.autoTable({ startY: startY, body: expenseBody, theme: 'grid', styles: bodyStyles, headStyles: headStyles, columnStyles: {0:{fontStyle:'bold', cellWidth: 80}, 1:{halign:'right', cellWidth: 'auto'}} });
startY = doc.autoTable.previous.finalY + 10;
doc.setFontSize(12); doc.setTextColor(secondaryColorRGB.r, secondaryColorRGB.g, secondaryColorRGB.b);
doc.text("Available Funds & Loan Estimation", 14, startY); startY += 6;
const fundingBody = [
["Personal Savings:", sablt_formatCurrency(availableFunds.savings)],
["Scholarships/Grants:", sablt_formatCurrency(availableFunds.scholarships)],
["Family Contributions:", sablt_formatCurrency(availableFunds.family)],
[{content: "Total Available Funds:", styles: boldStyle}, {content: sablt_formatCurrency(availableFunds.total), styles: {fontStyle:'bold', textColor: [primaryColorRGB.r, primaryColorRGB.g, primaryColorRGB.b]}}],
[{content: "ESTIMATED LOAN AMOUNT NEEDED:", styles: {fontStyle:'bold', fillColor: [236,239,241]}}, {content: sablt_formatCurrency(estimatedLoanNeeded), styles: {fontStyle:'bold', textColor: [accentColorRGB.r, accentColorRGB.g, accentColorRGB.b], fillColor: [236,239,241]}}],
];
if (estimatedLoanNeeded <= 0) {
fundingBody.push([{content: "Your available funds appear to cover your estimated expenses.", colSpan:2, styles: {halign:'center', textColor: [primaryColorRGB.r, primaryColorRGB.g, primaryColorRGB.b]}}]);
}
doc.autoTable({ startY: startY, body: fundingBody, theme: 'grid', styles: bodyStyles, headStyles: headStyles, columnStyles: {0:{fontStyle:'bold', cellWidth: 80}, 1:{halign:'right'}} });
startY = doc.autoTable.previous.finalY + 10;
if (loanPreview.active && estimatedLoanNeeded > 0) {
doc.setFontSize(12); doc.setTextColor(secondaryColorRGB.r, secondaryColorRGB.g, secondaryColorRGB.b);
doc.text("Loan Repayment Preview (for Estimated Loan Amount)", 14, startY); startY += 6;
doc.autoTable({
startY: startY, theme: 'grid', styles: bodyStyles, headStyles: headStyles,
body: [
["Assumed Loan Interest Rate:", sablt_formatPercent(loanPreview.interestRate,2)],
["Assumed Loan Term:", `${loanPreview.termYears} years`],
["Estimated Monthly Payment:", sablt_formatCurrency(loanPreview.monthlyPayment)],
["Estimated Total Interest Paid:", sablt_formatCurrency(loanPreview.totalInterest)],
["Estimated Total Repayment:", sablt_formatCurrency(loanPreview.totalRepaid)],
], margin: { left: 14, right: 14 }, columnStyles: {0:{fontStyle:'bold', cellWidth: 80}, 1:{halign:'right'}}
});
startY = doc.autoTable.previous.finalY + 10;
}
doc.setFontSize(9);
doc.setTextColor(100);
const note = "This is an estimated budget. Actual costs can vary. Research specific costs for your chosen program and destination thoroughly. Look for additional scholarships or funding opportunities to minimize borrowing.";
const splitNote = doc.splitTextToSize(note, doc.internal.pageSize.width - 28);
doc.text(splitNote, 14, startY);
startY += (splitNote.length * (doc.getLineHeight() / doc.internal.scaleFactor * 0.8)) + 5;
doc.setFontSize(9);
doc.setTextColor(150);
doc.text(`Report generated on: ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`, 14, doc.internal.pageSize.height - 10);
doc.save("Study_Abroad_Budget_Estimate.pdf");
}
window.sablt_switchTab = sablt_switchTab;
window.sablt_navigateToTab = sablt_navigateToTab;
window.sablt_generatePdf = sablt_generatePdf;
// Expose update functions if needed, though listeners handle most dynamic updates internally
window.sablt_updateTotalLivingTravelDisplay = sablt_updateTotalLivingTravelDisplay;
window.sablt_updateFundingSummaryAndLoanPreview = sablt_updateFundingSummaryAndLoanPreview;