| <!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; |
| } |
| |
| |
| 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 { |
| 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); |
| } |
| |
| |
| .container { |
| max-width: 1400px; |
| margin: 0 auto; |
| padding: 2rem; |
| } |
| |
| |
| .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 { |
| display: grid; |
| grid-template-columns: 1fr 1fr; |
| gap: 1.5rem; |
| } |
| |
| @media (max-width: 1024px) { |
| .main-grid { |
| grid-template-columns: 1fr; |
| } |
| } |
| |
| |
| .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 { |
| 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); |
| } |
| |
| |
| .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); |
| } |
| |
| |
| .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 { |
| 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 { |
| 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 { |
| 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-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 { |
| text-align: center; |
| padding: 3rem; |
| color: var(--gray); |
| } |
| |
| .empty-state i { |
| font-size: 3rem; |
| margin-bottom: 1rem; |
| opacity: 0.5; |
| } |
| |
| |
| @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-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; |
| } |
| |
| |
| ::-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); |
| } |
| |
| |
| @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"> |
| |
| <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> |
|
|
| |
| <div class="main-grid"> |
| |
| <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> |
|
|
| |
| <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"> |
| |
| </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> |
|
|
| |
| <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> |
|
|
| |
| <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> |
|
|
| |
| <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> |
| |
| let leads = []; |
| let expenses = []; |
| let expenseFilter = 'all'; |
| |
| |
| document.addEventListener('DOMContentLoaded', () => { |
| loadFromStorage(); |
| updateStats(); |
| renderLeads(); |
| renderExpenses(); |
| calculateMortgage(); |
| |
| |
| document.getElementById('expenseDueDate').valueAsDate = new Date(); |
| }); |
| |
| |
| 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); |
| } |
| |
| |
| 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() |
| }; |
| |
| |
| lead.ltv = (lead.loanAmount / lead.propertyValue * 100).toFixed(1); |
| lead.dti = ((lead.loanAmount * 0.04) / (lead.income / 12) * 100).toFixed(1); |
| |
| leads.unshift(lead); |
| saveToStorage(); |
| updateStats(); |
| renderLeads(); |
| |
| |
| const estimatedPayment = (lead.loanAmount * 0.005).toFixed(0); |
| 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(); |
| }); |
| |
| |
| 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(); |
| } |
| |
| |
| 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(''); |
| } |
| |
| |
| 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(''); |
| } |
| |
| |
| 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(); |
| } |
| |
| |
| 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(); |
| } |
| |
| |
| 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 |