<!DOCTYPE html>
<html class="dark" lang="en">
<head>
<meta charset="utf-8" />
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<title>Dashboard - CodeGuard AI</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1"
rel="stylesheet" />
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
tailwind.config = {
darkMode: "class",
theme: {
extend: {
colors: {
"primary": "#1337ec",
"accent-cyan": "#00f2ff",
"accent-purple": "#7c3aed",
"surface-dark": "#111111",
"border-dark": "#232948",
"background-dark": "#0a0a0a",
"danger": "#ef4444",
"warning": "#f59e0b",
"success": "#10b981",
},
fontFamily: {
"display": ["Inter", "sans-serif"],
"mono": ["JetBrains Mono", "monospace"],
}
}
}
}
</script>
<style>
.glass-panel {
background: rgba(17, 17, 17, 0.7);
backdrop-filter: blur(10px);
border: 1px solid rgba(35, 41, 72, 0.5);
}
</style>
</head>
<body class="bg-background-dark text-white font-display antialiased overflow-hidden h-screen flex">
<!-- Sidebar -->
<aside class="w-64 border-r border-border-dark flex flex-col bg-surface-dark/50">
<div class="h-16 flex items-center gap-3 px-6 border-b border-border-dark">
<span class="material-symbols-outlined text-primary text-2xl">shield_lock</span>
<span class="font-bold text-lg">CodeGuard</span>
</div>
<nav class="flex-1 py-6 px-3 space-y-1">
<a href="#" class="flex items-center gap-3 px-3 py-2 rounded-lg bg-primary/10 text-primary font-medium">
<span class="material-symbols-outlined">dashboard</span>
Overview
</a>
<a href="#"
class="flex items-center gap-3 px-3 py-2 rounded-lg text-gray-400 hover:text-white hover:bg-white/5 transition-colors">
<span class="material-symbols-outlined">folder_open</span>
Repositories
</a>
<a href="#"
class="flex items-center gap-3 px-3 py-2 rounded-lg text-gray-400 hover:text-white hover:bg-white/5 transition-colors">
<span class="material-symbols-outlined">description</span>
Reports
<span
class="ml-auto text-[10px] bg-accent-purple/20 text-accent-purple px-1.5 py-0.5 rounded">NEW</span>
</a>
<a href="#"
class="flex items-center gap-3 px-3 py-2 rounded-lg text-gray-400 hover:text-white hover:bg-white/5 transition-colors">
<span class="material-symbols-outlined">school</span>
Training
</a>
<a href="#"
class="flex items-center gap-3 px-3 py-2 rounded-lg text-gray-400 hover:text-white hover:bg-white/5 transition-colors">
<span class="material-symbols-outlined">settings</span>
Settings
</a>
</nav>
<div class="p-4 border-t border-border-dark">
<div class="flex items-center gap-3">
<div
class="w-8 h-8 rounded-full bg-gradient-to-tr from-primary to-accent-purple flex items-center justify-center text-xs font-bold">
AC
</div>
<div>
<div class="text-sm font-medium">Acme Corp</div>
<div class="text-xs text-gray-500">Enterprise Plan</div>
</div>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="flex-1 flex flex-col overflow-hidden relative">
<!-- Header -->
<header
class="h-16 border-b border-border-dark flex items-center justify-between px-8 bg-background-dark/80 backdrop-blur-md z-10">
<h1 class="text-xl font-bold">Compliance Overview</h1>
<div class="flex items-center gap-4">
<button
class="flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-surface-dark border border-border-dark rounded-lg hover:bg-white/5 transition-colors">
<span class="material-symbols-outlined text-lg">calendar_month</span>
Last 30 Days
</button>
<button
class="flex items-center gap-2 px-4 py-2 text-sm font-bold text-white bg-primary rounded-lg hover:bg-blue-600 transition-colors shadow-lg shadow-blue-900/20">
<span class="material-symbols-outlined text-lg">download</span>
Export PDF
</button>
</div>
</header>
<!-- Scrollable Content -->
<div class="flex-1 overflow-y-auto p-8">
<!-- Top Metrics Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<!-- Compliance Score -->
<div class="glass-panel p-6 rounded-xl relative overflow-hidden group">
<div
class="absolute -right-6 -top-6 w-24 h-24 bg-primary/20 blur-xl rounded-full group-hover:bg-primary/30 transition-colors">
</div>
<div class="text-sm text-gray-400 mb-1">Overall Compliance Score</div>
<div class="flex items-end gap-3">
<span class="text-4xl font-bold text-white">68</span>
<span class="text-sm text-gray-400 mb-1">/ 100</span>
<span class="text-xs text-success bg-success/10 px-1.5 py-0.5 rounded mb-1.5 ml-auto">+12 vs
last month</span>
</div>
<div class="w-full h-1.5 bg-gray-800 rounded-full mt-4 overflow-hidden">
<div class="h-full bg-gradient-to-r from-warning to-success w-[68%]"></div>
</div>
</div>
<!-- Critical Issues -->
<div class="glass-panel p-6 rounded-xl relative overflow-hidden">
<div class="text-sm text-gray-400 mb-1">Critical Issues</div>
<div class="flex items-end gap-3">
<span class="text-4xl font-bold text-danger">3</span>
<span class="text-xs text-success bg-success/10 px-1.5 py-0.5 rounded mb-1.5 ml-auto">-2 vs last
month</span>
</div>
<div class="text-xs text-gray-500 mt-2">Requires immediate attention</div>
</div>
<!-- Fix Rate -->
<div class="glass-panel p-6 rounded-xl relative overflow-hidden">
<div class="text-sm text-gray-400 mb-1">Fix Rate (MTTR)</div>
<div class="flex items-end gap-3">
<span class="text-4xl font-bold text-white">2.4</span>
<span class="text-sm text-gray-400 mb-1">days</span>
<span class="text-xs text-danger bg-danger/10 px-1.5 py-0.5 rounded mb-1.5 ml-auto">+0.5 vs last
month</span>
</div>
<div class="text-xs text-gray-500 mt-2">Avg time to resolve criticals</div>
</div>
<!-- Protected Data -->
<div class="glass-panel p-6 rounded-xl relative overflow-hidden">
<div class="text-sm text-gray-400 mb-1">Data Flows Mapped</div>
<div class="flex items-end gap-3">
<span class="text-4xl font-bold text-accent-cyan">142</span>
<span
class="text-xs text-accent-cyan bg-accent-cyan/10 px-1.5 py-0.5 rounded mb-1.5 ml-auto">98%
Coverage</span>
</div>
<div class="text-xs text-gray-500 mt-2">Across 15 repositories</div>
</div>
</div>
<!-- Main Grid -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Trend Chart -->
<div class="lg:col-span-2 glass-panel p-6 rounded-xl">
<div class="flex items-center justify-between mb-6">
<h3 class="font-bold text-lg">Compliance Trend</h3>
<select
class="bg-surface-dark border border-border-dark text-xs rounded px-2 py-1 text-gray-300 outline-none">
<option>All Repositories</option>
<option>Backend API</option>
<option>Frontend App</option>
</select>
</div>
<div class="h-[300px]">
<canvas id="trendChart"></canvas>
</div>
</div>
<!-- Leaderboard -->
<div class="glass-panel p-6 rounded-xl">
<h3 class="font-bold text-lg mb-4">Top Fixers 🏆</h3>
<div class="space-y-4">
<div
class="flex items-center gap-3 p-3 rounded-lg bg-surface-dark/50 border border-border-dark/50">
<div
class="w-8 h-8 rounded-full bg-purple-500 flex items-center justify-center text-xs font-bold">
JS</div>
<div class="flex-1">
<div class="text-sm font-medium">Joao Silva</div>
<div class="text-xs text-gray-500">12 fixes this month</div>
</div>
<span class="text-success font-bold text-sm">+240xp</span>
</div>
<div
class="flex items-center gap-3 p-3 rounded-lg bg-surface-dark/50 border border-border-dark/50">
<div
class="w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-xs font-bold">
MS</div>
<div class="flex-1">
<div class="text-sm font-medium">Maria Santos</div>
<div class="text-xs text-gray-500">8 fixes this month</div>
</div>
<span class="text-success font-bold text-sm">+160xp</span>
</div>
<div
class="flex items-center gap-3 p-3 rounded-lg bg-surface-dark/50 border border-border-dark/50">
<div
class="w-8 h-8 rounded-full bg-green-500 flex items-center justify-center text-xs font-bold">
AL</div>
<div class="flex-1">
<div class="text-sm font-medium">Andre Lima</div>
<div class="text-xs text-gray-500">5 fixes this month</div>
</div>
<span class="text-success font-bold text-sm">+100xp</span>
</div>
</div>
<button
class="w-full mt-4 py-2 text-xs text-gray-400 hover:text-white transition-colors border border-dashed border-border-dark rounded">View
All Members</button>
<div class="mt-8">
<h3 class="font-bold text-lg mb-4">Risk Matrix</h3>
<div
class="relative w-full aspect-square border-l border-b border-gray-700 bg-[linear-gradient(45deg,transparent_25%,rgba(255,255,255,0.05)_25%,rgba(255,255,255,0.05)_50%,transparent_50%,transparent_75%,rgba(255,255,255,0.05)_75%,rgba(255,255,255,0.05)_100%)] bg-[length:20px_20px]">
<!-- Axis Labels -->
<div class="absolute -left-6 top-1/2 -rotate-90 text-[10px] text-gray-500">IMPACT</div>
<div class="absolute bottom-[-20px] left-1/2 -translate-x-1/2 text-[10px] text-gray-500">
PROBABILITY</div>
<!-- Quadrants -->
<div class="absolute inset-0 grid grid-cols-2 grid-rows-2">
<div class="bg-warning/5 border-r border-b border-gray-800/50"></div>
<!-- High Impact, Low Prob -->
<div class="bg-danger/10 border-b border-gray-800/50"></div>
<!-- High Impact, High Prob -->
<div class="bg-success/5 border-r border-gray-800/50"></div>
<!-- Low Impact, Low Prob -->
<div class="bg-warning/5"></div> <!-- Low Impact, High Prob -->
</div>
<!-- Dots -->
<div class="absolute top-[20%] right-[15%] w-3 h-3 bg-danger rounded-full shadow-[0_0_10px_rgba(239,68,68,0.5)] animate-pulse"
title="CRITICAL-001"></div>
<div class="absolute top-[35%] right-[25%] w-3 h-3 bg-danger rounded-full shadow-[0_0_10px_rgba(239,68,68,0.5)]"
title="CRITICAL-002"></div>
<div class="absolute top-[30%] left-[20%] w-2.5 h-2.5 bg-warning rounded-full"
title="HIGH-004"></div>
<div class="absolute bottom-[20%] right-[30%] w-2.5 h-2.5 bg-warning rounded-full"
title="HIGH-005"></div>
<div class="absolute bottom-[30%] left-[30%] w-2 h-2 bg-success rounded-full"
title="LOW-001"></div>
</div>
</div>
</div>
</div>
<!-- Violations Table -->
<div class="mt-8 glass-panel rounded-xl overflow-hidden">
<div class="px-6 py-4 border-b border-border-dark flex items-center justify-between">
<h3 class="font-bold text-lg">Active Violations</h3>
<div class="flex gap-2">
<input type="text" placeholder="Search..."
class="bg-background-dark border border-border-dark rounded px-3 py-1.5 text-sm text-gray-300 focus:outline-none focus:border-primary">
</div>
</div>
<table class="w-full text-sm text-left text-gray-400">
<thead class="text-xs text-gray-500 uppercase bg-surface-dark border-b border-border-dark">
<tr>
<th class="px-6 py-3">ID</th>
<th class="px-6 py-3">Severity</th>
<th class="px-6 py-3">Description</th>
<th class="px-6 py-3">File</th>
<th class="px-6 py-3">Framework</th>
<th class="px-6 py-3 text-right">Action</th>
</tr>
</thead>
<tbody>
<tr
class="bg-surface-dark/20 border-b border-border-dark/50 hover:bg-surface-dark/40 transition-colors">
<td class="px-6 py-4 font-mono text-white">CRIT-001</td>
<td class="px-6 py-4"><span
class="px-2 py-1 rounded-full text-xs font-bold bg-danger/10 text-danger border border-danger/20">CRITICAL</span>
</td>
<td class="px-6 py-4 font-medium text-white">PII Leak in Logs</td>
<td class="px-6 py-4 font-mono text-xs">src/auth/controller.ts:45</td>
<td class="px-6 py-4"><span
class="bg-purple-900/30 text-purple-400 px-1.5 py-0.5 rounded text-xs">LGPD</span>
</td>
<td class="px-6 py-4 text-right">
<button
class="text-primary hover:text-white font-medium hover:underline">Auto-Fix</button>
</td>
</tr>
<tr
class="bg-surface-dark/20 border-b border-border-dark/50 hover:bg-surface-dark/40 transition-colors">
<td class="px-6 py-4 font-mono text-white">CRIT-002</td>
<td class="px-6 py-4"><span
class="px-2 py-1 rounded-full text-xs font-bold bg-danger/10 text-danger border border-danger/20">CRITICAL</span>
</td>
<td class="px-6 py-4 font-medium text-white">Admin Missing Auth</td>
<td class="px-6 py-4 font-mono text-xs">src/routes/admin.ts:12</td>
<td class="px-6 py-4"><span
class="bg-purple-900/30 text-purple-400 px-1.5 py-0.5 rounded text-xs">GDPR</span>
</td>
<td class="px-6 py-4 text-right">
<button
class="text-primary hover:text-white font-medium hover:underline">Auto-Fix</button>
</td>
</tr>
<tr
class="bg-surface-dark/20 border-b border-border-dark/50 hover:bg-surface-dark/40 transition-colors">
<td class="px-6 py-4 font-mono text-white">HIGH-001</td>
<td class="px-6 py-4"><span
class="px-2 py-1 rounded-full text-xs font-bold bg-warning/10 text-warning border border-warning/20">HIGH</span>
</td>
<td class="px-6 py-4 font-medium text-white">Unencrypted Storage</td>
<td class="px-6 py-4 font-mono text-xs">db/models/user.ts:23</td>
<td class="px-6 py-4"><span
class="bg-blue-900/30 text-blue-400 px-1.5 py-0.5 rounded text-xs">PCI-DSS</span>
</td>
<td class="px-6 py-4 text-right">
<button
class="text-primary hover:text-white font-medium hover:underline">Details</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script>
// Chart.js Configuration
const ctx = document.getElementById('trendChart').getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(19, 55, 236, 0.5)');
gradient.addColorStop(1, 'rgba(19, 55, 236, 0)');
new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan 1', 'Jan 5', 'Jan 10', 'Jan 15', 'Jan 20', 'Jan 25', 'Jan 30', 'Feb 5'],
datasets: [{
label: 'Compliance Score',
data: [45, 48, 52, 50, 58, 62, 65, 68],
borderColor: '#1337ec',
backgroundColor: gradient,
borderWidth: 2,
tension: 0.4,
fill: true,
pointBackgroundColor: '#1337ec',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: '#1337ec'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false,
backgroundColor: '#111',
titleColor: '#fff',
bodyColor: '#ccc',
borderColor: '#232948',
borderWidth: 1
}
},
scales: {
y: {
grid: {
color: '#232948',
drawBorder: false
},
ticks: {
color: '#6b7280',
stepSize: 20
},
min: 0,
max: 100
},
x: {
grid: {
display: false
},
ticks: {
color: '#6b7280'
}
}
}
}
});
// LOCAL MODE: Attempt to load scan-results.json
fetch('./scan-results.json')
.then(response => {
if (response.ok) return response.json();
throw new Error('No local scan found');
})
.then(data => {
console.log("Loaded local scan data", data);
// Simple update logic (Proof of Concept)
// In production, we would map all fields.
// For now, let's just log it to prove integration.
alert('Local Scan Data Loaded! Check Console.');
})
.catch(e => console.log('Running in demo mode (no local scan found)'));
</script>
</body>
</html>