myfinancetools / index.html
madansa7's picture
Update index.html
7a293c8 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Financial Toolkit Pro</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>
:root {
--primary: #4f46e5;
--secondary: #10b981;
--dark: #1e293b;
--light: #f8fafc;
}
body {
background-color: #f1f5f9;
color: var(--dark);
font-family: 'Inter', sans-serif;
}
.card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.card:hover {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform: translateY(-2px);
}
.input-group {
position: relative;
margin-bottom: 1.5rem;
}
.input-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
color: #64748b;
}
.input-group input, .input-group select {
width: 100%;
padding: 0.75rem;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-size: 1rem;
transition: all 0.2s;
}
.input-group input:focus, .input-group select:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.input-group .input-icon {
position: absolute;
right: 12px;
top: 38px;
color: #94a3b8;
}
.btn {
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
border: none;
}
.btn-primary {
background-color: var(--primary);
color: white;
}
.btn-primary:hover {
background-color: #4338ca;
}
.btn-secondary {
background-color: var(--secondary);
color: white;
}
.btn-secondary:hover {
background-color: #0d9488;
}
.result-card {
background-color: #f8fafc;
border-left: 4px solid var(--primary);
padding: 1.5rem;
border-radius: 8px;
margin-top: 1.5rem;
}
.result-value {
font-size: 1.5rem;
font-weight: 700;
color: var(--primary);
}
.tab {
padding: 0.75rem 1rem;
border-radius: 8px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s;
}
.tab.active {
background-color: var(--primary);
color: white;
}
.tab:hover:not(.active) {
background-color: #e2e8f0;
}
.tooltip {
position: relative;
display: inline-block;
}
.tooltip .tooltip-text {
visibility: hidden;
width: 200px;
background-color: var(--dark);
color: #fff;
text-align: center;
border-radius: 6px;
padding: 0.5rem;
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;
}
.amortization-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
font-size: 0.875rem;
}
.amortization-table th {
background-color: #e2e8f0;
padding: 0.5rem;
text-align: left;
}
.amortization-table td {
padding: 0.5rem;
border-bottom: 1px solid #e2e8f0;
}
.amortization-table tr:hover {
background-color: #f1f5f9;
}
.visual-container {
margin-top: 1.5rem;
padding: 1rem;
background-color: #f8fafc;
border-radius: 8px;
border-left: 4px solid var(--secondary);
}
.visual-title {
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--dark);
}
.bar-container {
height: 24px;
background-color: #e2e8f0;
border-radius: 12px;
margin: 0.5rem 0;
overflow: hidden;
position: relative;
}
.bar-fill {
height: 100%;
border-radius: 12px;
transition: width 0.5s ease;
}
.bar-label {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 8px;
color: white;
font-weight: 500;
font-size: 0.75rem;
text-shadow: 0 1px 1px rgba(0,0,0,0.3);
}
.pie-chart {
width: 160px;
height: 160px;
border-radius: 50%;
background: conic-gradient(
var(--primary) 0% 30%,
var(--secondary) 30% 70%,
#f59e0b 70% 100%
);
margin: 0 auto;
}
.legend {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 1rem;
justify-content: center;
}
.legend-item {
display: flex;
align-items: center;
font-size: 0.75rem;
}
.legend-color {
width: 12px;
height: 12px;
border-radius: 2px;
margin-right: 4px;
}
.scrollable-table {
max-height: 300px;
overflow-y: auto;
margin-top: 1rem;
border: 1px solid #e2e8f0;
border-radius: 8px;
}
@media (max-width: 768px) {
.calculator-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body class="min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="mb-10 text-center">
<h1 class="text-4xl font-bold text-gray-800 mb-2">Financial Toolkit Pro</h1>
<p class="text-lg text-gray-600">Your comprehensive financial calculation dashboard</p>
</header>
<!-- Navigation Tabs -->
<div class="flex flex-wrap gap-2 mb-8 justify-center">
<div class="tab active" data-tab="mortgage">Mortgage Calculator</div>
<div class="tab" data-tab="ltv">LTV Calculator</div>
<div class="tab" data-tab="dti">DTI Calculator</div>
<div class="tab" data-tab="dsr">DSR Calculator</div>
<div class="tab" data-tab="roi">ROI Calculator</div>
<div class="tab" data-tab="npv">NPV Calculator</div>
</div>
<!-- Calculator Grid -->
<div class="calculator-grid grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Mortgage Calculator -->
<div class="card p-6" id="mortgage-calculator">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-home text-indigo-500"></i>
Mortgage Calculator
</h2>
<div class="input-group">
<label for="mortgage-amount">Loan Amount ($)</label>
<input type="number" id="mortgage-amount" placeholder="300,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="mortgage-rate">Interest Rate (%)</label>
<input type="number" id="mortgage-rate" placeholder="3.5" step="0.01">
<i class="fas fa-percent input-icon"></i>
</div>
<div class="input-group">
<label for="mortgage-term">Loan Term (years)</label>
<input type="number" id="mortgage-term" placeholder="30">
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateMortgage()">
Calculate Payment
</button>
<div class="result-card" id="mortgage-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Monthly Payment</h3>
<div class="result-value" id="monthly-payment">$0.00</div>
<div class="mt-2 text-sm text-gray-600">
<div>Total Interest: <span id="total-interest">$0.00</span></div>
<div>Total Payment: <span id="total-payment">$0.00</span></div>
</div>
</div>
</div>
<!-- Mortgage Amortization Table -->
<div class="card p-6" id="mortgage-amortization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-table text-indigo-500"></i>
Amortization Schedule
</h2>
<div class="visual-container">
<div class="visual-title">Payment Breakdown (First 5 Years)</div>
<div class="pie-chart"></div>
<div class="legend">
<div class="legend-item"><span class="legend-color" style="background-color: #4f46e5;"></span> Principal</div>
<div class="legend-item"><span class="legend-color" style="background-color: #10b981;"></span> Interest</div>
<div class="legend-item"><span class="legend-color" style="background-color: #f59e0b;"></span> Other</div>
</div>
</div>
<div class="scrollable-table">
<table class="amortization-table" id="amortization-table">
<thead>
<tr>
<th>Year</th>
<th>Principal</th>
<th>Interest</th>
<th>Balance</th>
</tr>
</thead>
<tbody id="amortization-body">
<!-- Filled by JavaScript -->
</tbody>
</table>
</div>
</div>
<!-- LTV Calculator -->
<div class="card p-6" id="ltv-calculator" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-percentage text-green-500"></i>
Loan-to-Value (LTV) Calculator
</h2>
<div class="input-group">
<label for="loan-amount">Loan Amount ($)</label>
<input type="number" id="loan-amount" placeholder="250,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="property-value">Property Value ($)</label>
<input type="number" id="property-value" placeholder="300,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateLTV()">
Calculate LTV
</button>
<div class="result-card" id="ltv-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Loan-to-Value Ratio</h3>
<div class="result-value" id="ltv-ratio">0%</div>
<div class="mt-2 text-sm text-gray-600">
<span id="ltv-assessment">LTV assessment will appear here</span>
</div>
</div>
</div>
<!-- LTV Visualization -->
<div class="card p-6" id="ltv-visualization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-pie text-green-500"></i>
LTV Visualization
</h2>
<div class="visual-container">
<div class="visual-title">Loan vs. Property Value</div>
<div class="bar-container">
<div class="bar-fill" id="ltv-bar" style="width: 0%; background-color: var(--primary);"></div>
<div class="bar-label" id="ltv-bar-label">0%</div>
</div>
<div class="grid grid-cols-2 gap-4 mt-4">
<div class="p-3 bg-blue-50 rounded-lg">
<div class="text-sm text-gray-600">Loan Amount</div>
<div class="font-semibold text-blue-600" id="visual-loan-amount">$0</div>
</div>
<div class="p-3 bg-green-50 rounded-lg">
<div class="text-sm text-gray-600">Property Value</div>
<div class="font-semibold text-green-600" id="visual-property-value">$0</div>
</div>
</div>
</div>
<div class="mt-4 p-4 bg-yellow-50 rounded-lg">
<h4 class="font-semibold text-yellow-800 mb-2">LTV Risk Levels</h4>
<div class="text-sm text-yellow-700">
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <80%: Excellent (Best rates)</div>
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 80-90%: Good (May need PMI)</div>
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >90%: High Risk (Difficult to qualify)</div>
</div>
</div>
</div>
<!-- DTI Calculator -->
<div class="card p-6" id="dti-calculator" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-calculator text-blue-500"></i>
Debt-to-Income (DTI) Calculator
</h2>
<div class="input-group">
<label for="monthly-debt">Monthly Debt Payments ($)</label>
<input type="number" id="monthly-debt" placeholder="1,500">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="gross-income">Gross Monthly Income ($)</label>
<input type="number" id="gross-income" placeholder="6,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateDTI()">
Calculate DTI
</button>
<div class="result-card" id="dti-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Debt-to-Income Ratio</h3>
<div class="result-value" id="dti-ratio">0%</div>
<div class="mt-2 text-sm text-gray-600">
<span id="dti-assessment">DTI assessment will appear here</span>
</div>
</div>
</div>
<!-- DTI Visualization -->
<div class="card p-6" id="dti-visualization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-bar text-blue-500"></i>
DTI Visualization
</h2>
<div class="visual-container">
<div class="visual-title">Income vs. Debt</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div class="p-3 bg-blue-50 rounded-lg">
<div class="text-sm text-gray-600">Monthly Income</div>
<div class="font-semibold text-blue-600" id="visual-income">$0</div>
</div>
<div class="p-3 bg-purple-50 rounded-lg">
<div class="text-sm text-gray-600">Monthly Debt</div>
<div class="font-semibold text-purple-600" id="visual-debt">$0</div>
</div>
</div>
<div class="bar-container">
<div class="bar-fill" id="dti-bar" style="width: 0%; background-color: var(--primary);"></div>
<div class="bar-label" id="dti-bar-label">0%</div>
</div>
</div>
<div class="mt-4 p-4 bg-blue-50 rounded-lg">
<h4 class="font-semibold text-blue-800 mb-2">DTI Guidelines</h4>
<div class="text-sm text-blue-700">
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <36%: Ideal for most lenders</div>
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 36-43%: Acceptable but may limit options</div>
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >43%: May have difficulty qualifying</div>
</div>
</div>
</div>
<!-- DSR Calculator -->
<div class="card p-6" id="dsr-calculator" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-scale-balanced text-purple-500"></i>
Debt Service Ratio (DSR) Calculator
</h2>
<div class="input-group">
<label for="annual-debt">Annual Debt Service ($)</label>
<input type="number" id="annual-debt" placeholder="18,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="net-income">Net Annual Income ($)</label>
<input type="number" id="net-income" placeholder="72,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateDSR()">
Calculate DSR
</button>
<div class="result-card" id="dsr-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Debt Service Ratio</h3>
<div class="result-value" id="dsr-ratio">0%</div>
<div class="mt-2 text-sm text-gray-600">
<span id="dsr-assessment">DSR assessment will appear here</span>
</div>
</div>
</div>
<!-- DSR Visualization -->
<div class="card p-6" id="dsr-visualization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-line text-purple-500"></i>
DSR Visualization
</h2>
<div class="visual-container">
<div class="visual-title">Income Coverage</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div class="p-3 bg-green-50 rounded-lg">
<div class="text-sm text-gray-600">Net Income</div>
<div class="font-semibold text-green-600" id="visual-net-income">$0</div>
</div>
<div class="p-3 bg-red-50 rounded-lg">
<div class="text-sm text-gray-600">Debt Service</div>
<div class="font-semibold text-red-600" id="visual-annual-debt">$0</div>
</div>
</div>
<div class="bar-container">
<div class="bar-fill" id="dsr-bar" style="width: 0%; background-color: var(--secondary);"></div>
<div class="bar-label" id="dsr-bar-label">0%</div>
</div>
</div>
<div class="mt-4 p-4 bg-purple-50 rounded-lg">
<h4 class="font-semibold text-purple-800 mb-2">DSR Risk Levels</h4>
<div class="text-sm text-purple-700">
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> <20%: Excellent coverage</div>
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-yellow-500 rounded-full mr-2"></span> 20-35%: Manageable</div>
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> >35%: Potentially unsustainable</div>
</div>
</div>
</div>
<!-- ROI Calculator -->
<div class="card p-6" id="roi-calculator" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-line text-teal-500"></i>
Return on Investment (ROI) Calculator
</h2>
<div class="input-group">
<label for="investment-gain">Investment Gain ($)</label>
<input type="number" id="investment-gain" placeholder="50,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="investment-cost">Investment Cost ($)</label>
<input type="number" id="investment-cost" placeholder="200,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateROI()">
Calculate ROI
</button>
<div class="result-card" id="roi-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Return on Investment</h3>
<div class="result-value" id="roi-percentage">0%</div>
<div class="mt-2 text-sm text-gray-600">
<span id="roi-assessment">ROI assessment will appear here</span>
</div>
</div>
</div>
<!-- ROI Visualization -->
<div class="card p-6" id="roi-visualization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-pie text-teal-500"></i>
ROI Visualization
</h2>
<div class="visual-container">
<div class="visual-title">Investment Performance</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div class="p-3 bg-blue-50 rounded-lg">
<div class="text-sm text-gray-600">Cost</div>
<div class="font-semibold text-blue-600" id="visual-investment-cost">$0</div>
</div>
<div class="p-3 bg-green-50 rounded-lg">
<div class="text-sm text-gray-600">Gain</div>
<div class="font-semibold text-green-600" id="visual-investment-gain">$0</div>
</div>
</div>
<div class="flex items-center justify-center">
<div class="w-32 h-32 rounded-full flex items-center justify-center border-4 border-teal-200" id="roi-circle">
<div class="text-xl font-bold text-teal-600" id="roi-circle-value">0%</div>
</div>
</div>
</div>
<div class="mt-4 p-4 bg-teal-50 rounded-lg">
<h4 class="font-semibold text-teal-800 mb-2">ROI Interpretation</h4>
<div class="text-sm text-teal-700">
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> Positive: Profitable investment</div>
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> Negative: Losing investment</div>
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-gray-500 rounded-full mr-2"></span> Zero: Break-even point</div>
</div>
</div>
</div>
<!-- NPV Calculator -->
<div class="card p-6" id="npv-calculator" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-coins text-amber-500"></i>
Net Present Value (NPV) Calculator
</h2>
<div class="input-group">
<label for="initial-investment">Initial Investment ($)</label>
<input type="number" id="initial-investment" placeholder="100,000">
<i class="fas fa-dollar-sign input-icon"></i>
</div>
<div class="input-group">
<label for="discount-rate">Discount Rate (%)</label>
<input type="number" id="discount-rate" placeholder="5" step="0.1">
<i class="fas fa-percent input-icon"></i>
</div>
<div class="input-group">
<label for="cash-flows">Cash Flows (comma separated, $)</label>
<input type="text" id="cash-flows" placeholder="30,000, 35,000, 40,000">
</div>
<button class="btn btn-primary w-full mt-2" onclick="calculateNPV()">
Calculate NPV
</button>
<div class="result-card" id="npv-result" style="display: none;">
<h3 class="font-semibold text-gray-700">Net Present Value</h3>
<div class="result-value" id="npv-value">$0.00</div>
<div class="mt-2 text-sm text-gray-600">
<span id="npv-assessment">NPV assessment will appear here</span>
</div>
</div>
</div>
<!-- NPV Visualization -->
<div class="card p-6" id="npv-visualization" style="display: none;">
<h2 class="text-xl font-bold mb-4 text-gray-800 flex items-center gap-2">
<i class="fas fa-chart-line text-amber-500"></i>
NPV Cash Flow Timeline
</h2>
<div class="visual-container">
<div class="visual-title">Discounted Cash Flows</div>
<div class="h-48 flex items-end justify-center gap-1" id="npv-chart">
<!-- Bars will be added by JavaScript -->
</div>
</div>
<div class="mt-4 p-4 bg-amber-50 rounded-lg">
<h4 class="font-semibold text-amber-800 mb-2">NPV Decision Rule</h4>
<div class="text-sm text-amber-700">
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-green-500 rounded-full mr-2"></span> Positive NPV: Accept project (adds value)</div>
<div class="flex items-center mb-1"><span class="inline-block w-3 h-3 bg-red-500 rounded-full mr-2"></span> Negative NPV: Reject project (destroys value)</div>
<div class="flex items-center"><span class="inline-block w-3 h-3 bg-gray-500 rounded-full mr-2"></span> Zero NPV: Indifferent (no value change)</div>
</div>
</div>
</div>
</div>
<!-- Financial Glossary -->
<div class="mt-12 card p-6">
<h2 class="text-xl font-bold mb-4 text-gray-800">
<i class="fas fa-book mr-2 text-indigo-500"></i>
Financial Terms Glossary
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">LTV (Loan-to-Value)</h3>
<p class="text-sm text-gray-600">The ratio of a loan to the value of the asset purchased, expressed as a percentage.</p>
</div>
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">DTI (Debt-to-Income)</h3>
<p class="text-sm text-gray-600">A personal finance measure comparing an individual's debt payments to their overall income.</p>
</div>
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">DSR (Debt Service Ratio)</h3>
<p class="text-sm text-gray-600">Measures the cash flow available to meet annual interest and principal payments on debt.</p>
</div>
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">ROI (Return on Investment)</h3>
<p class="text-sm text-gray-600">A performance measure used to evaluate the efficiency of an investment.</p>
</div>
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">NPV (Net Present Value)</h3>
<p class="text-sm text-gray-600">The difference between the present value of cash inflows and outflows over a period of time.</p>
</div>
<div class="p-4 border border-gray-200 rounded-lg">
<h3 class="font-semibold text-indigo-600 mb-2">Amortization</h3>
<p class="text-sm text-gray-600">The process of spreading out a loan into a series of fixed payments over time.</p>
</div>
</div>
</div>
</div>
<script>
// Tab switching functionality
document.querySelectorAll('.tab').forEach(tab => {
tab.addEventListener('click', () => {
// Remove active class from all tabs
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
// Add active class to clicked tab
tab.classList.add('active');
// Hide all calculators and visualizations
document.querySelectorAll('.card[id$="-calculator"], .card[id$="-visualization"], #mortgage-amortization').forEach(calc => {
calc.style.display = 'none';
});
// Show selected calculator and its visualization
const tabName = tab.getAttribute('data-tab');
document.getElementById(`${tabName}-calculator`).style.display = 'block';
// Special case for mortgage which has amortization table
if (tabName === 'mortgage') {
document.getElementById('mortgage-amortization').style.display = 'block';
} else {
document.getElementById(`${tabName}-visualization`).style.display = 'block';
}
});
});
// Format currency
function formatCurrency(amount) {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
}
// Format percentage
function formatPercentage(value) {
return value.toFixed(2) + '%';
}
// Mortgage Calculator
function calculateMortgage() {
const amount = parseFloat(document.getElementById('mortgage-amount').value) || 0;
const rate = parseFloat(document.getElementById('mortgage-rate').value) || 0;
const term = parseFloat(document.getElementById('mortgage-term').value) || 0;
if (amount <= 0 || rate <= 0 || term <= 0) {
alert('Please enter valid values for all fields');
return;
}
const monthlyRate = rate / 100 / 12;
const payments = term * 12;
// Calculate monthly payment
const monthlyPayment = amount *
(monthlyRate * Math.pow(1 + monthlyRate, payments)) /
(Math.pow(1 + monthlyRate, payments) - 1);
// Calculate total payment and interest
const totalPayment = monthlyPayment * payments;
const totalInterest = totalPayment - amount;
// Display results
document.getElementById('monthly-payment').textContent = formatCurrency(monthlyPayment);
document.getElementById('total-interest').textContent = formatCurrency(totalInterest);
document.getElementById('total-payment').textContent = formatCurrency(totalPayment);
document.getElementById('mortgage-result').style.display = 'block';
// Generate amortization table
generateAmortizationTable(amount, rate, term, monthlyPayment);
}
// Generate amortization table
function generateAmortizationTable(amount, rate, term, monthlyPayment) {
const tableBody = document.getElementById('amortization-body');
tableBody.innerHTML = '';
let balance = amount;
const monthlyRate = rate / 100 / 12;
const totalPayments = term * 12;
let totalInterest = 0;
// Calculate for each year
for (let year = 1; year <= term; year++) {
let yearInterest = 0;
let yearPrincipal = 0;
// Calculate for each month in the year
for (let month = 1; month <= 12 && (year-1)*12+month <= totalPayments; month++) {
const interestPayment = balance * monthlyRate;
const principalPayment = monthlyPayment - interestPayment;
yearInterest += interestPayment;
yearPrincipal += principalPayment;
balance -= principalPayment;
}
totalInterest += yearInterest;
// Add row to table
const row = document.createElement('tr');
row.innerHTML = `
<td>${year}</td>
<td>${formatCurrency(yearPrincipal)}</td>
<td>${formatCurrency(yearInterest)}</td>
<td>${formatCurrency(balance)}</td>
`;
tableBody.appendChild(row);
}
// Show the amortization table
document.getElementById('mortgage-amortization').style.display = 'block';
}
// LTV Calculator
function calculateLTV() {
const loanAmount = parseFloat(document.getElementById('loan-amount').value) || 0;
const propertyValue = parseFloat(document.getElementById('property-value').value) || 0;
if (loanAmount <= 0 || propertyValue <= 0) {
alert('Please enter valid values for all fields');
return;
}
const ltv = (loanAmount / propertyValue) * 100;
// Display results
document.getElementById('ltv-ratio').textContent = formatPercentage(ltv);
// Update visualization
document.getElementById('ltv-bar').style.width = `${Math.min(100, ltv)}%`;
document.getElementById('ltv-bar-label').textContent = formatPercentage(ltv);
document.getElementById('visual-loan-amount').textContent = formatCurrency(loanAmount);
document.getElementById('visual-property-value').textContent = formatCurrency(propertyValue);
// Assessment
let assessment = '';
if (ltv <= 80) {
assessment = 'Excellent - You may qualify for the best mortgage rates.';
document.getElementById('ltv-bar').style.backgroundColor = '#10b981';
} else if (ltv <= 90) {
assessment = 'Good - You may need to pay Private Mortgage Insurance (PMI).';
document.getElementById('ltv-bar').style.backgroundColor = '#f59e0b';
} else {
assessment = 'High Risk - You may have difficulty qualifying for a loan.';
document.getElementById('ltv-bar').style.backgroundColor = '#ef4444';
}
document.getElementById('ltv-assessment').textContent = assessment;
document.getElementById('ltv-result').style.display = 'block';
document.getElementById('ltv-visualization').style.display = 'block';
}
// DTI Calculator
function calculateDTI() {
const monthlyDebt = parseFloat(document.getElementById('monthly-debt').value) || 0;
const grossIncome = parseFloat(document.getElementById('gross-income').value) || 0;
if (monthlyDebt <= 0 || grossIncome <= 0) {
alert('Please enter valid values for all fields');
return;
}
const dti = (monthlyDebt / grossIncome) * 100;
// Display results
document.getElementById('dti-ratio').textContent = formatPercentage(dti);
// Update visualization
document.getElementById('dti-bar').style.width = `${Math.min(100, dti)}%`;
document.getElementById('dti-bar-label').textContent = formatPercentage(dti);
document.getElementById('visual-income').textContent = formatCurrency(grossIncome);
document.getElementById('visual-debt').textContent = formatCurrency(monthlyDebt);
// Assessment
let assessment = '';
if (dti <= 35) {
assessment = 'Excellent - You have a healthy debt-to-income ratio.';
document.getElementById('dti-bar').style.backgroundColor = '#10b981';
} else if (dti <= 43) {
assessment = 'Good - Most lenders will approve loans with this DTI.';
document.getElementById('dti-bar').style.backgroundColor = '#f59e0b';
} else if (dti <= 50) {
assessment = 'Fair - You may qualify but could face higher rates.';
document.getElementById('dti-bar').style.backgroundColor = '#ef4444';
} else {
assessment = 'High Risk - You may have difficulty qualifying for new credit.';
document.getElementById('dti-bar').style.backgroundColor = '#dc2626';
}
document.getElementById('dti-assessment').textContent = assessment;
document.getElementById('dti-result').style.display = 'block';
document.getElementById('dti-visualization').style.display = 'block';
}
// DSR Calculator
function calculateDSR() {
const annualDebt = parseFloat(document.getElementById('annual-debt').value) || 0;
const netIncome = parseFloat(document.getElementById('net-income').value) || 0;
if (annualDebt <= 0 || netIncome <= 0) {
alert('Please enter valid values for all fields');
return;
}
const dsr = (annualDebt / netIncome) * 100;
// Display results
document.getElementById('dsr-ratio').textContent = formatPercentage(dsr);
// Update visualization
document.getElementById('dsr-bar').style.width = `${Math.min(100, dsr)}%`;
document.getElementById('dsr-bar-label').textContent = formatPercentage(dsr);
document.getElementById('visual-net-income').textContent = formatCurrency(netIncome);
document.getElementById('visual-annual-debt').textContent = formatCurrency(annualDebt);
// Assessment
let assessment = '';
if (dsr <= 20) {
assessment = 'Excellent - Very comfortable debt service coverage.';
document.getElementById('dsr-bar').style.backgroundColor = '#10b981';
} else if (dsr <= 35) {
assessment = 'Good - Manageable debt service obligations.';
document.getElementById('dsr-bar').style.backgroundColor = '#f59e0b';
} else if (dsr <= 50) {
assessment = 'Fair - Approaching high debt service levels.';
document.getElementById('dsr-bar').style.backgroundColor = '#ef4444';
} else {
assessment = 'High Risk - Debt service may be unsustainable.';
document.getElementById('dsr-bar').style.backgroundColor = '#dc2626';
}
document.getElementById('dsr-assessment').textContent = assessment;
document.getElementById('dsr-result').style.display = 'block';
document.getElementById('dsr-visualization').style.display = 'block';
}
// ROI Calculator
function calculateROI() {
const gain = parseFloat(document.getElementById('investment-gain').value) || 0;
const cost = parseFloat(document.getElementById('investment-cost').value) || 0;
if (cost <= 0) {
alert('Please enter valid values for all fields');
return;
}
const roi = ((gain - cost) / cost) * 100;
// Display results
document.getElementById('roi-percentage').textContent = formatPercentage(roi);
// Update visualization
document.getElementById('roi-circle-value').textContent = formatPercentage(roi);
document.getElementById('visual-investment-cost').textContent = formatCurrency(cost);
document.getElementById('visual-investment-gain').textContent = formatCurrency(gain);
// Set circle color based on ROI
const roiCircle = document.getElementById('roi-circle');
if (roi > 0) {
roiCircle.style.borderColor = '#10b981';
roiCircle.style.backgroundColor = '#ecfdf5';
} else if (roi < 0) {
roiCircle.style.borderColor = '#ef4444';
roiCircle.style.backgroundColor = '#fee2e2';
} else {
roiCircle.style.borderColor = '#9ca3af';
roiCircle.style.backgroundColor = '#f3f4f6';
}
// Assessment
let assessment = '';
if (roi > 0) {
assessment = 'Positive Return - Your investment is profitable.';
} else if (roi < 0) {
assessment = 'Negative Return - Your investment is losing money.';
} else {
assessment = 'Break Even - Your investment has neither gained nor lost value.';
}
document.getElementById('roi-assessment').textContent = assessment;
document.getElementById('roi-result').style.display = 'block';
document.getElementById('roi-visualization').style.display = 'block';
}
// NPV Calculator
function calculateNPV() {
const initialInvestment = parseFloat(document.getElementById('initial-investment').value) || 0;
const discountRate = parseFloat(document.getElementById('discount-rate').value) || 0;
const cashFlowsInput = document.getElementById('cash-flows').value;
if (isNaN(initialInvestment) || isNaN(discountRate) || !cashFlowsInput) {
alert('Please enter valid values for all fields');
return;
}
// Parse cash flows
const cashFlows = cashFlowsInput.split(',').map(item => {
return parseFloat(item.trim()) || 0;
});
// Calculate NPV
let npv = -initialInvestment;
const rate = discountRate / 100;
// Clear previous chart
const npvChart = document.getElementById('npv-chart');
npvChart.innerHTML = '';
// Calculate discounted cash flows and create chart bars
let maxHeight = 0;
const discountedFlows = [];
for (let i = 0; i < cashFlows.length; i++) {
const discounted = cashFlows[i] / Math.pow(1 + rate, i + 1);
discountedFlows.push(discounted);
if (Math.abs(discounted) > maxHeight) {
maxHeight = Math.abs(discounted);
}
}
// Add initial investment bar
const initialBar = document.createElement('div');
initialBar.className = 'flex flex-col items-center w-8';
const initialHeight = (Math.abs(initialInvestment) / maxHeight) * 100;
initialBar.innerHTML = `
<div class="w-full bg-red-500 rounded-t-sm" style="height: ${initialHeight}%"></div>
<div class="text-xs mt-1">Year 0</div>
<div class="text-xs">${formatCurrency(-initialInvestment)}</div>
`;
npvChart.appendChild(initialBar);
// Add cash flow bars
for (let i = 0; i < discountedFlows.length; i++) {
const discounted = discountedFlows[i];
npv += discounted;
const bar = document.createElement('div');
bar.className = 'flex flex-col items-center w-8';
const height = (Math.abs(discounted) / maxHeight) * 100;
const color = discounted >= 0 ? 'bg-green-500' : 'bg-red-500';
bar.innerHTML = `
<div class="w-full ${color} rounded-t-sm" style="height: ${height}%"></div>
<div class="text-xs mt-1">Year ${i+1}</div>
<div class="text-xs">${formatCurrency(discounted)}</div>
`;
npvChart.appendChild(bar);
}
// Display results
document.getElementById('npv-value').textContent = formatCurrency(npv);
// Assessment
let assessment = '';
if (npv > 0) {
assessment = 'Positive NPV - This investment adds value and should be considered.';
} else if (npv < 0) {
assessment = 'Negative NPV - This investment would destroy value.';
} else {
assessment = 'Break Even - The investment neither adds nor subtracts value.';
}
document.getElementById('npv-assessment').textContent = assessment;
document.getElementById('npv-result').style.display = 'block';
document.getElementById('npv-visualization').style.display = 'block';
}
</script>
</html>