Initial commit: Jetour BI Dashboard

FastAPI backend with PostgreSQL queries for sales/CRM pipeline.
Chart.js dark-themed dashboard with:
- Pipeline funnel, velocity, conversion rates
- Monthly trend, lead sources, model distribution
- Vehicle order overview with per-color breakdown + subtotals
- Salesperson leaderboard, new vs used, lost reason analysis
- Email report settings (recipients + SMTP config)
- n8n integration for daily/weekly/monthly reports
This commit is contained in:
root
2026-06-18 20:41:05 +00:00
commit 8f206aa4f1
4 changed files with 1716 additions and 0 deletions

124
static/settings.html Normal file
View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jetour BI — Settings</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;background:#0b1120;color:#e2e8f0;min-height:100vh}
.banner{background:linear-gradient(135deg,#1a1a2e,#16213e,#0f3460);padding:16px 32px;border-bottom:1px solid #1e293b;display:flex;align-items:center;gap:16px}
.banner h1{font-size:18px;font-weight:700}
.banner a{color:#60a5fa;text-decoration:none;font-size:13px}
main{max-width:900px;margin:0 auto;padding:24px}
.tabs{display:flex;gap:4px;margin-bottom:20px;flex-wrap:wrap}
.tab{padding:10px 20px;border:1px solid #334155;border-radius:8px 8px 0 0;background:#1e293b;color:#94a3b8;cursor:pointer;font-size:13px;border-bottom:none}
.tab.active{background:#1e293b;color:#f1f5f9;border-color:#334155;font-weight:600}
.tab-content{display:none;background:#1e293b;border:1px solid #334155;border-radius:0 8px 8px 8px;padding:20px}
.tab-content.active{display:block}
.add-row{display:flex;gap:8px;margin-bottom:16px}
.add-row input{padding:10px 14px;border:1px solid #334155;border-radius:6px;background:#0f172a;color:#e2e8f0;font-size:13px;flex:1}
.add-row button,.form-btn{padding:10px 18px;border:none;border-radius:6px;background:#2563eb;color:#fff;cursor:pointer;font-size:13px;font-weight:600;white-space:nowrap}
.rec-list{list-style:none}
.rec-item{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid #1e293b;gap:12px}
.rec-item:last-child{border-bottom:none}
.rec-info{flex:1;min-width:0}
.rec-email{font-size:14px;color:#e2e8f0;font-weight:500}
.rec-name{font-size:11px;color:#64748b;margin-top:2px}
.rec-actions{display:flex;gap:8px;align-items:center}
.btn-sm{padding:5px 12px;border:1px solid #334155;border-radius:5px;background:transparent;color:#94a3b8;cursor:pointer;font-size:11px}
.btn-sm.del{color:#f87171;border-color:#7f1d1d}
.form-row{display:flex;gap:12px;margin-bottom:12px}
.form-row input,.form-row select{padding:10px 14px;border:1px solid #334155;border-radius:6px;background:#0f172a;color:#e2e8f0;font-size:13px;flex:1}
.section-title{font-size:11px;text-transform:uppercase;color:#64748b;letter-spacing:1px;margin:16px 0 8px}
.status{position:fixed;bottom:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;z-index:100}
.status.ok{background:#065f46;color:#34d399}
.status.err{background:#7f1d1d;color:#fca5a5}
</style>
</head>
<body>
<div class="banner"><h1>Settings</h1><a href="/">Back to Dashboard</a></div>
<main>
<div class="tabs">
<div class="tab active" data-tab="daily">Daily Report</div>
<div class="tab" data-tab="weekly">Weekly Report</div>
<div class="tab" data-tab="monthly">Monthly Report</div>
<div class="tab" data-tab="smtp">SMTP Config</div>
<div class="tab" data-tab="users">Users</div>
</div>
<div class="tab-content active" id="tab-report">
<div class="add-row">
<input type="email" id="new-email" placeholder="email@example.com">
<input type="text" id="new-name" placeholder="Name (optional)">
<button onclick="addRecipient()">+ Add</button>
</div>
<ul class="rec-list" id="rec-list"></ul>
<div style="color:#64748b;padding:8px" id="rec-empty">No recipients yet.</div>
</div>
<div class="tab-content" id="tab-smtp">
<form onsubmit="saveSmtp(event)">
<div class="form-row">
<input type="text" id="smtp-host" placeholder="SMTP Host" required>
<input type="number" id="smtp-port" placeholder="Port" value="587" style="width:90px;flex:none">
</div>
<div class="form-row">
<input type="text" id="smtp-user" placeholder="Username / Email" required>
<input type="password" id="smtp-pass" placeholder="Password">
</div>
<div class="form-row">
<input type="email" id="smtp-from" placeholder="From address" required>
<label style="font-size:13px;color:#94a3b8"><input type="checkbox" id="smtp-tls" checked> TLS</label>
</div>
<button type="submit" class="form-btn">Save SMTP</button>
</form>
<div class="form-row" style="margin-top:16px">
<input type="email" id="test-email" placeholder="test@example.com">
<button onclick="testSmtp()" style="padding:10px 18px;border:1px solid #334155;border-radius:6px;background:#1e293b;color:#94a3b8;cursor:pointer;font-size:13px">Test</button>
</div>
<div id="smtp-status" style="margin-top:12px;font-size:12px;color:#34d399"></div>
</div>
<div class="tab-content" id="tab-users">
<div class="section-title">Change Password</div>
<div class="form-row">
<input type="password" id="settingsCurrPass" placeholder="Current password">
<input type="password" id="settingsNewPass" placeholder="New password">
</div>
<button class="form-btn" onclick="changePassword()" style="margin-bottom:16px">Update Password</button>
<div class="section-title">Manage Users</div>
<div class="form-row">
<input type="text" id="newUser" placeholder="Username">
<input type="email" id="newUserEmail" placeholder="Email (optional)"><input type="password" id="newPass" placeholder="Password">
<select id="newRole" style="flex:none;width:120px">
<option value="standard">Standard</option>
<option value="admin">Admin</option>
</select>
</div>
<button class="form-btn" onclick="addUser()" style="margin-bottom:12px">+ Add User</button>
<div id="userList"></div>
</div>
<div class="modal-overlay" id="editUserModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.7);z-index:10001;align-items:center;justify-content:center">
<div style="background:#1e293b;border-radius:12px;padding:24px;width:440px;border:1px solid #334155">
<h3 style="margin-bottom:16px">Edit User: <span id="editUserName"></span></h3>
<label style="font-size:11px;color:#94a3b8">Email</label>
<input type="email" id="editUserEmail" placeholder="Email" style="width:100%;padding:10px;border:1px solid #334155;border-radius:6px;background:#0f172a;color:#e2e8f0;font-size:13px;margin-bottom:10px">
<label style="font-size:11px;color:#94a3b8">Role</label>
<select id="editUserRole" style="width:100%;padding:10px;border:1px solid #334155;border-radius:6px;background:#0f172a;color:#e2e8f0;font-size:13px;margin-bottom:10px">
<option value="standard">Standard</option>
<option value="admin">Admin</option>
</select>
<label style="font-size:11px;color:#94a3b8">New Password (leave blank to keep)</label>
<input type="password" id="editUserPass" placeholder="New password" style="width:100%;padding:10px;border:1px solid #334155;border-radius:6px;background:#0f172a;color:#e2e8f0;font-size:13px;margin-bottom:14px">
<button onclick="saveUserEdit()" style="width:100%;padding:10px;background:#2563eb;border:none;border-radius:6px;color:#fff;cursor:pointer;font-size:13px;margin-bottom:8px">Save Changes</button>
<button onclick="document.getElementById('editUserModal').style.display='none'" style="width:100%;padding:8px;border:1px solid #334155;border-radius:6px;background:transparent;color:#94a3b8;cursor:pointer;font-size:12px">Cancel</button>
</div>
</div>
</main>
<div class="status" id="status" style="display:none"></div>
<script src="/settings.js?v=3"></script>
</body>
</html>