|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Blended Rate Calculator</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
.input-highlight { |
|
transition: all 0.3s ease; |
|
} |
|
.input-highlight:focus { |
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); |
|
border-color: #3b82f6; |
|
} |
|
.result-box { |
|
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); |
|
} |
|
.add-btn:hover { |
|
transform: scale(1.05); |
|
} |
|
.remove-btn:hover { |
|
transform: scale(1.1); |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 min-h-screen"> |
|
<div class="container mx-auto px-4 py-8 max-w-4xl"> |
|
<div class="text-center mb-8"> |
|
<h1 class="text-3xl font-bold text-blue-800 mb-2">Blended Rate Calculator</h1> |
|
<p class="text-gray-600">Calculate the combined interest rate across multiple loans or debts</p> |
|
</div> |
|
|
|
<div class="bg-white rounded-xl shadow-lg overflow-hidden mb-8"> |
|
<div class="p-6"> |
|
<div class="grid grid-cols-12 gap-4 mb-4 font-medium text-gray-700"> |
|
<div class="col-span-6 md:col-span-5">Loan Details</div> |
|
<div class="col-span-3 md:col-span-2 text-right">Balance ($)</div> |
|
<div class="col-span-3 md:col-span-2 text-right">Rate (%)</div> |
|
<div class="col-span-0 md:col-span-3"></div> |
|
</div> |
|
|
|
<div id="loan-entries"> |
|
|
|
</div> |
|
|
|
<div class="flex justify-center mt-4"> |
|
<button id="add-loan" class="add-btn bg-blue-100 text-blue-700 px-4 py-2 rounded-full flex items-center transition-all"> |
|
<i class="fas fa-plus-circle mr-2"></i> Add Another Loan |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="result-box p-6 border-t border-gray-200"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div class="bg-white p-4 rounded-lg border border-gray-200 shadow-sm"> |
|
<div class="text-gray-500 mb-1">Total Balance</div> |
|
<div class="text-2xl font-bold text-blue-800">$<span id="total-balance">0.00</span></div> |
|
</div> |
|
<div class="bg-white p-4 rounded-lg border border-gray-200 shadow-sm"> |
|
<div class="text-gray-500 mb-1">Blended Rate</div> |
|
<div class="text-2xl font-bold text-blue-800"><span id="blended-rate">0.000</span>%</div> |
|
</div> |
|
</div> |
|
<div class="mt-4 text-sm text-gray-500 italic"> |
|
<i class="fas fa-info-circle mr-1"></i> Effective rate is accurate when all loans have the same repayment period. |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="text-center text-sm text-gray-500 mt-8"> |
|
<a href="#" class="text-blue-600 hover:underline">More Calculators</a> |
|
<span class="mx-2">•</span> |
|
<a href="#" class="text-blue-600 hover:underline">Privacy Policy</a> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
document.addEventListener('DOMContentLoaded', function() { |
|
const loanEntries = document.getElementById('loan-entries'); |
|
const addLoanBtn = document.getElementById('add-loan'); |
|
const totalBalanceEl = document.getElementById('total-balance'); |
|
const blendedRateEl = document.getElementById('blended-rate'); |
|
|
|
|
|
const initialLoans = [ |
|
{ balance: '100000', rate: '7' }, |
|
{ balance: '25000', rate: '9' } |
|
]; |
|
|
|
|
|
initialLoans.forEach(loan => addLoanEntry(loan.balance, loan.rate)); |
|
|
|
|
|
calculateBlendedRate(); |
|
|
|
|
|
addLoanBtn.addEventListener('click', () => addLoanEntry()); |
|
|
|
|
|
function addLoanEntry(balance = '', rate = '') { |
|
const loanId = Date.now(); |
|
const loanEntry = document.createElement('div'); |
|
loanEntry.className = 'grid grid-cols-12 gap-4 mb-4 items-center loan-entry'; |
|
loanEntry.dataset.id = loanId; |
|
|
|
loanEntry.innerHTML = ` |
|
<div class="col-span-6 md:col-span-5 flex items-center"> |
|
<span class="text-gray-500 mr-2">${document.querySelectorAll('.loan-entry').length + 1}.</span> |
|
<input type="text" placeholder="Loan name (optional)" class="flex-1 bg-gray-50 border border-gray-200 rounded px-3 py-2 text-sm focus:outline-none input-highlight"> |
|
</div> |
|
<div class="col-span-3 md:col-span-2"> |
|
<div class="relative"> |
|
<span class="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400">$</span> |
|
<input type="number" value="${balance}" min="0" step="0.01" class="balance-input w-full bg-gray-50 border border-gray-200 rounded px-3 py-2 pl-8 text-sm text-right focus:outline-none input-highlight" placeholder="0.00"> |
|
</div> |
|
</div> |
|
<div class="col-span-3 md:col-span-2"> |
|
<div class="relative"> |
|
<input type="number" value="${rate}" min="0" step="0.01" class="rate-input w-full bg-gray-50 border border-gray-200 rounded px-3 py-2 pr-8 text-sm text-right focus:outline-none input-highlight" placeholder="0.00"> |
|
<span class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400">%</span> |
|
</div> |
|
</div> |
|
<div class="col-span-0 md:col-span-3 flex justify-end"> |
|
<button class="remove-btn bg-red-100 text-red-600 p-2 rounded-full hover:bg-red-200 transition-all" data-id="${loanId}"> |
|
<i class="fas fa-times"></i> |
|
</button> |
|
</div> |
|
`; |
|
|
|
loanEntries.appendChild(loanEntry); |
|
|
|
|
|
const balanceInput = loanEntry.querySelector('.balance-input'); |
|
const rateInput = loanEntry.querySelector('.rate-input'); |
|
const removeBtn = loanEntry.querySelector('.remove-btn'); |
|
|
|
balanceInput.addEventListener('input', calculateBlendedRate); |
|
rateInput.addEventListener('input', calculateBlendedRate); |
|
removeBtn.addEventListener('click', function() { |
|
loanEntry.remove(); |
|
updateLoanNumbers(); |
|
calculateBlendedRate(); |
|
}); |
|
|
|
updateLoanNumbers(); |
|
} |
|
|
|
|
|
function updateLoanNumbers() { |
|
const entries = document.querySelectorAll('.loan-entry'); |
|
entries.forEach((entry, index) => { |
|
const numberSpan = entry.querySelector('span.text-gray-500'); |
|
if (numberSpan) { |
|
numberSpan.textContent = `${index + 1}.`; |
|
} |
|
}); |
|
} |
|
|
|
|
|
function calculateBlendedRate() { |
|
const balanceInputs = document.querySelectorAll('.balance-input'); |
|
const rateInputs = document.querySelectorAll('.rate-input'); |
|
|
|
let totalBalance = 0; |
|
let weightedRateSum = 0; |
|
let validLoans = 0; |
|
|
|
balanceInputs.forEach((input, index) => { |
|
const balance = parseFloat(input.value) || 0; |
|
const rate = parseFloat(rateInputs[index].value) || 0; |
|
|
|
if (balance > 0 && rate > 0) { |
|
totalBalance += balance; |
|
weightedRateSum += balance * rate; |
|
validLoans++; |
|
} |
|
}); |
|
|
|
let blendedRate = 0; |
|
if (totalBalance > 0) { |
|
blendedRate = weightedRateSum / totalBalance; |
|
} |
|
|
|
|
|
totalBalanceEl.textContent = totalBalance.toLocaleString('en-US', { |
|
minimumFractionDigits: 2, |
|
maximumFractionDigits: 2 |
|
}); |
|
|
|
blendedRateEl.textContent = blendedRate.toLocaleString('en-US', { |
|
minimumFractionDigits: 3, |
|
maximumFractionDigits: 3 |
|
}); |
|
} |
|
}); |
|
</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=Honda219/blended-rate-calculator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |