VCM / index.html
Pablosolaris's picture
Add 2 files
d150bdb verified
raw
history blame
36.8 kB
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculadora de Crédito</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.dark-mode {
background-color: #1a202c;
color: #f7fafc;
}
.dark-mode .card {
background-color: #2d3748;
border-color: #4a5568;
}
.dark-mode input, .dark-mode select {
background-color: #2d3748;
border-color: #4a5568;
color: #f7fafc;
}
.dark-mode .btn-primary {
background-color: #4299e1;
}
.dark-mode .btn-secondary {
background-color: #718096;
}
.dark-mode .table-container {
background-color: #2d3748;
}
.dark-mode table {
color: #f7fafc;
}
.dark-mode table th, .dark-mode table td {
border-color: #4a5568;
}
.dark-mode table tr:nth-child(even) {
background-color: #4a5568;
}
.transition-all {
transition: all 0.3s ease;
}
.card {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.btn-primary {
background-color: #3182ce;
color: white;
}
.btn-primary:hover {
background-color: #2c5282;
}
.btn-secondary {
background-color: #a0aec0;
color: white;
}
.btn-secondary:hover {
background-color: #718096;
}
.table-container {
max-height: 400px;
overflow-y: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
table th, table td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid #e2e8f0;
}
table tr:nth-child(even) {
background-color: #f8fafc;
}
.chart-container {
position: relative;
height: 300px;
width: 100%;
}
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 200px;
background-color: #555;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 5px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
margin-left: -100px;
opacity: 0;
transition: opacity 0.3s;
}
.tooltip:hover .tooltip-text {
visibility: visible;
opacity: 1;
}
</style>
</head>
<body class="bg-gray-100 transition-all">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="flex justify-between items-center mb-8">
<h1 class="text-3xl font-bold text-blue-800" id="title">Calculadora de Crédito</h1>
<div class="flex space-x-4">
<div class="tooltip">
<button id="darkModeToggle" class="p-2 rounded-full bg-gray-200 hover:bg-gray-300">
<i class="fas fa-moon"></i>
</button>
<span class="tooltip-text" id="darkModeTooltip">Modo oscuro</span>
</div>
<div class="relative">
<select id="languageSelect" class="p-2 rounded border border-gray-300 bg-white">
<option value="es">Español</option>
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</div>
</div>
</header>
<!-- Main Content -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Input Section -->
<div class="lg:col-span-1">
<div class="card bg-white rounded-lg shadow p-6">
<h2 class="text-xl font-semibold mb-4" id="inputTitle">Datos del Crédito</h2>
<div class="mb-4">
<label for="amount" class="block text-sm font-medium text-gray-700 mb-1" id="amountLabel">Monto Total</label>
<input type="number" id="amount" class="w-full p-2 border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500" placeholder="0.00" min="0">
</div>
<div class="mb-4">
<label for="currency" class="block text-sm font-medium text-gray-700 mb-1" id="currencyLabel">Moneda</label>
<select id="currency" class="w-full p-2 border border-gray-300 rounded">
<option value="MXN">MXN - Peso Mexicano</option>
<option value="USD">USD - Dólar Estadounidense</option>
<option value="CAD">CAD - Dólar Canadiense</option>
<option value="CLP">CLP - Peso Chileno</option>
<option value="ARS">ARS - Peso Argentino</option>
<option value="COP">COP - Peso Colombiano</option>
<option value="EUR">EUR - Euro</option>
</select>
</div>
<div class="mb-6">
<label class="block text-sm font-medium text-gray-700 mb-1" id="termLabel">Plazo del Financiamiento Intermedio (20%)</label>
<div class="flex space-x-4 mt-2">
<div class="flex items-center">
<input id="term6" name="term" type="radio" value="6" class="h-4 w-4 text-blue-600 focus:ring-blue-500" checked>
<label for="term6" class="ml-2 block text-sm text-gray-700">
<span id="term6Label">6 meses (4.99%)</span>
</label>
</div>
<div class="flex items-center">
<input id="term9" name="term" type="radio" value="9" class="h-4 w-4 text-blue-600 focus:ring-blue-500">
<label for="term9" class="ml-2 block text-sm text-gray-700">
<span id="term9Label">9 meses (6.99%)</span>
</label>
</div>
</div>
</div>
<button id="calculateBtn" class="w-full btn-primary py-2 px-4 rounded font-medium" id="calculateBtnText">
Calcular
</button>
</div>
</div>
<!-- Results Section -->
<div class="lg:col-span-2">
<div class="card bg-white rounded-lg shadow p-6 mb-6">
<h2 class="text-xl font-semibold mb-4" id="summaryTitle">Resumen del Crédito</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div class="bg-blue-50 p-4 rounded-lg">
<p class="text-sm text-blue-800 font-medium" id="totalAmountLabel">Monto Total</p>
<p id="totalAmount" class="text-2xl font-bold text-blue-900">$0.00</p>
</div>
<div class="bg-green-50 p-4 rounded-lg">
<p class="text-sm text-green-800 font-medium" id="downPaymentLabel">Enganche (10%)</p>
<p id="downPayment" class="text-2xl font-bold text-green-900">$0.00</p>
</div>
<div class="bg-yellow-50 p-4 rounded-lg">
<p class="text-sm text-yellow-800 font-medium" id="interestLabel">Interés Generado (20%)</p>
<p id="interest" class="text-2xl font-bold text-yellow-900">$0.00</p>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<p class="text-sm text-purple-800 font-medium" id="totalPaymentLabel">Total a Pagar</p>
<p id="totalPayment" class="text-2xl font-bold text-purple-900">$0.00</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h3 class="font-medium mb-2" id="monthlyPaymentsLabel">Pagos Mensuales</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm text-gray-600" id="intermediatePaymentLabel">Financiamiento intermedio (20% con interés):</p>
<p id="intermediatePayment" class="text-lg font-semibold">$0.00</p>
<p class="text-sm text-gray-600 mt-2" id="longTermPaymentLabel">Financiamiento largo plazo (70% sin interés):</p>
<p id="longTermPayment" class="text-lg font-semibold">$0.00</p>
</div>
</div>
<div>
<h3 class="font-medium mb-2" id="comparisonTitle">Comparación de Plazos</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm text-gray-600" id="term6ComparisonLabel">6 meses: Total interés</p>
<p id="term6Comparison" class="text-lg font-semibold">$0.00</p>
<p class="text-sm text-gray-600 mt-2" id="term9ComparisonLabel">9 meses: Total interés</p>
<p id="term9Comparison" class="text-lg font-semibold">$0.00</p>
</div>
</div>
</div>
</div>
<!-- Charts Section -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
<div class="card bg-white rounded-lg shadow p-4">
<h3 class="font-medium mb-2" id="distributionChartTitle">Distribución del Pago</h3>
<div class="chart-container">
<canvas id="pieChart"></canvas>
</div>
</div>
<div class="card bg-white rounded-lg shadow p-4">
<h3 class="font-medium mb-2" id="paymentEvolutionTitle">Evolución de Pagos</h3>
<div class="chart-container">
<canvas id="lineChart"></canvas>
</div>
</div>
</div>
<!-- Amortization Table -->
<div class="card bg-white rounded-lg shadow p-6">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold" id="amortizationTitle">Tabla de Amortización</h2>
<div class="flex space-x-2">
<button id="exportExcel" class="btn-secondary py-1 px-3 rounded text-sm">
<i class="fas fa-file-excel mr-1"></i>
<span id="exportExcelText">Excel</span>
</button>
<button id="exportPDF" class="btn-secondary py-1 px-3 rounded text-sm">
<i class="fas fa-file-pdf mr-1"></i>
<span id="exportPDFText">PDF</span>
</button>
</div>
</div>
<div class="table-container">
<table id="amortizationTable">
<thead>
<tr class="bg-gray-100">
<th class="py-2" id="monthHeader">Mes</th>
<th class="py-2" id="intermediatePaymentHeader">Pago 20% (con interés)</th>
<th class="py-2" id="longTermPaymentHeader">Pago 70% (sin interés)</th>
<th class="py-2" id="remainingBalanceHeader">Saldo Restante</th>
</tr>
</thead>
<tbody id="amortizationBody">
<!-- Table content will be generated by JavaScript -->
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script>
// Translations
const translations = {
es: {
title: "Calculadora de Crédito",
inputTitle: "Datos del Crédito",
amountLabel: "Monto Total",
currencyLabel: "Moneda",
termLabel: "Plazo del Financiamiento Intermedio (20%)",
term6Label: "6 meses (4.99%)",
term9Label: "9 meses (6.99%)",
calculateBtnText: "Calcular",
summaryTitle: "Resumen del Crédito",
totalAmountLabel: "Monto Total",
downPaymentLabel: "Enganche (10%)",
interestLabel: "Interés Generado (20%)",
totalPaymentLabel: "Total a Pagar",
monthlyPaymentsLabel: "Pagos Mensuales",
intermediatePaymentLabel: "Financiamiento intermedio (20% con interés):",
longTermPaymentLabel: "Financiamiento largo plazo (70% sin interés):",
comparisonTitle: "Comparación de Plazos",
term6ComparisonLabel: "6 meses: Total interés",
term9ComparisonLabel: "9 meses: Total interés",
distributionChartTitle: "Distribución del Pago",
paymentEvolutionTitle: "Evolución de Pagos",
amortizationTitle: "Tabla de Amortización",
exportExcelText: "Excel",
exportPDFText: "PDF",
monthHeader: "Mes",
intermediatePaymentHeader: "Pago 20% (con interés)",
longTermPaymentHeader: "Pago 70% (sin interés)",
remainingBalanceHeader: "Saldo Restante",
darkModeTooltip: "Modo oscuro"
},
en: {
title: "Loan Calculator",
inputTitle: "Loan Data",
amountLabel: "Total Amount",
currencyLabel: "Currency",
termLabel: "Intermediate Financing Term (20%)",
term6Label: "6 months (4.99%)",
term9Label: "9 months (6.99%)",
calculateBtnText: "Calculate",
summaryTitle: "Loan Summary",
totalAmountLabel: "Total Amount",
downPaymentLabel: "Down Payment (10%)",
interestLabel: "Generated Interest (20%)",
totalPaymentLabel: "Total Payment",
monthlyPaymentsLabel: "Monthly Payments",
intermediatePaymentLabel: "Intermediate financing (20% with interest):",
longTermPaymentLabel: "Long term financing (70% without interest):",
comparisonTitle: "Term Comparison",
term6ComparisonLabel: "6 months: Total interest",
term9ComparisonLabel: "9 months: Total interest",
distributionChartTitle: "Payment Distribution",
paymentEvolutionTitle: "Payment Evolution",
amortizationTitle: "Amortization Table",
exportExcelText: "Excel",
exportPDFText: "PDF",
monthHeader: "Month",
intermediatePaymentHeader: "20% Payment (with interest)",
longTermPaymentHeader: "70% Payment (without interest)",
remainingBalanceHeader: "Remaining Balance",
darkModeTooltip: "Dark mode"
},
fr: {
title: "Calculateur de Crédit",
inputTitle: "Données du Crédit",
amountLabel: "Montant Total",
currencyLabel: "Devise",
termLabel: "Durée du Financement Intermédiaire (20%)",
term6Label: "6 mois (4.99%)",
term9Label: "9 mois (6.99%)",
calculateBtnText: "Calculer",
summaryTitle: "Résumé du Crédit",
totalAmountLabel: "Montant Total",
downPaymentLabel: "Acompte (10%)",
interestLabel: "Intérêt Généré (20%)",
totalPaymentLabel: "Total à Payer",
monthlyPaymentsLabel: "Paiements Mensuels",
intermediatePaymentLabel: "Financement intermédiaire (20% avec intérêt):",
longTermPaymentLabel: "Financement à long terme (70% sans intérêt):",
comparisonTitle: "Comparaison des Durées",
term6ComparisonLabel: "6 mois: Intérêt total",
term9ComparisonLabel: "9 mois: Intérêt total",
distributionChartTitle: "Répartition des Paiements",
paymentEvolutionTitle: "Évolution des Paiements",
amortizationTitle: "Tableau d'Amortissement",
exportExcelText: "Excel",
exportPDFText: "PDF",
monthHeader: "Mois",
intermediatePaymentHeader: "Paiement 20% (avec intérêt)",
longTermPaymentHeader: "Paiement 70% (sans intérêt)",
remainingBalanceHeader: "Solde Restant",
darkModeTooltip: "Mode sombre"
}
};
// DOM Elements
const amountInput = document.getElementById('amount');
const currencySelect = document.getElementById('currency');
const term6Radio = document.getElementById('term6');
const term9Radio = document.getElementById('term9');
const calculateBtn = document.getElementById('calculateBtn');
const languageSelect = document.getElementById('languageSelect');
const darkModeToggle = document.getElementById('darkModeToggle');
const darkModeTooltip = document.getElementById('darkModeTooltip');
// Results Elements
const totalAmountEl = document.getElementById('totalAmount');
const downPaymentEl = document.getElementById('downPayment');
const interestEl = document.getElementById('interest');
const totalPaymentEl = document.getElementById('totalPayment');
const intermediatePaymentEl = document.getElementById('intermediatePayment');
const longTermPaymentEl = document.getElementById('longTermPayment');
const term6ComparisonEl = document.getElementById('term6Comparison');
const term9ComparisonEl = document.getElementById('term9Comparison');
const amortizationBody = document.getElementById('amortizationBody');
// Charts
let pieChart, lineChart;
// Dark Mode
let darkMode = false;
// Current language
let currentLanguage = 'es';
// Initialize the calculator
function init() {
// Event Listeners
calculateBtn.addEventListener('click', calculateLoan);
amountInput.addEventListener('input', calculateLoan);
term6Radio.addEventListener('change', calculateLoan);
term9Radio.addEventListener('change', calculateLoan);
languageSelect.addEventListener('change', changeLanguage);
darkModeToggle.addEventListener('click', toggleDarkMode);
document.getElementById('exportExcel').addEventListener('click', exportToExcel);
document.getElementById('exportPDF').addEventListener('click', exportToPDF);
// Initial calculation
calculateLoan();
}
// Calculate loan details
function calculateLoan() {
const amount = parseFloat(amountInput.value) || 0;
const currency = currencySelect.value;
const term = term6Radio.checked ? 6 : 9;
const interestRate = term6Radio.checked ? 0.0499 : 0.0699;
// Calculate payments
const downPayment = amount * 0.1;
const intermediateAmount = amount * 0.2;
const longTermAmount = amount * 0.7;
// Calculate intermediate payment with compound interest
const monthlyRate = interestRate / 12;
const intermediateMonthlyPayment = intermediateAmount * (monthlyRate * Math.pow(1 + monthlyRate, term)) / (Math.pow(1 + monthlyRate, term) - 1);
const totalIntermediatePayment = intermediateMonthlyPayment * term;
const interestPaid = totalIntermediatePayment - intermediateAmount;
// Calculate long term payment (48 months no interest)
const longTermMonthlyPayment = longTermAmount / 48;
// Calculate total payment
const totalPayment = downPayment + totalIntermediatePayment + longTermAmount;
// Calculate comparison values
const term6MonthlyRate = 0.0499 / 12;
const term6IntermediateMonthlyPayment = intermediateAmount * (term6MonthlyRate * Math.pow(1 + term6MonthlyRate, 6)) / (Math.pow(1 + term6MonthlyRate, 6) - 1);
const term6TotalInterest = (term6IntermediateMonthlyPayment * 6) - intermediateAmount;
const term9MonthlyRate = 0.0699 / 12;
const term9IntermediateMonthlyPayment = intermediateAmount * (term9MonthlyRate * Math.pow(1 + term9MonthlyRate, 9)) / (Math.pow(1 + term9MonthlyRate, 9) - 1);
const term9TotalInterest = (term9IntermediateMonthlyPayment * 9) - intermediateAmount;
// Update UI
updateResults(currency, amount, downPayment, interestPaid, totalPayment, intermediateMonthlyPayment, longTermMonthlyPayment, term6TotalInterest, term9TotalInterest);
updateAmortizationTable(currency, term, intermediateMonthlyPayment, longTermMonthlyPayment, intermediateAmount, longTermAmount);
updateCharts(currency, downPayment, intermediateAmount + interestPaid, longTermAmount);
}
// Update results in UI
function updateResults(currency, amount, downPayment, interest, totalPayment, intermediatePayment, longTermPayment, term6Interest, term9Interest) {
totalAmountEl.textContent = formatCurrency(currency, amount);
downPaymentEl.textContent = formatCurrency(currency, downPayment);
interestEl.textContent = formatCurrency(currency, interest);
totalPaymentEl.textContent = formatCurrency(currency, totalPayment);
intermediatePaymentEl.textContent = formatCurrency(currency, intermediatePayment);
longTermPaymentEl.textContent = formatCurrency(currency, longTermPayment);
term6ComparisonEl.textContent = formatCurrency(currency, term6Interest);
term9ComparisonEl.textContent = formatCurrency(currency, term9Interest);
}
// Update amortization table
function updateAmortizationTable(currency, term, intermediatePayment, longTermPayment, intermediateAmount, longTermAmount) {
amortizationBody.innerHTML = '';
let intermediateRemaining = intermediateAmount;
let longTermRemaining = longTermAmount;
for (let month = 1; month <= 48; month++) {
const row = document.createElement('tr');
// Month column
const monthCell = document.createElement('td');
monthCell.textContent = month;
row.appendChild(monthCell);
// Intermediate payment column
const intermediateCell = document.createElement('td');
if (month <= term) {
intermediateCell.textContent = formatCurrency(currency, intermediatePayment);
intermediateRemaining -= intermediatePayment;
} else {
intermediateCell.textContent = formatCurrency(currency, 0);
}
row.appendChild(intermediateCell);
// Long term payment column
const longTermCell = document.createElement('td');
if (month <= 48) {
longTermCell.textContent = formatCurrency(currency, longTermPayment);
longTermRemaining -= longTermPayment;
} else {
longTermCell.textContent = formatCurrency(currency, 0);
}
row.appendChild(longTermCell);
// Remaining balance column
const remainingCell = document.createElement('td');
remainingCell.textContent = formatCurrency(currency, intermediateRemaining + longTermRemaining);
row.appendChild(remainingCell);
amortizationBody.appendChild(row);
}
}
// Update charts
function updateCharts(currency, downPayment, intermediateTotal, longTermAmount) {
// Pie Chart
const pieCtx = document.getElementById('pieChart').getContext('2d');
if (pieChart) {
pieChart.destroy();
}
pieChart = new Chart(pieCtx, {
type: 'pie',
data: {
labels: [
translations[currentLanguage].downPaymentLabel,
translations[currentLanguage].intermediatePaymentHeader,
translations[currentLanguage].longTermPaymentHeader
],
datasets: [{
data: [downPayment, intermediateTotal, longTermAmount],
backgroundColor: [
'#4299e1',
'#f6ad55',
'#9f7aea'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
const label = context.label || '';
const value = context.raw || 0;
return `${label}: ${formatCurrency(currency, value)}`;
}
}
}
}
}
});
// Line Chart
const lineCtx = document.getElementById('lineChart').getContext('2d');
if (lineChart) {
lineChart.destroy();
}
// Generate data for 48 months
const term = term6Radio.checked ? 6 : 9;
const intermediatePayment = parseFloat(intermediatePaymentEl.textContent.replace(/[^0-9.-]+/g,"")) || 0;
const longTermPayment = parseFloat(longTermPaymentEl.textContent.replace(/[^0-9.-]+/g,"")) || 0;
const labels = Array.from({length: 48}, (_, i) => i + 1);
const intermediateData = labels.map((_, i) => i < term ? intermediatePayment : 0);
const longTermData = labels.map(() => longTermPayment);
const totalData = labels.map((_, i) => intermediateData[i] + longTermData[i]);
lineChart = new Chart(lineCtx, {
type: 'line',
data: {
labels: labels,
datasets: [
{
label: translations[currentLanguage].intermediatePaymentHeader,
data: intermediateData,
borderColor: '#f6ad55',
backgroundColor: 'rgba(246, 173, 85, 0.1)',
tension: 0.1,
fill: true
},
{
label: translations[currentLanguage].longTermPaymentHeader,
data: longTermData,
borderColor: '#9f7aea',
backgroundColor: 'rgba(159, 122, 234, 0.1)',
tension: 0.1,
fill: true
},
{
label: translations[currentLanguage].totalPaymentLabel,
data: totalData,
borderColor: '#4299e1',
backgroundColor: 'rgba(66, 153, 225, 0.1)',
tension: 0.1,
fill: true
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return formatCurrency(currency, value);
}
}
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
const label = context.dataset.label || '';
const value = context.raw || 0;
return `${label}: ${formatCurrency(currency, value)}`;
}
}
}
}
}
});
}
// Format currency
function formatCurrency(currency, amount) {
return new Intl.NumberFormat(getLocale(currency), {
style: 'currency',
currency: currency
}).format(amount);
}
// Get locale based on currency
function getLocale(currency) {
const locales = {
USD: 'en-US',
MXN: 'es-MX',
CAD: 'en-CA',
CLP: 'es-CL',
ARS: 'es-AR',
COP: 'es-CO',
EUR: 'de-DE'
};
return locales[currency] || 'en-US';
}
// Change language
function changeLanguage() {
currentLanguage = languageSelect.value;
updateTranslations();
calculateLoan(); // Recalculate to update chart labels
}
// Update all translations
function updateTranslations() {
const lang = translations[currentLanguage];
for (const key in lang) {
const element = document.getElementById(key);
if (element) {
element.textContent = lang[key];
}
}
// Update dark mode tooltip
darkModeTooltip.textContent = lang.darkModeTooltip;
}
// Toggle dark mode
function toggleDarkMode() {
darkMode = !darkMode;
document.body.classList.toggle('dark-mode', darkMode);
// Update icon
const icon = darkModeToggle.querySelector('i');
icon.classList.toggle('fa-moon', !darkMode);
icon.classList.toggle('fa-sun', darkMode);
// Recreate charts with dark mode colors
if (amountInput.value) {
calculateLoan();
}
}
// Export to Excel
function exportToExcel() {
const table = document.getElementById('amortizationTable');
const ws = XLSX.utils.table_to_sheet(table);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Amortization");
const currency = currencySelect.value;
const amount = amountInput.value || 0;
const fileName = `Amortization_${currency}_${amount}.xlsx`;
XLSX.writeFile(wb, fileName);
}
// Export to PDF
function exportToPDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
// Title
const title = translations[currentLanguage].amortizationTitle;
doc.setFontSize(18);
doc.text(title, 14, 15);
// Loan summary
doc.setFontSize(12);
doc.text(`${translations[currentLanguage].totalAmountLabel}: ${totalAmountEl.textContent}`, 14, 25);
doc.text(`${translations[currentLanguage].downPaymentLabel}: ${downPaymentEl.textContent}`, 14, 32);
doc.text(`${translations[currentLanguage].interestLabel}: ${interestEl.textContent}`, 14, 39);
doc.text(`${translations[currentLanguage].totalPaymentLabel}: ${totalPaymentEl.textContent}`, 14, 46);
// Table headers
const headers = [
translations[currentLanguage].monthHeader,
translations[currentLanguage].intermediatePaymentHeader,
translations[currentLanguage].longTermPaymentHeader,
translations[currentLanguage].remainingBalanceHeader
];
// Table data
const tableData = [];
const rows = amortizationBody.querySelectorAll('tr');
rows.forEach(row => {
const rowData = [];
row.querySelectorAll('td').forEach(cell => {
rowData.push(cell.textContent);
});
tableData.push(rowData);
});
// Add table to PDF
doc.autoTable({
head: [headers],
body: tableData,
startY: 55,
styles: {
fontSize: 8,
cellPadding: 2
},
columnStyles: {
0: { cellWidth: 15 },
1: { cellWidth: 40 },
2: { cellWidth: 40 },
3: { cellWidth: 40 }
}
});
// Save PDF
const currency = currencySelect.value;
const amount = amountInput.value || 0;
doc.save(`Amortization_${currency}_${amount}.pdf`);
}
// Initialize the calculator when the page loads
window.addEventListener('DOMContentLoaded', init);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Pablosolaris/mesa-inteligente" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>