anycoder-b738a38b / index.html
defaultdolphin's picture
Upload folder using huggingface_hub
96fe1b5 verified
Raw History Blame Contribute Delete
43.7 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mortgage Leads & Expense Manager</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> :root { --primary: #2563eb; --primary-dark: #1d4ed8; --secondary: #7c3aed; --success: #10b981; --warning: #f59e0b; --danger: #ef4444; --dark: #1e293b; --light: #f8fafc; --gray: #64748b; --white: #ffffff; --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); --gradient: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; } body { background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%); min-height: 100vh; color: var(--white); overflow-x: hidden; } /* Background Pattern */ body::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(circle at 20% 80%, rgba(37, 99, 235, 0.1) 0%, transparent 50%), radial-gradient(circle at 80% 20%, rgba(124, 58, 237, 0.1) 0%, transparent 50%); pointer-events: none; z-index: -1; } /* Header */ header { background: rgba(30, 41, 59, 0.8); backdrop-filter: blur(20px); border-bottom: 1px solid rgba(255, 255, 255, 0.1); padding: 1rem 2rem; position: sticky; top: 0; z-index: 100; } .header-content { max-width: 1400px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; } .logo { display: flex; align-items: center; gap: 0.75rem; } .logo-icon { width: 42px; height: 42px; background: var(--gradient); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; box-shadow: var(--shadow); } .logo h1 { font-size: 1.5rem; font-weight: 700; background: var(--gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .header-links { display: flex; gap: 1.5rem; align-items: center; } .header-links a { color: var(--gray); text-decoration: none; font-weight: 500; transition: color 0.3s; } .header-links a:hover { color: var(--white); } .anycoder-link { background: rgba(255, 255, 255, 0.1); padding: 0.5rem 1rem; border-radius: 8px; font-size: 0.875rem; color: var(--gray); text-decoration: none; transition: all 0.3s; } .anycoder-link:hover { background: var(--primary); color: var(--white); } /* Main Container */ .container { max-width: 1400px; margin: 0 auto; padding: 2rem; } /* Stats Cards */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; } .stat-card { background: rgba(30, 41, 59, 0.6); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 16px; padding: 1.5rem; transition: transform 0.3s, box-shadow 0.3s; } .stat-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); } .stat-card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; } .stat-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 1.25rem; } .stat-icon.blue { background: rgba(37, 99, 235, 0.2); color: #3b82f6; } .stat-icon.green { background: rgba(16, 185, 129, 0.2); color: #10b981; } .stat-icon.purple { background: rgba(124, 58, 237, 0.2); color: #8b5cf6; } .stat-icon.orange { background: rgba(245, 158, 11, 0.2); color: #f59e0b; } .stat-trend { font-size: 0.875rem; padding: 0.25rem 0.5rem; border-radius: 6px; } .stat-trend.up { background: rgba(16, 185, 129, 0.2); color: #10b981; } .stat-trend.down { background: rgba(239, 68, 68, 0.2); color: #ef4444; } .stat-value { font-size: 2rem; font-weight: 700; margin-bottom: 0.25rem; } .stat-label { color: var(--gray); font-size: 0.875rem; } /* Main Grid */ .main-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; } @media (max-width: 1024px) { .main-grid { grid-template-columns: 1fr; } } /* Cards */ .card { background: rgba(30, 41, 59, 0.6); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 16px; overflow: hidden; } .card-header { padding: 1.25rem 1.5rem; border-bottom: 1px solid rgba(255, 255, 255, 0.1); display: flex; justify-content: space-between; align-items: center; } .card-title { font-size: 1.125rem; font-weight: 600; display: flex; align-items: center; gap: 0.75rem; } .card-title i { color: var(--primary); } .card-body { padding: 1.5rem; } /* Tabs */ .tabs { display: flex; gap: 0.5rem; padding: 0.5rem; background: rgba(0, 0, 0, 0.2); border-radius: 10px; margin-bottom: 1.5rem; } .tab { flex: 1; padding: 0.75rem 1rem; border: none; background: transparent; color: var(--gray); font-size: 0.875rem; font-weight: 500; border-radius: 8px; cursor: pointer; transition: all 0.3s; } .tab.active { background: var(--gradient); color: var(--white); } .tab:hover:not(.active) { color: var(--white); } /* Forms */ .form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; } @media (max-width: 600px) { .form-grid { grid-template-columns: 1fr; } } .form-group { margin-bottom: 1rem; } .form-group.full-width { grid-column: 1 / -1; } .form-label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.5rem; color: var(--gray); } .form-input, .form-select { width: 100%; padding: 0.75rem 1rem; background: rgba(0, 0, 0, 0.2); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 10px; color: var(--white); font-size: 0.9rem; transition: border-color 0.3s, box-shadow 0.3s; } .form-input:focus, .form-select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); } .form-input::placeholder { color: var(--gray); } .form-select option { background: var(--dark); } /* Buttons */ .btn { padding: 0.75rem 1.5rem; border: none; border-radius: 10px; font-size: 0.9rem; font-weight: 600; cursor: pointer; transition: all 0.3s; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; } .btn-primary { background: var(--gradient); color: var(--white); box-shadow: var(--shadow); } .btn-primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); } .btn-secondary { background: rgba(255, 255, 255, 0.1); color: var(--white); } .btn-secondary:hover { background: rgba(255, 255, 255, 0.2); } .btn-danger { background: rgba(239, 68, 68, 0.2); color: #ef4444; } .btn-danger:hover { background: #ef4444; color: var(--white); } .btn-group { display: flex; gap: 0.75rem; margin-top: 1.5rem; } /* Expense Table */ .expense-table { width: 100%; border-collapse: collapse; } .expense-table th, .expense-table td { padding: 1rem; text-align: left; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .expense-table th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--gray); font-weight: 600; } .expense-table td { font-size: 0.9rem; } .expense-table tbody tr { transition: background 0.2s; } .expense-table tbody tr:hover { background: rgba(255, 255, 255, 0.05); } .expense-category { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0.75rem; border-radius: 6px; font-size: 0.8rem; font-weight: 500; } .expense-category.mortgage { background: rgba(37, 99, 235, 0.2); color: #3b82f6; } .expense-category.taxes { background: rgba(124, 58, 237, 0.2); color: #8b5cf6; } .expense-category.insurance { background: rgba(16, 185, 129, 0.2); color: #10b981; } .expense-category.maintenance { background: rgba(245, 158, 11, 0.2); color: #f59e0b; } .expense-category.utilities { background: rgba(236, 72, 153, 0.2); color: #ec4899; } .status-badge { padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.75rem; font-weight: 600; } .status-badge.new { background: rgba(37, 99, 235, 0.2); color: #3b82f6; } .status-badge.contacted { background: rgba(245, 158, 11, 0.2); color: #f59e0b; } .status-badge.qualified { background: rgba(16, 185, 129, 0.2); color: #10b981; } .status-badge.closed { background: rgba(124, 58, 237, 0.2); color: #8b5cf6; } /* Calculator Result */ .calculator-result { background: rgba(0, 0, 0, 0.3); border-radius: 12px; padding: 1.5rem; margin-top: 1.5rem; } .result-row { display: flex; justify-content: space-between; align-items: center; padding: 0.75rem 0; border-bottom: 1px solid rgba(255, 255, 255, 0.05); } .result-row:last-child { border-bottom: none; } .result-label { color: var(--gray); font-size: 0.9rem; } .result-value { font-weight: 600; font-size: 1.1rem; } .result-value.highlight { color: var(--success); font-size: 1.5rem; } /* Lead List */ .lead-list { max-height: 400px; overflow-y: auto; } .lead-item { display: flex; align-items: center; gap: 1rem; padding: 1rem; background: rgba(0, 0, 0, 0.2); border-radius: 10px; margin-bottom: 0.75rem; transition: all 0.3s; } .lead-item:hover { background: rgba(0, 0, 0, 0.3); } .lead-avatar { width: 44px; height: 44px; border-radius: 10px; background: var(--gradient); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 1rem; flex-shrink: 0; } .lead-info { flex: 1; min-width: 0; } .lead-name { font-weight: 600; margin-bottom: 0.25rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .lead-detail { font-size: 0.8rem; color: var(--gray); } .lead-actions { display: flex; gap: 0.5rem; } .lead-actions button { width: 32px; height: 32px; border: none; border-radius: 8px; cursor: pointer; transition: all 0.3s; display: flex; align-items: center; justify-content: center; } .lead-actions .view-btn { background: rgba(37, 99, 235, 0.2); color: #3b82f6; } .lead-actions .delete-btn { background: rgba(239, 68, 68, 0.2); color: #ef4444; } .lead-actions button:hover { transform: scale(1.1); } /* Chart Placeholder */ .chart-container { height: 200px; display: flex; align-items: flex-end; gap: 0.5rem; padding: 1rem 0; } .chart-bar { flex: 1; background: var(--gradient); border-radius: 6px 6px 0 0; transition: height 0.5s ease; position: relative; } .chart-bar::after { content: attr(data-label); position: absolute; bottom: -25px; left: 50%; transform: translateX(-50%); font-size: 0.7rem; color: var(--gray); white-space: nowrap; } /* Empty State */ .empty-state { text-align: center; padding: 3rem; color: var(--gray); } .empty-state i { font-size: 3rem; margin-bottom: 1rem; opacity: 0.5; } /* Animations */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } .fade-in { animation: fadeIn 0.4s ease forwards; } /* Modal */ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); backdrop-filter: blur(4px); display: none; align-items: center; justify-content: center; z-index: 1000; padding: 1rem; } .modal-overlay.active { display: flex; } .modal { background: var(--dark); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 16px; max-width: 500px; width: 100%; max-height: 90vh; overflow-y: auto; animation: fadeIn 0.3s ease; } .modal-header { padding: 1.25rem 1.5rem; border-bottom: 1px solid rgba(255, 255, 255, 0.1); display: flex; justify-content: space-between; align-items: center; } .modal-header h3 { font-size: 1.125rem; } .modal-close { width: 32px; height: 32px; border: none; background: rgba(255, 255, 255, 0.1); color: var(--white); border-radius: 8px; cursor: pointer; transition: background 0.3s; } .modal-close:hover { background: rgba(239, 68, 68, 0.5); } .modal-body { padding: 1.5rem; } /* Scrollbar */ ::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.2); border-radius: 4px; } ::-webkit-scrollbar-thumb { background: var(--gray); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--primary); } /* Responsive */ @media (max-width: 768px) { .header-content { flex-direction: column; text-align: center; } .header-links { width: 100%; justify-content: center; flex-wrap: wrap; } .container { padding: 1rem; } .stats-grid { grid-template-columns: 1fr 1fr; } .stat-card { padding: 1rem; } .stat-value { font-size: 1.5rem; } .btn-group { flex-direction: column; } .lead-item { flex-wrap: wrap; } } @media (max-width: 480px) { .stats-grid { grid-template-columns: 1fr; } .tabs { flex-direction: column; } .form-grid { grid-template-columns: 1fr; } } </style> </head> <body> <header> <div class="header-content"> <div class="logo"> <div class="logo-icon"> <i class="fas fa-home"></i> </div> <h1>MortgageHub</h1> </div> <div class="header-links"> <a href="#" onclick="showTab('leads')"><i class="fas fa-users"></i> Leads</a> <a href="#" onclick="showTab('expenses')"><i class="fas fa-calculator"></i> Expenses</a> <a href="#" onclick="showTab('calculator')"><i class="fas fa-chart-line"></i> Calculator</a> <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link"> <i class="fas fa-code"></i> Built with anycoder </a> </div> </div> </header> <div class="container"> <!-- Stats Grid --> <div class="stats-grid"> <div class="stat-card"> <div class="stat-card-header"> <div class="stat-icon blue"> <i class="fas fa-users"></i> </div> <span class="stat-trend up"><i class="fas fa-arrow-up"></i> 12%</span> </div> <div class="stat-value" id="totalLeads">0</div> <div class="stat-label">Total Leads</div> </div> <div class="stat-card"> <div class="stat-card-header"> <div class="stat-icon green"> <i class="fas fa-check-circle"></i> </div> <span class="stat-trend up"><i class="fas fa-arrow-up"></i> 8%</span> </div> <div class="stat-value" id="qualifiedLeads">0</div> <div class="stat-label">Qualified Leads</div> </div> <div class="stat-card"> <div class="stat-card-header"> <div class="stat-icon purple"> <i class="fas fa-dollar-sign"></i> </div> </div> <div class="stat-value" id="totalExpenses">$0</div> <div class="stat-label">Total Monthly Expenses</div> </div> <div class="stat-card"> <div class="stat-card-header"> <div class="stat-icon orange"> <i class="fas fa-file-invoice-dollar"></i> </div> </div> <div class="stat-value" id="avgMortgage">$0</div> <div class="stat-label">Avg. Mortgage Payment</div> </div> </div> <!-- Main Grid --> <div class="main-grid"> <!-- Lead Generation Form --> <div class="card"> <div class="card-header"> <h2 class="card-title"> <i class="fas fa-user-plus"></i> Generate New Lead </h2> </div> <div class="card-body"> <form id="leadForm"> <div class="form-grid"> <div class="form-group"> <label class="form-label">Full Name</label> <input type="text" class="form-input" id="leadName" placeholder="John Doe" required> </div> <div class="form-group"> <label class="form-label">Email Address</label> <input type="email" class="form-input" id="leadEmail" placeholder="john@example.com" required> </div> <div class="form-group"> <label class="form-label">Phone Number</label> <input type="tel" class="form-input" id="leadPhone" placeholder="(555) 123-4567" required> </div> <div class="form-group"> <label class="form-label">Property Type</label> <select class="form-select" id="leadPropertyType"> <option value="single-family">Single Family Home</option> <option value="condo">Condo</option> <option value="townhouse">Townhouse</option> <option value="multi-family">Multi-Family</option> <option value="commercial">Commercial</option> </select> </div> <div class="form-group"> <label class="form-label">Loan Amount Needed</label> <input type="number" class="form-input" id="leadLoanAmount" placeholder="250000" required> </div> <div class="form-group"> <label class="form-label">Property Value</label> <input type="number" class="form-input" id="leadPropertyValue" placeholder="350000" required> </div> <div class="form-group"> <label class="form-label">Annual Income</label> <input type="number" class="form-input" id="leadIncome" placeholder="75000" required> </div> <div class="form-group"> <label class="form-label">Credit Score</label> <select class="form-select" id="leadCreditScore"> <option value="excellent">Excellent (750+)</option> <option value="good">Good (700-749)</option> <option value="fair">Fair (650-699)</option> <option value="poor">Poor (<650)</option> </select> </div> </div> <div class="btn-group"> <button type="submit" class="btn btn-primary"> <i class="fas fa-plus-circle"></i> Generate Lead </button> <button type="reset" class="btn btn-secondary"> <i class="fas fa-redo"></i> Reset </button> </div> </form> </div> </div> <!-- Expense Tracker --> <div class="card"> <div class="card-header"> <h2 class="card-title"> <i class="fas fa-wallet"></i> Expense Tracker </h2> <button class="btn btn-primary" onclick="openExpenseModal()"> <i class="fas fa-plus"></i> Add Expense </button> </div> <div class="card-body"> <div class="tabs"> <button class="tab active" onclick="filterExpenses('all')">All</button> <button class="tab" onclick="filterExpenses('mortgage')">Mortgage</button> <button class="tab" onclick="filterExpenses('taxes')">Taxes</button> <button class="tab" onclick="filterExpenses('insurance')">Insurance</button> </div> <div id="expenseList"> <table class="expense-table"> <thead> <tr> <th>Description</th> <th>Category</th> <th>Amount</th> <th>Due Date</th> <th>Actions</th> </tr> </thead> <tbody id="expenseTableBody"> <!-- Expenses will be added here --> </tbody> </table> <div class="empty-state" id="expenseEmptyState"> <i class="fas fa-receipt"></i> <p>No expenses added yet</p> </div> </div> </div> </div> </div> <!-- Leads List --> <div class="card" style="margin-top: 1.5rem;"> <div class="card-header"> <h2 class="card-title"> <i class="fas fa-list"></i> Recent Leads </h2> <div> <button class="btn btn-secondary" onclick="exportLeads()"> <i class="fas fa-download"></i> Export </button> </div> </div> <div class="card-body"> <div class="lead-list" id="leadList"> <div class="empty-state" id="leadEmptyState"> <i class="fas fa-user-friends"></i> <p>No leads generated yet</p> </div> </div> </div> </div> <!-- Mortgage Calculator --> <div class="card" style="margin-top: 1.5rem;"> <div class="card-header"> <h2 class="card-title"> <i class="fas fa-calculator"></i> Mortgage Calculator </h2> </div> <div class="card-body"> <div class="form-grid"> <div class="form-group"> <label class="form-label">Home Price ($)</label> <input type="number" class="form-input" id="calcHomePrice" value="350000" oninput="calculateMortgage()"> </div> <div class="form-group"> <label class="form-label">Down Payment ($)</label> <input type="number" class="form-input" id="calcDownPayment" value="70000" oninput="calculateMortgage()"> </div> <div class="form-group"> <label class="form-label">Interest Rate (%)</label> <input type="number" class="form-input" id="calcInterestRate" value="6.5" step="0.1" oninput="calculateMortgage()"> </div> <div class="form-group"> <label class="form-label">Loan Term (Years)</label> <select class="form-select" id="calcLoanTerm" onchange="calculateMortgage()"> <option value="15">15 Years</option> <option value="20">20 Years</option> <option value="30" selected>30 Years</option> </select> </div> </div> <div class="calculator-result" id="calcResult"> <div class="result-row"> <span class="result-label">Loan Amount</span> <span class="result-value" id="resultLoanAmount">$280,000</span> </div> <div class="result-row"> <span class="result-label">Monthly Principal & Interest</span> <span class="result-value highlight" id="resultMonthlyPayment">$1,772</span> </div> <div class="result-row"> <span class="result-label">Total Interest Paid</span> <span class="result-value" id="resultTotalInterest">$357,920</span> </div> <div class="result-row"> <span class="result-label">Total Amount Paid</span> <span class="result-value" id="resultTotalAmount">$637,920</span> </div> </div> </div> </div> </div> <!-- Expense Modal --> <div class="modal-overlay" id="expenseModal"> <div class="modal"> <div class="modal-header"> <h3>Add New Expense</h3> <button class="modal-close" onclick="closeExpenseModal()"> <i class="fas fa-times"></i> </button> </div> <div class="modal-body"> <form id="expenseForm"> <div class="form-group"> <label class="form-label">Description</label> <input type="text" class="form-input" id="expenseDescription" placeholder="Monthly mortgage payment" required> </div> <div class="form-group"> <label class="form-label">Category</label> <select class="form-select" id="expenseCategory"> <option value="mortgage">Mortgage</option> <option value="taxes">Property Taxes</option> <option value="insurance">Home Insurance</option> <option value="maintenance">Maintenance</option> <option value="utilities">Utilities</option> </select> </div> <div class="form-group"> <label class="form-label">Amount ($)</label> <input type="number" class="form-input" id="expenseAmount" placeholder="1500" required> </div> <div class="form-group"> <label class="form-label">Due Date</label> <input type="date" class="form-input" id="expenseDueDate" required> </div> <div class="btn-group"> <button type="submit" class="btn btn-primary" style="width: 100%;"> <i class="fas fa-plus"></i> Add Expense </button> </div> </form> </div> </div> </div> <script> // Data Storage let leads = []; let expenses = []; let expenseFilter = 'all'; // Initialize document.addEventListener('DOMContentLoaded', () => { loadFromStorage(); updateStats(); renderLeads(); renderExpenses(); calculateMortgage(); // Set default date to today document.getElementById('expenseDueDate').valueAsDate = new Date(); }); // Storage Functions function saveToStorage() { localStorage.setItem('mortgageLeads', JSON.stringify(leads)); localStorage.setItem('mortgageExpenses', JSON.stringify(expenses)); } function loadFromStorage() { const storedLeads = localStorage.getItem('mortgageLeads'); const storedExpenses = localStorage.getItem('mortgageExpenses'); if (storedLeads) leads = JSON.parse(storedLeads); if (storedExpenses) expenses = JSON.parse(storedExpenses); } // Lead Form Handler document.getElementById('leadForm').addEventListener('submit', (e) => { e.preventDefault(); const lead = { id: Date.now(), name: document.getElementById('leadName').value, email: document.getElementById('leadEmail').value, phone: document.getElementById('leadPhone').value, propertyType: document.getElementById('leadPropertyType').value, loanAmount: parseFloat(document.getElementById('leadLoanAmount').value), propertyValue: parseFloat(document.getElementById('leadPropertyValue').value), income: parseFloat(document.getElementById('leadIncome').value), creditScore: document.getElementById('leadCreditScore').value, status: 'new', date: new Date().toLocaleDateString() }; // Calculate LTV and DTI lead.ltv = (lead.loanAmount / lead.propertyValue * 100).toFixed(1); lead.dti = ((lead.loanAmount * 0.04) / (lead.income / 12) * 100).toFixed(1); // Estimated leads.unshift(lead); saveToStorage(); updateStats(); renderLeads(); // Auto-add estimated mortgage as expense const estimatedPayment = (lead.loanAmount * 0.005).toFixed(0); // Rough estimate if (confirm(`Lead added! Would you like to add estimated monthly mortgage payment ($${estimatedPayment}) as an expense?`)) { addExpense({ description: `Mortgage - ${lead.name}`, category: 'mortgage', amount: parseFloat(estimatedPayment), dueDate: new Date().toISOString().split('T')[0] }); } e.target.reset(); }); // Expense Form Handler document.getElementById('expenseForm').addEventListener('submit', (e) => { e.preventDefault(); const expense = { id: Date.now(), description: document.getElementById('expenseDescription').value, category: document.getElementById('expenseCategory').value, amount: parseFloat(document.getElementById('expenseAmount').value), dueDate: document.getElementById('expenseDueDate').value, date: new Date().toLocaleDateString() }; addExpense(expense); closeExpenseModal(); e.target.reset(); }); function addExpense(expense) { expenses.unshift(expense); saveToStorage(); updateStats(); renderExpenses(); } // Render Leads function renderLeads() { const container = document.getElementById('leadList'); const emptyState = document.getElementById('leadEmptyState'); if (leads.length === 0) { container.innerHTML = ''; container.appendChild(emptyState); emptyState.style.display = 'block'; return; } emptyState.style.display = 'none'; container.innerHTML = leads.map((lead, index) => ` <div class="lead-item fade-in" style="animation-delay: ${index * 0.05}s"> <div class="lead-avatar">${lead.name.split(' ').map(n => n[0]).join('')}</div> <div class="lead-info"> <div class="lead-name">${lead.name}</div> <div class="lead-detail"> <i class="fas fa-phone"></i> ${lead.phone} | <i class="fas fa-home"></i> ${lead.propertyType} | <i class="fas fa-dollar-sign"></i> $${lead.loanAmount.toLocaleString()} </div> <div class="lead-detail"> <span class="status-badge ${lead.status}">${lead.status.toUpperCase()}</span> <span style="margin-left: 0.5rem; color: var(--gray);">LTV: ${lead.ltv}% | DTI: ${lead.dti}%</span> </div> </div> <div class="lead-actions"> <button class="view-btn" onclick="viewLead(${lead.id})" title="View Details"> <i class="fas fa-eye"></i> </button> <button class="delete-btn" onclick="deleteLead(${lead.id})" title="Delete"> <i class="fas fa-trash"></i> </button> </div> </div> `).join(''); } // Render Expenses function renderExpenses() { const tbody = document.getElementById('expenseTableBody'); const emptyState = document.getElementById('expenseEmptyState'); let filteredExpenses = expenseFilter === 'all' ? expenses : expenses.filter(e => e.category === expenseFilter); if (filteredExpenses.length === 0) { tbody.innerHTML = ''; emptyState.style.display = 'block'; return; } emptyState.style.display = 'none'; tbody.innerHTML = filteredExpenses.map(expense => ` <tr class="fade-in"> <td>${expense.description}</td> <td><span class="expense-category ${expense.category}">${expense.category}</span></td> <td>$${expense.amount.toLocaleString()}</td> <td>${new Date(expense.dueDate).toLocaleDateString()}</td> <td> <button class="btn btn-danger" style="padding: 0.25rem 0.5rem; font-size: 0.75rem;" onclick="deleteExpense(${expense.id})"> <i class="fas fa-trash"></i> </button> </td> </tr> `).join(''); } // Filter Expenses function filterExpenses(category) { expenseFilter = category; document.querySelectorAll('.tabs .tab').forEach(tab => { tab.classList.remove('active'); if (tab.textContent.toLowerCase().includes(category) || (category === 'all' && tab.textContent === 'All')) { tab.classList.add('active'); } }); renderExpenses(); } // Update Stats function updateStats() { document.getElementById('totalLeads').textContent = leads.length; document.getElementById('qualifiedLeads').textContent = leads.filter(l => l.status === 'qualified' || l.status === 'closed').length; const totalExpenses = expenses.reduce((sum, e) => sum + e.amount, 0); document.getElementById('totalExpenses').textContent = '$' + totalExpenses.toLocaleString(); const mortgageExpenses = expenses.filter(e => e.category === 'mortgage'); const avgMortgage = mortgageExpenses.length > 0 ? mortgageExpenses.reduce((sum, e) => sum + e.amount, 0) / mortgageExpenses.length : 0; document.getElementById('avgMortgage').textContent = '$' + Math.round(avgMortgage).toLocaleString(); } // Mortgage Calculator function calculateMortgage() { const homePrice = parseFloat(document.getElementById('calcHomePrice').value) || 0; const downPayment = parseFloat(document.getElementById('calcDownPayment').value) || 0; const interestRate = parseFloat(document.getElementById('calcInterestRate').value) || 0; const loanTerm = parseInt(document.getElementById('calcLoanTerm').value) || 30; const loanAmount = homePrice - downPayment; const monthlyRate = interestRate / 100 / 12; const numPayments = loanTerm * 12; let monthlyPayment; if (monthlyRate === 0) { monthlyPayment = loanAmount / numPayments; } else { monthlyPayment = loanAmount * (monthlyRate * Math.pow(1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mortgage Leads & Expense Manager</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #2563eb;
--primary-dark: #1d4ed8;
--secondary: #7c3aed;
--success: #10b981;
--warning: #f59e0b;
--danger: #ef4444;
--dark: #1e293b;
--light: #f8fafc;
--gray: #64748b;
--white: #ffffff;
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--gradient: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
}
body {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
min-height: 100vh;
color: var(--white);
overflow-x: hidden;
}
/* Background Pattern */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 80%, rgba(37, 99, 235, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 20%, rgba(124, 58, 237, 0.1) 0%, transparent 50%);
pointer-events: none;
z-index: -1;
}
/* Header */
header {
background: rgba(30, 41, 59, 0.8);
backdrop-filter: blur(20px);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
padding: 1rem 2rem;
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
max-width: 1400px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 1rem;
}
.logo {
display: flex;
align-items: center;
gap: 0.75rem;
}
.logo-icon {
width: 42px;
height: 42px;
background: var(--gradient);
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25rem;
box-shadow: var(--shadow);
}
.logo h1 {
font-size: 1.5rem;
font-weight: 700;
background: var(--gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}