d7fb7b7a7b
Build & Deploy / Build & Push Docker Image (push) Failing after 47s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Failing after 4m55s
Test / Admin Unit Tests (push) Successful in 9m37s
Test / Dashboard Unit Tests (push) Successful in 9m37s
Test / API Integration Tests (push) Successful in 9m54s
1252 lines
73 KiB
HTML
1252 lines
73 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>RentalDriveGo — Rental Fleet Operating System</title>
|
||
<script src="https://cdn.tailwindcss.com">
|
||
</script>
|
||
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js">
|
||
</script>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root {
|
||
--bg-primary: #0A0F1A;
|
||
--bg-elevated: #111827;
|
||
--bg-card: rgba(30, 58, 95, 0.25);
|
||
--border-subtle: rgba(59, 130, 246, 0.10);
|
||
--border-accent: rgba(249, 115, 22, 0.30);
|
||
--text-primary: #E8EDF5;
|
||
--text-secondary: #8899B4;
|
||
--accent-blue: #3B82F6;
|
||
--accent-blue-light: #60A5FA;
|
||
--accent-blue-dark: #2563EB;
|
||
--accent-orange: #F97316;
|
||
--accent-orange-light: #FB923C;
|
||
--accent-orange-dark: #EA580C;
|
||
--success: #10B981;
|
||
--danger: #EF4444;
|
||
--warning: #F59E0B;
|
||
--info: #3B82F6;
|
||
--gradient-blue: linear-gradient(135deg, #3B82F6, #2563EB);
|
||
--gradient-orange: linear-gradient(135deg, #F97316, #EA580C);
|
||
--gradient-mixed: linear-gradient(135deg, #3B82F6, #F97316);
|
||
--glow-blue: 0 0 20px rgba(59, 130, 246, 0.15);
|
||
--glow-orange: 0 0 20px rgba(249, 115, 22, 0.15);
|
||
--glass-bg: rgba(15, 25, 45, 0.6);
|
||
}
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
scrollbar-width: thin;
|
||
scrollbar-color: rgba(59, 130, 246, 0.2) transparent;
|
||
}
|
||
|
||
*::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
*::-webkit-scrollbar-track {
|
||
background: transparent;
|
||
}
|
||
*::-webkit-scrollbar-thumb {
|
||
background: rgba(59, 130, 246, 0.2);
|
||
border-radius: 3px;
|
||
transition: background 0.3s;
|
||
}
|
||
*::-webkit-scrollbar-thumb:hover {
|
||
background: rgba(59, 130, 246, 0.4);
|
||
}
|
||
|
||
body {
|
||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||
background: var(--bg-primary);
|
||
color: var(--text-primary);
|
||
overflow: hidden;
|
||
background-image:
|
||
radial-gradient(ellipse at 20% 20%, rgba(59, 130, 246, 0.08) 0%, transparent 60%),
|
||
radial-gradient(ellipse at 80% 70%, rgba(249, 115, 22, 0.06) 0%, transparent 60%),
|
||
radial-gradient(ellipse at 50% 50%, rgba(59, 130, 246, 0.03) 0%, transparent 80%);
|
||
}
|
||
|
||
.font-mono {
|
||
font-family: 'JetBrains Mono', monospace;
|
||
}
|
||
|
||
.glass-card {
|
||
background: var(--glass-bg);
|
||
border: 1px solid var(--border-subtle);
|
||
border-radius: 14px;
|
||
backdrop-filter: blur(24px);
|
||
-webkit-backdrop-filter: blur(24px);
|
||
transition: all 0.3s ease;
|
||
}
|
||
.glass-card:hover {
|
||
border-color: rgba(59, 130, 246, 0.2);
|
||
box-shadow: var(--glow-blue);
|
||
}
|
||
|
||
.glass-card-elevated {
|
||
background: rgba(30, 58, 95, 0.35);
|
||
border: 1px solid rgba(59, 130, 246, 0.15);
|
||
border-radius: 14px;
|
||
backdrop-filter: blur(24px);
|
||
}
|
||
|
||
.btn-primary {
|
||
background: var(--gradient-blue);
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 10px;
|
||
padding: 10px 20px;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.25s ease;
|
||
font-family: 'Inter', sans-serif;
|
||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.btn-primary::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: -100%;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||
transition: left 0.5s;
|
||
}
|
||
.btn-primary:hover::before {
|
||
left: 100%;
|
||
}
|
||
.btn-primary:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 16px rgba(59, 130, 246, 0.4);
|
||
}
|
||
|
||
.btn-orange {
|
||
background: var(--gradient-orange);
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 10px;
|
||
padding: 10px 20px;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.25s ease;
|
||
font-family: 'Inter', sans-serif;
|
||
box-shadow: 0 2px 8px rgba(249, 115, 22, 0.3);
|
||
}
|
||
.btn-orange:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 16px rgba(249, 115, 22, 0.4);
|
||
}
|
||
|
||
.btn-secondary {
|
||
background: rgba(59, 130, 246, 0.08);
|
||
color: var(--text-primary);
|
||
border: 1px solid rgba(59, 130, 246, 0.15);
|
||
border-radius: 10px;
|
||
padding: 10px 20px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.25s ease;
|
||
font-family: 'Inter', sans-serif;
|
||
}
|
||
.btn-secondary:hover {
|
||
background: rgba(59, 130, 246, 0.15);
|
||
border-color: rgba(59, 130, 246, 0.3);
|
||
}
|
||
|
||
.btn-ghost {
|
||
background: transparent;
|
||
color: var(--text-secondary);
|
||
border: none;
|
||
border-radius: 8px;
|
||
padding: 6px 12px;
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
font-family: 'Inter', sans-serif;
|
||
}
|
||
.btn-ghost:hover {
|
||
background: rgba(59, 130, 246, 0.08);
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.badge-blue {
|
||
background: rgba(59, 130, 246, 0.15);
|
||
border: 1px solid rgba(59, 130, 246, 0.3);
|
||
color: var(--accent-blue-light);
|
||
padding: 4px 12px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.badge-orange {
|
||
background: rgba(249, 115, 22, 0.15);
|
||
border: 1px solid rgba(249, 115, 22, 0.3);
|
||
color: var(--accent-orange-light);
|
||
padding: 4px 12px;
|
||
border-radius: 20px;
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.animate-pulse-blue {
|
||
animation: pulseBlue 2.5s ease-in-out infinite;
|
||
}
|
||
@keyframes pulseBlue {
|
||
0%,
|
||
100% {
|
||
box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4);
|
||
}
|
||
50% {
|
||
box-shadow: 0 0 0 10px rgba(59, 130, 246, 0);
|
||
}
|
||
}
|
||
|
||
.animate-pulse-orange {
|
||
animation: pulseOrange 2.5s ease-in-out infinite;
|
||
}
|
||
@keyframes pulseOrange {
|
||
0%,
|
||
100% {
|
||
box-shadow: 0 0 0 0 rgba(249, 115, 22, 0.4);
|
||
}
|
||
50% {
|
||
box-shadow: 0 0 0 10px rgba(249, 115, 22, 0);
|
||
}
|
||
}
|
||
|
||
@keyframes fadeInUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(16px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.animate-in {
|
||
animation: fadeInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||
}
|
||
|
||
@keyframes shimmer {
|
||
0% {
|
||
background-position: -200% 0;
|
||
}
|
||
100% {
|
||
background-position: 200% 0;
|
||
}
|
||
}
|
||
|
||
.shimmer {
|
||
background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.1), transparent);
|
||
background-size: 200% 100%;
|
||
animation: shimmer 2s infinite;
|
||
}
|
||
|
||
.nav-item {
|
||
transition: all 0.25s ease;
|
||
cursor: pointer;
|
||
border-radius: 10px;
|
||
position: relative;
|
||
}
|
||
.nav-item:hover {
|
||
background: rgba(59, 130, 246, 0.08);
|
||
color: var(--text-primary);
|
||
}
|
||
.nav-item.active {
|
||
background: rgba(59, 130, 246, 0.12);
|
||
color: var(--text-primary);
|
||
box-shadow: inset 2px 0 0 var(--accent-blue);
|
||
}
|
||
.nav-item.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
left: 0;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 3px;
|
||
height: 60%;
|
||
background: var(--gradient-blue);
|
||
border-radius: 0 3px 3px 0;
|
||
}
|
||
|
||
.metric-value {
|
||
font-size: 34px;
|
||
font-weight: 300;
|
||
letter-spacing: -1.5px;
|
||
line-height: 1;
|
||
background: linear-gradient(135deg, #E8EDF5, #B0C4DE);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
|
||
.trend-up {
|
||
color: var(--success);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-weight: 500;
|
||
}
|
||
.trend-down {
|
||
color: var(--danger);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.progress-bar {
|
||
height: 6px;
|
||
background: rgba(59, 130, 246, 0.1);
|
||
border-radius: 3px;
|
||
overflow: hidden;
|
||
}
|
||
.progress-fill-blue {
|
||
height: 100%;
|
||
background: var(--gradient-blue);
|
||
border-radius: 3px;
|
||
transition: width 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
.progress-fill-orange {
|
||
height: 100%;
|
||
background: var(--gradient-orange);
|
||
border-radius: 3px;
|
||
transition: width 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
.progress-fill-mixed {
|
||
height: 100%;
|
||
background: var(--gradient-mixed);
|
||
border-radius: 3px;
|
||
transition: width 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
||
}
|
||
|
||
.input-search {
|
||
background: rgba(59, 130, 246, 0.06);
|
||
border: 1px solid rgba(59, 130, 246, 0.12);
|
||
border-radius: 10px;
|
||
color: var(--text-primary);
|
||
font-family: 'Inter', sans-serif;
|
||
outline: none;
|
||
transition: all 0.3s ease;
|
||
}
|
||
.input-search:focus {
|
||
border-color: rgba(59, 130, 246, 0.4);
|
||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.08);
|
||
background: rgba(59, 130, 246, 0.1);
|
||
}
|
||
.input-search::placeholder {
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
.map-glow-blue {
|
||
filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.4));
|
||
}
|
||
.map-glow-orange {
|
||
filter: drop-shadow(0 0 8px rgba(249, 115, 22, 0.4));
|
||
}
|
||
.map-glow-red {
|
||
filter: drop-shadow(0 0 8px rgba(239, 68, 68, 0.4));
|
||
}
|
||
|
||
.divider {
|
||
height: 1px;
|
||
background: linear-gradient(90deg, transparent, rgba(59, 130, 246, 0.2), rgba(249, 115, 22, 0.2), transparent);
|
||
}
|
||
|
||
.tooltip {
|
||
position: relative;
|
||
}
|
||
.tooltip:hover::after {
|
||
content: attr(data-tooltip);
|
||
position: absolute;
|
||
bottom: 100%;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
background: var(--bg-elevated);
|
||
border: 1px solid var(--border-subtle);
|
||
color: var(--text-primary);
|
||
padding: 6px 12px;
|
||
border-radius: 6px;
|
||
font-size: 12px;
|
||
white-space: nowrap;
|
||
z-index: 100;
|
||
margin-bottom: 8px;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* Animations for stat cards */
|
||
@keyframes countUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="h-screen flex">
|
||
|
||
<!-- Sidebar -->
|
||
<aside class="w-60 border-r flex flex-col flex-shrink-0" style="border-color: var(--border-subtle); background: rgba(10, 15, 26, 0.95); backdrop-filter: blur(20px);">
|
||
<!-- Logo -->
|
||
<div class="p-5 border-b flex items-center gap-3" style="border-color: var(--border-subtle);">
|
||
<div style="width: 38px; height: 38px; border-radius: 10px; background: var(--gradient-blue); display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);">
|
||
<span style="color: #fff; font-weight: 700; font-size: 16px; letter-spacing: -0.5px;">F</span>
|
||
</div>
|
||
<div>
|
||
<span style="font-size: 15px; font-weight: 600; letter-spacing: -0.3px; background: linear-gradient(135deg, #E8EDF5, #60A5FA); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">RentalDriveGo</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Navigation -->
|
||
<nav class="flex-1 py-5 px-3 space-y-1.5">
|
||
<div class="nav-item active flex items-center gap-3 px-3.5 py-3 text-sm" data-view="command">
|
||
<i data-lucide="layout-dashboard" style="width: 18px; height: 18px; color: var(--accent-blue-light);"></i>
|
||
<span style="font-weight: 500;">Command Center</span>
|
||
<span class="badge-blue" style="margin-left: auto; font-size: 10px; padding: 2px 8px;">Live</span>
|
||
</div>
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="fleet" style="color: var(--text-secondary);">
|
||
<i data-lucide="car" style="width: 18px; height: 18px;"></i>
|
||
<span>Fleet Intelligence</span>
|
||
</div>
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="revenue" style="color: var(--text-secondary);">
|
||
<i data-lucide="dollar-sign" style="width: 18px; height: 18px;"></i>
|
||
<span>Revenue Optimization</span>
|
||
<span class="badge-orange" style="margin-left: auto; font-size: 10px; padding: 2px 8px;">3</span>
|
||
</div>
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="maintenance" style="color: var(--text-secondary);">
|
||
<i data-lucide="wrench" style="width: 18px; height: 18px;"></i>
|
||
<span>Maintenance</span>
|
||
</div>
|
||
|
||
<div style="height: 1px; background: linear-gradient(90deg, transparent, rgba(59,130,246,0.15), transparent); margin: 8px 12px;"></div>
|
||
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="analytics" style="color: var(--text-secondary);">
|
||
<i data-lucide="bar-chart-3" style="width: 18px; height: 18px;"></i>
|
||
<span>Executive Analytics</span>
|
||
</div>
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="alerts" style="color: var(--text-secondary);">
|
||
<i data-lucide="alert-triangle" style="width: 18px; height: 18px;"></i>
|
||
<span>Risk & Alerts</span>
|
||
</div>
|
||
<div class="nav-item flex items-center gap-3 px-3.5 py-3 text-sm" data-view="customers" style="color: var(--text-secondary);">
|
||
<i data-lucide="users" style="width: 18px; height: 18px;"></i>
|
||
<span>Customer Experience</span>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- Bottom section -->
|
||
<div class="p-4 border-t" style="border-color: var(--border-subtle);">
|
||
<div class="glass-card p-3" style="background: rgba(59,130,246,0.06); border-color: rgba(59,130,246,0.12);">
|
||
<div class="flex items-center gap-3">
|
||
<div style="width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, #3B82F6, #8B5CF6); display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: #fff;">AD</div>
|
||
<div>
|
||
<p style="font-size: 13px; font-weight: 500;">Alex Durant</p>
|
||
<p style="font-size: 11px; color: var(--text-secondary);">Operations Director</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Main Content Area -->
|
||
<div class="flex-1 flex flex-col overflow-hidden">
|
||
<!-- Top Bar -->
|
||
<header class="h-16 border-b flex items-center justify-between px-6 flex-shrink-0" style="border-color: var(--border-subtle); background: rgba(10,15,26,0.9); backdrop-filter: blur(20px);">
|
||
<div class="flex items-center gap-5">
|
||
<div class="relative">
|
||
<i data-lucide="search" style="position: absolute; left: 14px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--text-secondary);"></i>
|
||
<input type="text" placeholder="Search vehicles, locations, VINs..."
|
||
class="input-search"
|
||
style="width: 380px; height: 40px; padding: 0 16px 0 42px; font-size: 14px;">
|
||
</div>
|
||
<div class="flex items-center gap-2 text-sm" style="color: var(--text-secondary);">
|
||
<span style="width: 6px; height: 6px; background: var(--success); border-radius: 50%;" class="animate-pulse-blue"></span>
|
||
System operational • Last sync: 3s ago
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center gap-3">
|
||
<button class="btn-ghost flex items-center gap-2 px-4 py-2" onclick="toggleCopilot()" style="border: 1px solid rgba(249,115,22,0.2); background: rgba(249,115,22,0.06); border-radius: 10px;">
|
||
<i data-lucide="bot" style="width: 16px; height: 16px; color: var(--accent-orange-light);"></i>
|
||
<span style="color: var(--accent-orange-light); font-weight: 500;">AI Copilot</span>
|
||
</button>
|
||
<button style="position: relative; padding: 8px; border-radius: 10px; background: none; border: none; cursor: pointer; transition: all 0.2s;"
|
||
onmouseover="this.style.background='rgba(59,130,246,0.08)'"
|
||
onmouseout="this.style.background='none'">
|
||
<i data-lucide="bell" style="width: 20px; height: 20px; color: var(--text-secondary);"></i>
|
||
<span style="position: absolute; top: 4px; right: 4px; width: 9px; height: 9px; background: var(--accent-orange); border-radius: 50%; border: 2px solid var(--bg-primary);" class="animate-pulse-orange"></span>
|
||
</button>
|
||
<button style="padding: 6px; border-radius: 10px; background: none; border: none; cursor: pointer; transition: all 0.2s;"
|
||
onmouseover="this.style.background='rgba(59,130,246,0.08)'"
|
||
onmouseout="this.style.background='none'">
|
||
<i data-lucide="settings" style="width: 20px; height: 20px; color: var(--text-secondary);"></i>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- Main Viewport -->
|
||
<main class="flex-1 overflow-y-auto p-6" id="main-content">
|
||
|
||
<!-- ==================== COMMAND CENTER ==================== -->
|
||
<div id="view-command" class="view active space-y-6">
|
||
|
||
<!-- Top Metric Cards -->
|
||
<div class="grid grid-cols-4 gap-5">
|
||
<!-- Utilization -->
|
||
<div class="glass-card p-5" style="animation: countUp 0.5s ease-out;">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<span style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1.5px; font-weight: 500;">Fleet Utilization</span>
|
||
<span style="width: 8px; height: 8px; background: var(--accent-blue-light); border-radius: 50%;" class="animate-pulse-blue"></span>
|
||
</div>
|
||
<div class="flex items-baseline gap-3 mb-3">
|
||
<span class="metric-value">84.2%</span>
|
||
<span class="trend-up" style="font-size: 14px;">
|
||
<i data-lucide="trending-up" style="width: 14px; height: 14px;"></i> +2.1%
|
||
</span>
|
||
</div>
|
||
<div class="progress-bar">
|
||
<div class="progress-fill-blue" style="width: 84%;"></div>
|
||
</div>
|
||
<div style="display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--text-secondary);">
|
||
<span>Target: 80%</span>
|
||
<span>+4.2% above target</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Revenue -->
|
||
<div class="glass-card p-5" style="animation: countUp 0.5s ease-out 0.1s both;">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<span style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1.5px; font-weight: 500;">Revenue per Vehicle</span>
|
||
</div>
|
||
<div class="flex items-baseline gap-3 mb-3">
|
||
<span class="metric-value">$2,847</span>
|
||
<span class="trend-up" style="font-size: 14px;">
|
||
<i data-lucide="trending-up" style="width: 14px; height: 14px;"></i> +$112
|
||
</span>
|
||
</div>
|
||
<div class="progress-bar">
|
||
<div class="progress-fill-mixed" style="width: 78%;"></div>
|
||
</div>
|
||
<div style="display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--text-secondary);">
|
||
<span>Target: $2,600</span>
|
||
<span>+$247 above target</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Shop Vehicles -->
|
||
<div class="glass-card p-5" style="animation: countUp 0.5s ease-out 0.2s both; border-color: rgba(249,115,22,0.2);">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<span style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1.5px; font-weight: 500;">Vehicles in Shop</span>
|
||
<span class="animate-pulse-orange" style="width: 8px; height: 8px; background: var(--accent-orange); border-radius: 50%; display: inline-block;"></span>
|
||
</div>
|
||
<div class="flex items-baseline gap-3 mb-3">
|
||
<span class="metric-value" style="background: linear-gradient(135deg, #FB923C, #F97316); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;">23</span>
|
||
<span class="trend-down" style="font-size: 14px; color: var(--success);">
|
||
<i data-lucide="trending-down" style="width: 14px; height: 14px;"></i> -2
|
||
</span>
|
||
</div>
|
||
<span style="font-size: 12px; color: var(--accent-orange-light); font-weight: 500;">⚠ Critical: 4 vehicles</span>
|
||
</div>
|
||
|
||
<!-- Fulfillment -->
|
||
<div class="glass-card p-5" style="animation: countUp 0.5s ease-out 0.3s both;">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<span style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1.5px; font-weight: 500;">Fulfillment Rate</span>
|
||
</div>
|
||
<div class="flex items-baseline gap-3 mb-3">
|
||
<span class="metric-value">96.8%</span>
|
||
<span class="trend-down" style="font-size: 14px;">
|
||
<i data-lucide="trending-down" style="width: 14px; height: 14px;"></i> -0.3%
|
||
</span>
|
||
</div>
|
||
<span style="font-size: 12px; color: var(--text-secondary);">Avg wait: 4.2 min</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Map + AI Panel Grid -->
|
||
<div class="grid grid-cols-3 gap-6">
|
||
<div class="col-span-2 space-y-6">
|
||
|
||
<!-- Live Map -->
|
||
<div class="glass-card overflow-hidden" style="animation: fadeInUp 0.6s ease-out 0.15s both;">
|
||
<div class="p-5 border-b flex items-center justify-between" style="border-color: var(--border-subtle);">
|
||
<div>
|
||
<h2 style="font-size: 15px; font-weight: 600;">Live Fleet Map</h2>
|
||
<p style="font-size: 12px; color: var(--text-secondary); margin-top: 2px;">Real-time vehicle distribution</p>
|
||
</div>
|
||
<div class="flex gap-2">
|
||
<button class="btn-ghost" style="background: rgba(59,130,246,0.1); color: var(--accent-blue-light); border-radius: 20px; padding: 6px 14px; font-size: 12px;">Utilization</button>
|
||
<button class="btn-ghost" style="border-radius: 20px; padding: 6px 14px; font-size: 12px;">Idle Vehicles</button>
|
||
<button class="btn-ghost" style="border-radius: 20px; padding: 6px 14px; font-size: 12px;">EV Fleet</button>
|
||
</div>
|
||
</div>
|
||
<div style="height: 340px; background: radial-gradient(ellipse at center, rgba(59,130,246,0.04) 0%, transparent 70%); position: relative; overflow: hidden;">
|
||
<svg viewBox="0 0 800 340" style="width: 100%; height: 100%;">
|
||
<defs>
|
||
<radialGradient id="glow-blue-strong">
|
||
<stop offset="0%" stop-color="rgba(59,130,246,0.5)"/>
|
||
<stop offset="100%" stop-color="rgba(59,130,246,0)"/>
|
||
</radialGradient>
|
||
<radialGradient id="glow-blue">
|
||
<stop offset="0%" stop-color="rgba(59,130,246,0.35)"/>
|
||
<stop offset="100%" stop-color="rgba(59,130,246,0)"/>
|
||
</radialGradient>
|
||
<radialGradient id="glow-orange">
|
||
<stop offset="0%" stop-color="rgba(249,115,22,0.35)"/>
|
||
<stop offset="100%" stop-color="rgba(249,115,22,0)"/>
|
||
</radialGradient>
|
||
<radialGradient id="glow-red">
|
||
<stop offset="0%" stop-color="rgba(239,68,68,0.4)"/>
|
||
<stop offset="100%" stop-color="rgba(239,68,68,0)"/>
|
||
</radialGradient>
|
||
<filter id="blur-glow">
|
||
<feGaussianBlur stdDeviation="3"/>
|
||
</filter>
|
||
</defs>
|
||
|
||
<!-- Background grid -->
|
||
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
||
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(59,130,246,0.03)" stroke-width="0.5"/>
|
||
</pattern>
|
||
<rect width="800" height="340" fill="url(#grid)"/>
|
||
|
||
<!-- Connection lines -->
|
||
<g stroke="rgba(59,130,246,0.08)" stroke-width="1.5" stroke-dasharray="6,4">
|
||
<line x1="120" y1="110" x2="580" y2="100"/>
|
||
<line x1="120" y1="110" x2="210" y2="85"/>
|
||
<line x1="580" y1="100" x2="530" y2="185"/>
|
||
<line x1="530" y1="185" x2="580" y2="195"/>
|
||
<line x1="420" y1="115" x2="580" y2="100"/>
|
||
<line x1="210" y1="85" x2="420" y2="115"/>
|
||
</g>
|
||
|
||
<!-- LAX - Blue (healthy) -->
|
||
<circle cx="120" cy="110" r="32" fill="url(#glow-blue-strong)" opacity="0.7" class="map-glow-blue"/>
|
||
<circle cx="120" cy="110" r="18" fill="#3B82F6" opacity="0.85" stroke="#60A5FA" stroke-width="2"/>
|
||
<text x="120" y="70" fill="#E8EDF5" font-size="11" text-anchor="middle" font-family="Inter, sans-serif" font-weight="600">LAX</text>
|
||
<text x="120" y="152" fill="#60A5FA" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">92% • 842 vehicles</text>
|
||
|
||
<!-- SFO - Blue -->
|
||
<circle cx="210" cy="85" r="25" fill="url(#glow-blue)" opacity="0.6"/>
|
||
<circle cx="210" cy="85" r="15" fill="#3B82F6" opacity="0.8" stroke="#60A5FA" stroke-width="1.5"/>
|
||
<text x="210" y="52" fill="#E8EDF5" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">SFO</text>
|
||
<text x="210" y="122" fill="#60A5FA" font-size="9" text-anchor="middle" font-family="Inter, sans-serif">88%</text>
|
||
|
||
<!-- JFK - Blue -->
|
||
<circle cx="580" cy="100" r="28" fill="url(#glow-blue)" opacity="0.6"/>
|
||
<circle cx="580" cy="100" r="17" fill="#3B82F6" opacity="0.8" stroke="#60A5FA" stroke-width="1.5"/>
|
||
<text x="580" y="62" fill="#E8EDF5" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">JFK</text>
|
||
<text x="580" y="142" fill="#60A5FA" font-size="9" text-anchor="middle" font-family="Inter, sans-serif">86%</text>
|
||
|
||
<!-- ORD - Orange (warning) -->
|
||
<circle cx="420" cy="115" r="26" fill="url(#glow-orange)" opacity="0.6" class="map-glow-orange"/>
|
||
<circle cx="420" cy="115" r="16" fill="#F97316" opacity="0.8" stroke="#FB923C" stroke-width="1.5"/>
|
||
<text x="420" y="78" fill="#E8EDF5" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">ORD</text>
|
||
<text x="420" y="152" fill="#FB923C" font-size="9" text-anchor="middle" font-family="Inter, sans-serif">78%</text>
|
||
|
||
<!-- MIA - Orange (warning) -->
|
||
<circle cx="530" cy="185" r="22" fill="url(#glow-orange)" opacity="0.5"/>
|
||
<circle cx="530" cy="185" r="13" fill="#F97316" opacity="0.8" stroke="#FB923C" stroke-width="1.5"/>
|
||
<text x="530" y="163" fill="#E8EDF5" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">MIA</text>
|
||
<text x="530" y="210" fill="#FB923C" font-size="9" text-anchor="middle" font-family="Inter, sans-serif">72%</text>
|
||
|
||
<!-- ATL - Red (critical) -->
|
||
<circle cx="580" cy="195" r="34" fill="url(#glow-red)" opacity="0.65" class="map-glow-red">
|
||
<animate attributeName="opacity" values="0.5;0.75;0.5" dur="2s" repeatCount="indefinite"/>
|
||
</circle>
|
||
<circle cx="580" cy="195" r="20" fill="#EF4444" opacity="0.85" stroke="#F87171" stroke-width="2">
|
||
<animate attributeName="r" values="20;21;20" dur="2s" repeatCount="indefinite"/>
|
||
</circle>
|
||
<text x="580" y="168" fill="#E8EDF5" font-size="11" text-anchor="middle" font-family="Inter, sans-serif" font-weight="600">ATL ⚠</text>
|
||
<text x="580" y="228" fill="#F87171" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" font-weight="500">58% • Critical</text>
|
||
</svg>
|
||
|
||
<!-- Legend -->
|
||
<div style="position: absolute; bottom: 16px; right: 20px; display: flex; gap: 16px; font-size: 11px; background: var(--glass-bg); backdrop-filter: blur(20px); border: 1px solid var(--border-subtle); border-radius: 10px; padding: 8px 14px;">
|
||
<span style="display: flex; align-items: center; gap: 6px; color: var(--text-secondary);">
|
||
<span style="width: 8px; height: 8px; background: #3B82F6; border-radius: 50%;"></span> >85%
|
||
</span>
|
||
<span style="display: flex; align-items: center; gap: 6px; color: var(--text-secondary);">
|
||
<span style="width: 8px; height: 8px; background: #F97316; border-radius: 50%;"></span> 70-85%
|
||
</span>
|
||
<span style="display: flex; align-items: center; gap: 6px; color: var(--text-secondary);">
|
||
<span style="width: 8px; height: 8px; background: #EF4444; border-radius: 50%;"></span> <70%
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Branch Performance -->
|
||
<div class="glass-card p-5" style="animation: fadeInUp 0.6s ease-out 0.3s both;">
|
||
<div class="flex items-center justify-between mb-5">
|
||
<div>
|
||
<h2 style="font-size: 15px; font-weight: 600;">Branch Performance</h2>
|
||
<p style="font-size: 12px; color: var(--text-secondary); margin-top: 2px;">Real-time utilization across locations</p>
|
||
</div>
|
||
<span class="badge-blue">6 Locations</span>
|
||
</div>
|
||
<div class="space-y-3">
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" style="transition: background 0.2s;" onmouseover="this.style.background='rgba(59,130,246,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">LAX</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 92%;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500;">92%</span>
|
||
<span style="font-size: 12px; color: #10B981; display: flex; align-items: center; gap: 2px;">▲ 0.8%</span>
|
||
</div>
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" onmouseover="this.style.background='rgba(59,130,246,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">SFO</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 88%;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500;">88%</span>
|
||
<span style="font-size: 12px; color: #10B981;">▲ 0.4%</span>
|
||
</div>
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" onmouseover="this.style.background='rgba(59,130,246,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">JFK</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 86%;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500;">86%</span>
|
||
<span style="font-size: 12px; color: #10B981;">▲ 1.2%</span>
|
||
</div>
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" onmouseover="this.style.background='rgba(249,115,22,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">ORD</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-orange" style="width: 78%;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500;">78%</span>
|
||
<span style="font-size: 12px; color: #EF4444;">▼ 1.8%</span>
|
||
</div>
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" onmouseover="this.style.background='rgba(249,115,22,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">MIA</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-orange" style="width: 72%;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500;">72%</span>
|
||
<span style="font-size: 12px; color: #EF4444;">▼ 4.2%</span>
|
||
<span style="width: 8px; height: 8px; background: #F97316; border-radius: 50%;" class="animate-pulse-orange"></span>
|
||
</div>
|
||
<div class="flex items-center gap-4 p-2 rounded-lg" style="background: rgba(239,68,68,0.05); border: 1px solid rgba(239,68,68,0.1); border-radius: 8px;">
|
||
<span style="width: 40px; font-size: 13px; font-weight: 600;">ATL</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-orange" style="width: 58%; background: #EF4444;"></div>
|
||
</div>
|
||
<span style="width: 48px; font-size: 13px; text-align: right; font-family: 'JetBrains Mono', monospace; font-weight: 500; color: #F87171;">58%</span>
|
||
<span style="font-size: 12px; color: #EF4444;">▼ 9.2%</span>
|
||
<span class="animate-pulse-orange" style="width: 8px; height: 8px; background: #EF4444; border-radius: 50%;"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- AI Panel -->
|
||
<div class="space-y-5">
|
||
<!-- AI Copilot Card -->
|
||
<div class="glass-card p-5" style="animation: fadeInUp 0.6s ease-out 0.2s both; border-color: rgba(249,115,22,0.15);">
|
||
<div class="flex items-center gap-2 mb-4">
|
||
<span class="animate-pulse-orange" style="width: 9px; height: 9px; background: var(--accent-orange); border-radius: 50%; display: inline-block;"></span>
|
||
<h2 style="font-size: 14px; font-weight: 600;">AI Ops Copilot</h2>
|
||
<span class="badge-orange" style="margin-left: auto; font-size: 10px;">Active</span>
|
||
</div>
|
||
<div class="space-y-4">
|
||
<div style="padding: 14px; background: rgba(249,115,22,0.06); border: 1px solid rgba(249,115,22,0.12); border-radius: 10px;">
|
||
<div class="flex items-start gap-3">
|
||
<div style="width: 28px; height: 28px; border-radius: 8px; background: var(--gradient-orange); display: flex; align-items: center; justify-content: center; flex-shrink: 0; margin-top: 1px;">
|
||
<i data-lucide="zap" style="width: 14px; height: 14px; color: #fff;"></i>
|
||
</div>
|
||
<div>
|
||
<h3 style="font-size: 13px; font-weight: 600; margin-bottom: 6px;">Fleet Imbalance Detected</h3>
|
||
<p style="font-size: 12px; color: var(--text-secondary); line-height: 1.6;">
|
||
LAX Branch: <strong style="color: var(--accent-orange-light);">22% idle SUVs</strong> vs 4% at SNA. Demand surge forecast for SUVs in LAX tomorrow.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="padding: 14px; background: rgba(59,130,246,0.04); border: 1px solid rgba(59,130,246,0.1); border-radius: 10px;">
|
||
<span style="font-size: 10px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1px; font-weight: 500;">Recommendation</span>
|
||
<p style="font-size: 13px; font-weight: 500; margin-top: 4px;">Transfer 12 SUVs SNA → LAX tonight.</p>
|
||
<div style="display: flex; align-items: center; gap: 6px; margin-top: 10px; font-size: 13px; color: #10B981; font-weight: 500;">
|
||
<i data-lucide="trending-up" style="width: 15px; height: 15px;"></i>
|
||
Revenue Opportunity: <strong>$8,400</strong>
|
||
</div>
|
||
</div>
|
||
<div class="flex gap-2">
|
||
<button class="btn-orange flex items-center gap-1.5" style="flex: 1; font-size: 13px; padding: 11px 16px;">
|
||
Apply Transfer
|
||
<i data-lucide="arrow-right" style="width: 14px; height: 14px;"></i>
|
||
</button>
|
||
<button class="btn-secondary" style="flex: 1; font-size: 13px;">Dismiss</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Recent Alerts -->
|
||
<div class="glass-card p-5" style="animation: fadeInUp 0.6s ease-out 0.35s both;">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<h2 style="font-size: 14px; font-weight: 600;">Recent Alerts</h2>
|
||
<span class="badge-blue" style="font-size: 10px;">3 new</span>
|
||
</div>
|
||
<div class="space-y-3">
|
||
<div style="display: flex; align-items: flex-start; gap: 10px; padding: 10px; border-radius: 8px; transition: background 0.2s;" onmouseover="this.style.background='rgba(249,115,22,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<div style="width: 24px; height: 24px; border-radius: 6px; background: rgba(245,158,11,0.15); display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
||
<i data-lucide="alert-triangle" style="width: 13px; height: 13px; color: #F59E0B;"></i>
|
||
</div>
|
||
<div style="font-size: 13px;">
|
||
<span style="font-weight: 500;">ATL shortage risk</span>
|
||
<span style="color: var(--text-secondary); display: block; font-size: 11px;">in 48 hours</span>
|
||
</div>
|
||
</div>
|
||
<div style="display: flex; align-items: flex-start; gap: 10px; padding: 10px; border-radius: 8px; transition: background 0.2s;" onmouseover="this.style.background='rgba(59,130,246,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<div style="width: 24px; height: 24px; border-radius: 6px; background: rgba(59,130,246,0.15); display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
||
<i data-lucide="info" style="width: 13px; height: 13px; color: #3B82F6;"></i>
|
||
</div>
|
||
<div style="font-size: 13px;">
|
||
<span style="font-weight: 500;">14 vehicles due for service</span>
|
||
<span style="color: var(--text-secondary); display: block; font-size: 11px;">across 4 locations</span>
|
||
</div>
|
||
</div>
|
||
<div style="display: flex; align-items: flex-start; gap: 10px; padding: 10px; border-radius: 8px; transition: background 0.2s;" onmouseover="this.style.background='rgba(239,68,68,0.04)'" onmouseout="this.style.background='transparent'">
|
||
<div style="width: 24px; height: 24px; border-radius: 6px; background: rgba(239,68,68,0.15); display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
||
<i data-lucide="alert-octagon" style="width: 13px; height: 13px; color: #EF4444;"></i>
|
||
</div>
|
||
<div style="font-size: 13px;">
|
||
<span style="font-weight: 500;">MIA recall notice</span>
|
||
<span style="color: var(--text-secondary); display: block; font-size: 11px;">23 VINs affected</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Quick Actions -->
|
||
<div class="glass-card p-5" style="animation: fadeInUp 0.6s ease-out 0.4s both;">
|
||
<h2 style="font-size: 14px; font-weight: 600; margin-bottom: 12px;">Quick Actions</h2>
|
||
<div class="space-y-2">
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; padding: 12px 14px; font-size: 13px; display: flex; align-items: center; gap: 8px;">
|
||
<i data-lucide="file-text" style="width: 15px; height: 15px; color: var(--accent-blue-light);"></i>
|
||
Generate daily ops report
|
||
</button>
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; padding: 12px 14px; font-size: 13px; display: flex; align-items: center; gap: 8px;">
|
||
<i data-lucide="truck" style="width: 15px; height: 15px; color: var(--accent-orange-light);"></i>
|
||
View fleet transfer requests
|
||
</button>
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; padding: 12px 14px; font-size: 13px; display: flex; align-items: center; gap: 8px;">
|
||
<i data-lucide="calendar" style="width: 15px; height: 15px; color: #10B981;"></i>
|
||
Schedule maintenance window
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== FLEET INTELLIGENCE ==================== -->
|
||
<div id="view-fleet" class="view space-y-6" style="display: none;">
|
||
<div class="flex items-center gap-4">
|
||
<button class="btn-ghost" style="padding: 8px 12px;" onclick="showView('command')">
|
||
<i data-lucide="arrow-left" style="width: 18px; height: 18px; color: var(--text-secondary);"></i>
|
||
</button>
|
||
<div>
|
||
<h1 style="font-size: 20px; font-weight: 600;">LAX Fleet Intelligence</h1>
|
||
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 2px;">Last updated: 2 seconds ago • 842 vehicles on lot</p>
|
||
</div>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-6">
|
||
<div class="glass-card p-6">
|
||
<h2 style="font-size: 16px; font-weight: 600; margin-bottom: 20px;">Vehicle Distribution</h2>
|
||
<div class="space-y-3">
|
||
<div style="padding: 14px; background: rgba(59,130,246,0.06); border: 1px solid rgba(59,130,246,0.1); border-radius: 10px; display: flex; justify-content: space-between; align-items: center;">
|
||
<div class="flex items-center gap-3">
|
||
<span style="width: 12px; height: 12px; background: #3B82F6; border-radius: 50%;"></span>
|
||
<span style="font-size: 14px; font-weight: 500;">Available</span>
|
||
</div>
|
||
<div>
|
||
<span style="font-size: 20px; font-weight: 600;">712</span>
|
||
<span style="font-size: 13px; color: var(--text-secondary); margin-left: 6px;">(84.5%)</span>
|
||
</div>
|
||
</div>
|
||
<div style="padding: 14px; background: rgba(59,130,246,0.03); border: 1px solid rgba(59,130,246,0.06); border-radius: 10px; display: flex; justify-content: space-between; align-items: center;">
|
||
<div class="flex items-center gap-3">
|
||
<span style="width: 12px; height: 12px; background: #60A5FA; border-radius: 50%;"></span>
|
||
<span style="font-size: 14px; font-weight: 500;">Rented</span>
|
||
</div>
|
||
<div>
|
||
<span style="font-size: 20px; font-weight: 600;">107</span>
|
||
<span style="font-size: 13px; color: var(--text-secondary); margin-left: 6px;">(12.7%)</span>
|
||
</div>
|
||
</div>
|
||
<div style="padding: 14px; background: rgba(249,115,22,0.06); border: 1px solid rgba(249,115,22,0.12); border-radius: 10px; display: flex; justify-content: space-between; align-items: center;">
|
||
<div class="flex items-center gap-3">
|
||
<i data-lucide="clock" style="width: 15px; height: 15px; color: var(--accent-orange);"></i>
|
||
<span style="font-size: 14px; font-weight: 500;">Idle >48h</span>
|
||
</div>
|
||
<div>
|
||
<span style="font-size: 20px; font-weight: 600; color: var(--accent-orange-light);">23</span>
|
||
<span style="font-size: 13px; color: var(--accent-orange-light); opacity: 0.7; margin-left: 6px;">(2.7%)</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<button class="btn-primary" style="margin-top: 16px; width: 100%; padding: 12px;">View Idle Vehicles →</button>
|
||
</div>
|
||
<div class="glass-card p-6">
|
||
<h2 style="font-size: 16px; font-weight: 600; margin-bottom: 20px;">Utilization Trend</h2>
|
||
<svg viewBox="0 0 400 180" style="width: 100%; height: 170px;">
|
||
<defs>
|
||
<linearGradient id="areaGradFleet" x1="0" y1="0" x2="0" y2="1">
|
||
<stop offset="0%" stop-color="#3B82F6" stop-opacity="0.3"/>
|
||
<stop offset="100%" stop-color="#F97316" stop-opacity="0"/>
|
||
</linearGradient>
|
||
<linearGradient id="lineGradFleet" x1="0" y1="0" x2="1" y2="0">
|
||
<stop offset="0%" stop-color="#3B82F6"/>
|
||
<stop offset="100%" stop-color="#F97316"/>
|
||
</linearGradient>
|
||
</defs>
|
||
<!-- Grid -->
|
||
<line x1="0" y1="40" x2="400" y2="40" stroke="rgba(59,130,246,0.1)" stroke-width="1" stroke-dasharray="4,4"/>
|
||
<line x1="0" y1="80" x2="400" y2="80" stroke="rgba(59,130,246,0.06)" stroke-width="0.5"/>
|
||
<line x1="0" y1="120" x2="400" y2="120" stroke="rgba(59,130,246,0.06)" stroke-width="0.5"/>
|
||
<!-- Area -->
|
||
<path d="M0,130 Q20,118 40,122 T80,108 T120,98 T160,93 T200,88 T240,83 T280,78 T320,73 T360,68 T400,63 L400,170 L0,170 Z" fill="url(#areaGradFleet)"/>
|
||
<!-- Line -->
|
||
<path d="M0,130 Q20,118 40,122 T80,108 T120,98 T160,93 T200,88 T240,83 T280,78 T320,73 T360,68 T400,63" fill="none" stroke="url(#lineGradFleet)" stroke-width="2.5" stroke-linecap="round"/>
|
||
<!-- Dot at end -->
|
||
<circle cx="400" cy="63" r="5" fill="#F97316" stroke="#fff" stroke-width="2"/>
|
||
</svg>
|
||
<div style="display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: var(--text-secondary);">
|
||
<span>Jun 1</span>
|
||
<span>Jun 8</span>
|
||
<span>Jun 15</span>
|
||
<span>Jun 24</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== REVENUE OPTIMIZATION ==================== -->
|
||
<div id="view-revenue" class="view space-y-6" style="display: none;">
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<h1 style="font-size: 20px; font-weight: 600;">Revenue Optimization</h1>
|
||
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 2px;">AI-powered pricing recommendations</p>
|
||
</div>
|
||
<span class="badge-orange">3 Pricing Recommendations</span>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-6">
|
||
<!-- Revenue by Class -->
|
||
<div class="glass-card p-6">
|
||
<h2 style="font-size: 15px; font-weight: 600; margin-bottom: 20px;">Rev/Vehicle by Class</h2>
|
||
<div class="space-y-4">
|
||
<div class="flex items-center gap-4">
|
||
<span style="width: 72px; font-size: 13px; color: var(--text-secondary); font-weight: 500;">Luxury</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 92%;"></div>
|
||
</div>
|
||
<span style="width: 72px; text-align: right; font-size: 13px; font-family: 'JetBrains Mono', monospace; font-weight: 500;">$4,820</span>
|
||
</div>
|
||
<div class="flex items-center gap-4">
|
||
<span style="width: 72px; font-size: 13px; color: var(--text-secondary); font-weight: 500;">SUV</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-mixed" style="width: 68%;"></div>
|
||
</div>
|
||
<span style="width: 72px; text-align: right; font-size: 13px; font-family: 'JetBrains Mono', monospace; font-weight: 500;">$3,140</span>
|
||
</div>
|
||
<div class="flex items-center gap-4">
|
||
<span style="width: 72px; font-size: 13px; color: var(--text-secondary); font-weight: 500;">Compact</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 55%;"></div>
|
||
</div>
|
||
<span style="width: 72px; text-align: right; font-size: 13px; font-family: 'JetBrains Mono', monospace; font-weight: 500;">$2,560</span>
|
||
</div>
|
||
<div class="flex items-center gap-4">
|
||
<span style="width: 72px; font-size: 13px; color: var(--text-secondary); font-weight: 500;">Economy</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-blue" style="width: 45%;"></div>
|
||
</div>
|
||
<span style="width: 72px; text-align: right; font-size: 13px; font-family: 'JetBrains Mono', monospace; font-weight: 500;">$2,100</span>
|
||
</div>
|
||
<div class="flex items-center gap-4">
|
||
<span style="width: 72px; font-size: 13px; color: var(--text-secondary); font-weight: 500;">EV</span>
|
||
<div class="progress-bar" style="flex: 1;">
|
||
<div class="progress-fill-orange" style="width: 60%;"></div>
|
||
</div>
|
||
<span style="width: 72px; text-align: right; font-size: 13px; font-family: 'JetBrains Mono', monospace; font-weight: 500;">$2,870</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Pricing Intelligence -->
|
||
<div class="glass-card p-6">
|
||
<div class="flex items-center gap-2 mb-4">
|
||
<div style="width: 28px; height: 28px; border-radius: 8px; background: var(--gradient-orange); display: flex; align-items: center; justify-content: center;">
|
||
<i data-lucide="trending-up" style="width: 15px; height: 15px; color: #fff;"></i>
|
||
</div>
|
||
<h2 style="font-size: 15px; font-weight: 600;">Pricing Intelligence</h2>
|
||
</div>
|
||
<div style="padding: 18px; background: rgba(249,115,22,0.06); border: 1px solid rgba(249,115,22,0.12); border-radius: 12px;">
|
||
<h3 style="font-size: 15px; font-weight: 600; margin-bottom: 14px;">Midsize SUV — LAX</h3>
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; font-size: 13px;">
|
||
<div>
|
||
<span style="color: var(--text-secondary); display: block; margin-bottom: 4px;">Current Rate</span>
|
||
<p style="font-family: 'JetBrains Mono', monospace; font-size: 18px; font-weight: 500;">$89/day</p>
|
||
</div>
|
||
<div>
|
||
<span style="color: var(--text-secondary); display: block; margin-bottom: 4px;">Recommended</span>
|
||
<p style="font-family: 'JetBrains Mono', monospace; font-size: 18px; font-weight: 600; color: #10B981;">$104/day</p>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top: 14px; font-size: 13px; display: flex; gap: 10px;">
|
||
<span style="color: #10B981; font-weight: 600;">+16.8%</span>
|
||
<span style="color: var(--text-secondary);">• Demand signal: Strong (+32%)</span>
|
||
</div>
|
||
<div class="divider" style="margin: 14px 0;"></div>
|
||
<div style="font-size: 14px; display: flex; align-items: center; gap: 8px; color: #10B981; font-weight: 500;">
|
||
<i data-lucide="trending-up" style="width: 16px; height: 16px;"></i>
|
||
Est. weekly impact: <strong>+$4,200</strong>
|
||
</div>
|
||
</div>
|
||
<div class="flex gap-2 mt-4">
|
||
<button class="btn-orange" style="flex: 1; padding: 12px;">Apply Rate Change</button>
|
||
<button class="btn-secondary" style="flex: 1; padding: 12px;">Set Auto-adjust ±15%</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Lost Revenue -->
|
||
<div class="glass-card p-6" style="border-color: rgba(249,115,22,0.2);">
|
||
<div class="flex items-start gap-4">
|
||
<div style="width: 40px; height: 40px; border-radius: 10px; background: rgba(249,115,22,0.15); display: flex; align-items: center; justify-content: center; flex-shrink: 0;">
|
||
<i data-lucide="alert-circle" style="width: 20px; height: 20px; color: var(--accent-orange);"></i>
|
||
</div>
|
||
<div>
|
||
<h3 style="font-size: 16px; font-weight: 600;">Lost Revenue Detection</h3>
|
||
<p style="font-size: 14px; color: var(--text-secondary); margin-top: 4px;">
|
||
23 turnaways at MIA last week due to vehicle shortage
|
||
</p>
|
||
<p style="font-size: 36px; font-weight: 300; letter-spacing: -1px; color: var(--accent-orange-light); margin-top: 10px;">$8,740</p>
|
||
<p style="font-size: 12px; color: var(--text-secondary);">Estimated revenue loss • <span style="color: var(--accent-orange-light); cursor: pointer;">View Details →</span></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ==================== MAINTENANCE ==================== -->
|
||
<div id="view-maintenance" class="view space-y-6" style="display: none;">
|
||
<div class="flex items-center justify-between">
|
||
<div>
|
||
<h1 style="font-size: 20px; font-weight: 600;">Maintenance Intelligence</h1>
|
||
<p style="font-size: 13px; color: var(--text-secondary); margin-top: 2px;">Predictive alerts & service scheduling</p>
|
||
</div>
|
||
<span class="badge-orange">4 Predictive Alerts</span>
|
||
</div>
|
||
<div class="grid grid-cols-2 gap-6">
|
||
<!-- Vehicle Health Map -->
|
||
<div class="glass-card p-6">
|
||
<h2 style="font-size: 15px; font-weight: 600; margin-bottom: 20px;">Vehicle Health Map</h2>
|
||
<svg viewBox="0 0 400 230" style="width: 100%; height: 230px;">
|
||
<line x1="40" y1="195" x2="380" y2="195" stroke="rgba(59,130,246,0.1)" stroke-width="1"/>
|
||
<line x1="40" y1="195" x2="40" y2="20" stroke="rgba(59,130,246,0.1)" stroke-width="1"/>
|
||
<text x="200" y="218" fill="#8899B4" font-size="10" text-anchor="middle" font-family="Inter, sans-serif">Mileage</text>
|
||
<text x="10" y="108" fill="#8899B4" font-size="10" text-anchor="middle" font-family="Inter, sans-serif" transform="rotate(-90, 10, 108)">Days Since Service</text>
|
||
<!-- Scatter points -->
|
||
<circle cx="80" cy="50" r="5" fill="#3B82F6" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="2.5s" repeatCount="indefinite"/></circle>
|
||
<circle cx="140" cy="80" r="5" fill="#3B82F6" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="3s" repeatCount="indefinite"/></circle>
|
||
<circle cx="190" cy="110" r="5" fill="#F97316" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="3.5s" repeatCount="indefinite"/></circle>
|
||
<circle cx="240" cy="95" r="5" fill="#3B82F6" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="2.8s" repeatCount="indefinite"/></circle>
|
||
<circle cx="290" cy="65" r="5" fill="#EF4444" opacity="0.8"><animate attributeName="opacity" values="0.5;0.9;0.5" dur="2s" repeatCount="indefinite"/></circle>
|
||
<circle cx="170" cy="145" r="5" fill="#F97316" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="3.2s" repeatCount="indefinite"/></circle>
|
||
<circle cx="320" cy="125" r="5" fill="#EF4444" opacity="0.8"><animate attributeName="opacity" values="0.5;0.9;0.5" dur="2.3s" repeatCount="indefinite"/></circle>
|
||
<circle cx="270" cy="155" r="5" fill="#F97316" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="3.7s" repeatCount="indefinite"/></circle>
|
||
<circle cx="120" cy="35" r="5" fill="#3B82F6" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="2.6s" repeatCount="indefinite"/></circle>
|
||
<circle cx="340" cy="45" r="5" fill="#3B82F6" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="3.1s" repeatCount="indefinite"/></circle>
|
||
<circle cx="70" cy="165" r="5" fill="#EF4444" opacity="0.8"><animate attributeName="opacity" values="0.5;0.9;0.5" dur="2.7s" repeatCount="indefinite"/></circle>
|
||
<circle cx="350" cy="170" r="5" fill="#F97316" opacity="0.7"><animate attributeName="opacity" values="0.4;0.8;0.4" dur="2.9s" repeatCount="indefinite"/></circle>
|
||
<!-- Legend -->
|
||
<circle cx="350" cy="15" r="4" fill="#3B82F6" opacity="0.7"/>
|
||
<text x="358" y="18" fill="#8899B4" font-size="9" font-family="Inter, sans-serif">Healthy</text>
|
||
<circle cx="350" cy="30" r="4" fill="#F97316" opacity="0.7"/>
|
||
<text x="358" y="33" fill="#8899B4" font-size="9" font-family="Inter, sans-serif">Warning</text>
|
||
<circle cx="350" cy="45" r="4" fill="#EF4444" opacity="0.8"/>
|
||
<text x="358" y="48" fill="#8899B4" font-size="9" font-family="Inter, sans-serif">Critical</text>
|
||
</svg>
|
||
</div>
|
||
|
||
<div class="space-y-4">
|
||
<!-- Predictive Alert -->
|
||
<div class="glass-card p-5" style="border-color: rgba(249,115,22,0.15);">
|
||
<div class="flex items-center gap-2 mb-4">
|
||
<span class="animate-pulse-orange" style="width: 9px; height: 9px; background: var(--accent-orange); border-radius: 50%;"></span>
|
||
<h2 style="font-size: 14px; font-weight: 600;">Predictive Alert</h2>
|
||
</div>
|
||
<h3 style="font-size: 15px; font-weight: 600;">#VA-2847 • 2024 Toyota Camry</h3>
|
||
<div style="display: flex; gap: 8px; margin-top: 10px; font-size: 13px;">
|
||
<span style="color: var(--accent-orange); font-size: 16px;">⚠</span>
|
||
<span style="color: var(--text-secondary); line-height: 1.6;">Brake pad wear at <strong style="color: var(--accent-orange-light);">82%</strong>. Predicted service: <strong>Sep 28 – Oct 5</strong></span>
|
||
</div>
|
||
<p style="font-size: 13px; color: var(--accent-blue-light); margin-top: 10px;">
|
||
💡 Schedule during low-demand window (Tue–Wed)
|
||
</p>
|
||
<div class="flex gap-2 mt-4">
|
||
<button class="btn-orange" style="font-size: 13px; padding: 10px 18px;">Schedule</button>
|
||
<button class="btn-secondary" style="font-size: 13px; padding: 10px 18px;">Add to Queue</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Service Backlog -->
|
||
<div class="glass-card p-5">
|
||
<h2 style="font-size: 15px; font-weight: 600; margin-bottom: 16px;">Service Backlog</h2>
|
||
<div style="display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 10px;">
|
||
<span style="color: #EF4444; font-weight: 500;">12 vehicles overdue</span>
|
||
<span style="color: var(--text-secondary);">↓ 8 in progress</span>
|
||
</div>
|
||
<div style="display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 16px;">
|
||
<span style="color: var(--text-secondary);">↓ 4 awaiting parts</span>
|
||
<span style="color: var(--text-secondary);">Avg turnaround: <strong style="color: var(--text-primary);">2.1 days</strong></span>
|
||
</div>
|
||
<div class="progress-bar" style="height: 8px;">
|
||
<div class="progress-fill-orange" style="width: 75%; background: linear-gradient(90deg, #EF4444, #F97316);"></div>
|
||
</div>
|
||
<div style="display: flex; justify-content: space-between; margin-top: 6px; font-size: 11px; color: var(--text-secondary);">
|
||
<span>0%</span>
|
||
<span>75% capacity</span>
|
||
<span>100%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- Copilot Panel -->
|
||
<div id="copilot-panel" class="flex flex-col flex-shrink-0" style="width: 0; overflow: hidden; border-left: 1px solid var(--border-subtle); background: rgba(10,15,26,0.95); backdrop-filter: blur(20px); transition: width 0.35s cubic-bezier(0.16, 1, 0.3, 1);">
|
||
<div class="p-5 border-b flex items-center gap-3" style="border-color: var(--border-subtle);">
|
||
<div style="width: 36px; height: 36px; border-radius: 10px; background: var(--gradient-orange); display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 12px rgba(249,115,22,0.3);">
|
||
<i data-lucide="bot" style="width: 18px; height: 18px; color: #fff;"></i>
|
||
</div>
|
||
<div>
|
||
<h2 style="font-size: 15px; font-weight: 600;">RentalDriveGo Copilot</h2>
|
||
<p style="font-size: 11px; color: var(--text-secondary);">AI Operations Assistant</p>
|
||
</div>
|
||
<button onclick="toggleCopilot()" style="margin-left: auto; background: rgba(255,255,255,0.04); border: none; cursor: pointer; color: var(--text-secondary); font-size: 20px; width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; transition: all 0.2s;"
|
||
onmouseover="this.style.background='rgba(239,68,68,0.15)'; this.style.color='#EF4444'"
|
||
onmouseout="this.style.background='rgba(255,255,255,0.04)'; this.style.color='var(--text-secondary)'">×</button>
|
||
</div>
|
||
|
||
<div class="flex-1 overflow-y-auto p-5 space-y-4">
|
||
<!-- Briefing -->
|
||
<div class="glass-card p-4" style="background: rgba(59,130,246,0.04); border-color: rgba(59,130,246,0.1);">
|
||
<div class="flex items-center gap-2 mb-3">
|
||
<i data-lucide="sparkles" style="width: 15px; height: 15px; color: var(--accent-blue-light);"></i>
|
||
<span style="font-size: 14px; font-weight: 600;">Executive Summary</span>
|
||
</div>
|
||
<p style="font-size: 13px; color: var(--text-secondary); line-height: 1.7;">
|
||
Overall utilization is <strong style="color: var(--accent-blue-light);">84.2%</strong>, up 2.1% from last week. Revenue per vehicle reached <strong>$2,847</strong>, exceeding the $2,600 target. The MIA branch shows a 9% decline requiring attention.
|
||
</p>
|
||
<div style="margin-top: 12px; display: flex; align-items: center; gap: 8px; font-size: 13px;">
|
||
<span class="animate-pulse-orange" style="width: 8px; height: 8px; background: var(--accent-orange); border-radius: 50%;"></span>
|
||
<span style="color: var(--accent-orange-light); font-weight: 500;">3 actions recommended</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Suggestions -->
|
||
<div>
|
||
<span style="font-size: 11px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1px; font-weight: 500;">Try asking</span>
|
||
<div class="space-y-2 mt-3">
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; font-size: 13px; padding: 12px 14px; border-color: rgba(59,130,246,0.12);">
|
||
What's my highest-performing vehicle class?
|
||
</button>
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; font-size: 13px; padding: 12px 14px; border-color: rgba(59,130,246,0.12);">
|
||
Show me vehicles idle > 72 hours
|
||
</button>
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; font-size: 13px; padding: 12px 14px; border-color: rgba(59,130,246,0.12);">
|
||
Generate weekly ops report
|
||
</button>
|
||
<button class="btn-secondary" style="width: 100%; text-align: left; font-size: 13px; padding: 12px 14px; border-color: rgba(59,130,246,0.12);">
|
||
Which branches need attention?
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Chat Input -->
|
||
<div class="p-4 border-t" style="border-color: var(--border-subtle);">
|
||
<div style="display: flex; gap: 8px;">
|
||
<input type="text" placeholder="Ask anything about your fleet..."
|
||
class="input-search"
|
||
style="flex: 1; height: 44px; padding: 0 14px; font-size: 13px;">
|
||
<button class="btn-orange" style="padding: 10px 14px; border-radius: 10px;">
|
||
<i data-lucide="send" style="width: 18px; height: 18px; color: #fff;"></i>
|
||
</button>
|
||
</div>
|
||
<p style="font-size: 10px; color: var(--text-secondary); margin-top: 8px; text-align: center;">
|
||
RentalDriveGo Copilot • v2.4.1 • Powered by AI
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Initialize Lucide icons
|
||
lucide.createIcons();
|
||
|
||
// View navigation
|
||
function showView(viewName) {
|
||
document.querySelectorAll('.view').forEach(v => v.style.display = 'none');
|
||
const target = document.getElementById('view-' + viewName);
|
||
if (target) {
|
||
target.style.display = '';
|
||
target.classList.add('animate-in');
|
||
}
|
||
|
||
document.querySelectorAll('.nav-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
item.style.color = 'var(--text-secondary)';
|
||
const icon = item.querySelector('[data-lucide]');
|
||
if (icon) icon.style.color = '';
|
||
});
|
||
|
||
const activeNav = document.querySelector(`[data-view="${viewName}"]`);
|
||
if (activeNav) {
|
||
activeNav.classList.add('active');
|
||
activeNav.style.color = 'var(--text-primary)';
|
||
const icon = activeNav.querySelector('[data-lucide]');
|
||
if (icon) icon.style.color = 'var(--accent-blue-light)';
|
||
}
|
||
}
|
||
|
||
// Nav click handlers
|
||
document.querySelectorAll('.nav-item').forEach(item => {
|
||
item.addEventListener('click', () => {
|
||
const view = item.getAttribute('data-view');
|
||
if (view) showView(view);
|
||
});
|
||
});
|
||
|
||
// Copilot toggle
|
||
function toggleCopilot() {
|
||
const panel = document.getElementById('copilot-panel');
|
||
const isOpen = panel.style.width === '420px';
|
||
panel.style.width = isOpen ? '0' : '420px';
|
||
}
|
||
|
||
// Default view
|
||
showView('command');
|
||
|
||
// Re-render icons after view changes
|
||
setTimeout(() => lucide.createIcons(), 100);
|
||
</script>
|
||
</body>
|
||
</html> |