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
125 lines
7.0 KiB
HTML
125 lines
7.0 KiB
HTML
<!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>
|