Darak / front /calculator.html
Antigravity AI
Update full system to Hugging Face
771f178
Raw
History Blame Contribute Delete
17.9 kB
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dark - Amortization Terminal</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@300;400;700;900&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
term: {
bg: '#050A15',
surface: '#0A0F1E',
primary: '#F59E0B', /* Darak Gold */
accent: '#D97706'
}
},
fontFamily: { sans: ['Cairo', 'sans-serif'], mono: ['Space Mono', 'monospace'] }
}
}
}
</script>
<style>
body { margin: 0; padding: 0; overflow: hidden; background: #050A15; color: #fff; font-family: 'Cairo', sans-serif; }
/* Grid Background matching Darak identity */
.bg-grid {
position: absolute; inset: 0;
background-image:
linear-gradient(to right, rgba(245, 158, 11, 0.03) 1px, transparent 1px),
linear-gradient(to bottom, rgba(245, 158, 11, 0.03) 1px, transparent 1px);
background-size: 40px 40px;
z-index: 0; pointer-events: none;
}
.panel {
background: rgba(10, 15, 30, 0.85);
backdrop-filter: blur(10px);
border: 1px solid rgba(245, 158, 11, 0.1);
border-radius: 1rem;
box-shadow: 0 10px 30px rgba(0,0,0,0.5), inset 0 0 20px rgba(245, 158, 11, 0.05);
}
/* Terminal Sliders - Gold */
input[type=range] {
-webkit-appearance: none; width: 100%; background: transparent; margin: 10px 0;
}
input[type=range]:focus { outline: none; }
input[type=range]::-webkit-slider-runnable-track {
width: 100%; height: 4px; cursor: pointer;
background: rgba(255,255,255,0.1); border-radius: 2px;
}
input[type=range]::-webkit-slider-thumb {
height: 16px; width: 16px; border-radius: 50%;
background: #F59E0B; cursor: pointer;
-webkit-appearance: none; margin-top: -6px;
box-shadow: 0 0 15px rgba(245, 158, 11, 0.8);
transition: transform 0.2s;
}
input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.2); }
/* Custom Scrollbar - Gold */
::-webkit-scrollbar { width: 4px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #F59E0B; }
</style>
</head>
<body class="w-screen h-screen flex flex-col p-4 gap-4 relative">
<div class="bg-grid"></div>
<div class="absolute inset-0 bg-[radial-gradient(ellipse_at_center,_transparent_0%,_#050A15_100%)] z-0 pointer-events-none opacity-80"></div>
<!-- Top Nav -->
<nav class="panel w-full h-16 shrink-0 flex items-center justify-between px-6 z-10">
<div class="flex items-center gap-3 cursor-pointer" onclick="window.location.href='index.html'">
<img src="logo.png" alt="Darak Logo" class="h-10 drop-shadow-[0_0_10px_rgba(245,158,11,0.5)]">
<span class="text-sm font-black tracking-widest uppercase text-white">DARAK <span class="text-term-primary">FINANCIAL TERMINAL</span></span>
</div>
<button onclick="window.location.href='index.html'" class="text-gray-400 hover:text-term-primary transition text-sm font-bold flex items-center gap-2">
العودة للرئيسية <i class="fa-solid fa-arrow-left"></i>
</button>
</nav>
<!-- Main Container -->
<main class="flex-1 flex gap-4 z-10 overflow-hidden">
<!-- LEFT: INPUT PANEL -->
<div class="w-[350px] shrink-0 panel flex flex-col p-6 overflow-y-auto">
<div class="border-b border-term-primary/20 pb-4 mb-6">
<h2 class="text-xs tracking-widest font-bold text-gray-400 uppercase"><i class="fa-solid fa-sliders text-term-primary ml-1"></i> متغيرات القرض</h2>
</div>
<div class="space-y-8 flex-1">
<!-- Price -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-xs text-gray-400 font-bold uppercase">سعر العقار</label>
<div class="text-lg font-black text-term-primary"><span id="val-price">10,000,000</span> <span class="text-[10px] text-gray-500">ج.م</span></div>
</div>
<input type="range" id="slider-price" min="500000" max="50000000" step="100000" value="10000000">
</div>
<!-- Down Payment -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-xs text-gray-400 font-bold uppercase">المقدم (<span id="val-dp-pct" class="text-white">20</span>%)</label>
<div class="text-base font-bold text-gray-300"><span id="val-dp-amt">2,000,000</span> <span class="text-[10px] text-gray-500">ج.م</span></div>
</div>
<input type="range" id="slider-dp" min="0" max="80" step="1" value="20">
</div>
<!-- Years -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-xs text-gray-400 font-bold uppercase">مدة التقسيط</label>
<div class="text-lg font-black text-white"><span id="val-years">10</span> <span class="text-[10px] text-gray-500">سنوات</span></div>
</div>
<input type="range" id="slider-years" min="1" max="30" step="1" value="10">
</div>
<!-- Interest Rate -->
<div>
<div class="flex justify-between items-end mb-2">
<label class="text-xs text-gray-400 font-bold uppercase">الفائدة السنوية</label>
<div class="text-lg font-black text-white"><span id="val-rate">12</span> <span class="text-[10px] text-gray-500">%</span></div>
</div>
<input type="range" id="slider-rate" min="0" max="30" step="0.5" value="12">
</div>
</div>
<!-- Big Monthly Payment Display -->
<div class="mt-8 p-6 bg-black/40 border border-term-primary/30 rounded-xl relative overflow-hidden text-center">
<div class="absolute -top-10 -right-10 w-32 h-32 bg-term-primary/20 blur-[40px]"></div>
<div class="text-xs text-gray-400 uppercase tracking-widest font-bold mb-2">القسط الشهري المتوقع</div>
<div class="text-4xl font-black text-white font-mono drop-shadow-[0_0_15px_rgba(245,158,11,0.5)]" id="val-monthly">0</div>
<div class="text-[10px] text-term-primary mt-1 font-mono">جنيه / شهر</div>
</div>
<button onclick="window.location.href='onboarding.html'" class="w-full mt-4 bg-term-primary/10 hover:bg-term-primary text-term-primary hover:text-black border border-term-primary transition-all duration-300 py-3 rounded-lg font-bold text-sm uppercase tracking-wider">
ابحث عن عقار بهذه الميزانية
</button>
</div>
<!-- RIGHT: CHART PANEL -->
<div class="flex-1 panel flex flex-col p-6 overflow-hidden">
<!-- Quick Stats Header -->
<div class="grid grid-cols-3 gap-4 mb-6 border-b border-white/5 pb-6 text-center">
<div class="bg-black/30 p-4 rounded-xl border border-white/5">
<div class="text-[10px] text-gray-500 font-bold uppercase tracking-widest mb-1">أصل مبلغ القرض</div>
<div class="text-xl font-bold text-white font-mono" id="stat-principal">0 <span class="text-xs text-gray-500">ج.م</span></div>
</div>
<div class="bg-black/30 p-4 rounded-xl border border-white/5">
<div class="text-[10px] text-gray-500 font-bold uppercase tracking-widest mb-1">إجمالي الفوائد</div>
<div class="text-xl font-bold text-white font-mono" id="stat-interest">0 <span class="text-xs text-gray-500">ج.م</span></div>
</div>
<div class="bg-term-primary/10 p-4 rounded-xl border border-term-primary/30 shadow-[0_0_15px_rgba(245,158,11,0.1)]">
<div class="text-[10px] text-term-primary font-bold uppercase tracking-widest mb-1">إجمالي التكلفة</div>
<div class="text-xl font-black text-term-primary font-mono" id="stat-total">0 <span class="text-xs text-term-primary/60">ج.م</span></div>
</div>
</div>
<div class="flex items-center justify-between mb-4">
<h2 class="text-sm tracking-widest font-bold text-white uppercase"><i class="fa-solid fa-chart-line text-term-primary ml-1"></i> جدول الإهلاك الزمني</h2>
<div class="flex gap-4 text-xs font-mono">
<span class="flex items-center gap-2"><span class="w-3 h-3 rounded bg-[#F59E0B]"></span> الرصيد المتبقي</span>
<span class="flex items-center gap-2"><span class="w-3 h-3 rounded bg-[#4ade80]"></span> الفوائد المتراكمة</span>
</div>
</div>
<!-- Massive Area Chart -->
<div class="flex-1 relative w-full h-full">
<canvas id="amortizationChart"></canvas>
</div>
</div>
</main>
<script>
// Formatting helper
const formatCurrency = (num) => new Intl.NumberFormat('en-US').format(Math.round(num));
// DOM Elements
const sliderPrice = document.getElementById('slider-price');
const sliderDp = document.getElementById('slider-dp');
const sliderYears = document.getElementById('slider-years');
const sliderRate = document.getElementById('slider-rate');
// Chart Instance
let amortizationChart = null;
function initChart() {
const ctx = document.getElementById('amortizationChart').getContext('2d');
Chart.defaults.color = '#94a3b8';
Chart.defaults.font.family = 'Space Mono';
amortizationChart = new Chart(ctx, {
type: 'line',
data: {
labels: [], // Years
datasets: [
{
label: 'الرصيد المتبقي',
data: [],
borderColor: '#F59E0B',
backgroundColor: 'rgba(245, 158, 11, 0.1)',
borderWidth: 2,
fill: true,
pointRadius: 0,
pointHoverRadius: 6,
tension: 0.4
},
{
label: 'الفوائد المتراكمة',
data: [],
borderColor: '#4ade80',
backgroundColor: 'rgba(74, 222, 128, 0.1)',
borderWidth: 2,
fill: true,
pointRadius: 0,
pointHoverRadius: 6,
tension: 0.4
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false },
plugins: {
legend: { display: false },
tooltip: {
backgroundColor: 'rgba(10, 15, 30, 0.95)',
titleColor: '#fff',
bodyColor: '#fff',
titleFont: { family: 'Cairo' },
bodyFont: { family: 'Space Mono' },
borderColor: 'rgba(245,158,11,0.3)',
borderWidth: 1,
padding: 12,
textDirection: 'rtl',
callbacks: {
label: function(context) {
return ' ' + context.dataset.label + ': ' + formatCurrency(context.raw) + ' ج.م';
}
}
}
},
scales: {
x: {
grid: { color: 'rgba(255,255,255,0.03)' },
ticks: { font: { family: 'Cairo' } }
},
y: {
grid: { color: 'rgba(255,255,255,0.03)' },
position: 'right', // Put Y axis on right for RTL
ticks: { callback: function(value) { return formatCurrency(value); } }
}
}
}
});
}
function calculateAmortization() {
// Get Values
const price = parseFloat(sliderPrice.value);
const dpPct = parseFloat(sliderDp.value);
const years = parseFloat(sliderYears.value);
const annualRate = parseFloat(sliderRate.value);
// Basic Math
const dpAmt = price * (dpPct / 100);
const principal = price - dpAmt;
const monthlyRate = (annualRate / 100) / 12;
const totalMonths = years * 12;
let monthlyPayment = 0;
if (annualRate > 0) {
monthlyPayment = principal * (monthlyRate * Math.pow(1 + monthlyRate, totalMonths)) / (Math.pow(1 + monthlyRate, totalMonths) - 1);
} else {
monthlyPayment = principal / totalMonths;
}
if(isNaN(monthlyPayment) || !isFinite(monthlyPayment)) monthlyPayment = 0;
// Update UI Inputs
document.getElementById('val-price').innerText = formatCurrency(price);
document.getElementById('val-dp-pct').innerText = dpPct;
document.getElementById('val-dp-amt').innerText = formatCurrency(dpAmt);
document.getElementById('val-years').innerText = years;
document.getElementById('val-rate').innerText = annualRate;
document.getElementById('val-monthly').innerText = formatCurrency(monthlyPayment);
// Generate Amortization Schedule for Chart
let currentPrincipal = principal;
let accInterest = 0;
const labels = [];
const principalData = [];
const interestData = [];
// Add Year 0
labels.push('السنة 0');
principalData.push(currentPrincipal);
interestData.push(0);
for (let m = 1; m <= totalMonths; m++) {
let interestPayment = currentPrincipal * monthlyRate;
let principalPayment = monthlyPayment - interestPayment;
if (annualRate === 0) {
interestPayment = 0;
principalPayment = monthlyPayment;
}
accInterest += interestPayment;
currentPrincipal -= principalPayment;
if (currentPrincipal < 0) currentPrincipal = 0;
// Save data point every 12 months (or last month)
if (m % 12 === 0 || m === totalMonths) {
labels.push('السنة ' + (m/12));
principalData.push(currentPrincipal);
interestData.push(accInterest);
}
}
// Update Top Stats
document.getElementById('stat-principal').innerHTML = formatCurrency(principal) + ' <span class="text-xs text-gray-500">ج.م</span>';
document.getElementById('stat-interest').innerHTML = formatCurrency(accInterest) + ' <span class="text-xs text-gray-500">ج.م</span>';
document.getElementById('stat-total').innerHTML = formatCurrency(principal + accInterest + dpAmt) + ' <span class="text-xs text-term-primary/60">ج.م</span>';
// Update Chart
amortizationChart.data.labels = labels;
amortizationChart.data.datasets[0].data = principalData; // Remaining Principal
amortizationChart.data.datasets[1].data = interestData; // Accumulated Interest
amortizationChart.update();
}
// Setup Event Listeners
[sliderPrice, sliderDp, sliderYears, sliderRate].forEach(slider => {
slider.addEventListener('input', calculateAmortization);
});
// Init
document.addEventListener('DOMContentLoaded', () => {
initChart();
calculateAmortization();
});
</script>
</body>
</html>