| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Dashboard - NETRA</title> |
| <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}"> |
| <link rel="stylesheet" href="{{ url_for('static', filename='css/dark-theme.css') }}"> |
| <style> |
| .dashboard-card { |
| transition: var(--transition); |
| } |
| |
| .dashboard-card:hover { |
| animation: slideInUp 0.3s ease; |
| } |
| </style> |
| </head> |
| <body> |
| |
| <div id="toast-container"></div> |
|
|
| |
| <nav class="navbar"> |
| <div class="nav-container"> |
| <div class="nav-brand"> |
| <span class="brand-icon">👁️</span> |
| <span>NETRA</span> |
| </div> |
| <button class="hamburger-menu" id="hamburger-toggle"> |
| <span></span> |
| <span></span> |
| <span></span> |
| </button> |
| <div class="nav-menu" id="nav-menu"> |
| <a href="{{ url_for('dashboard') }}" class="nav-link" style="opacity: 0.7;">Dashboard</a> |
| <div class="dropdown" id="analysis-dropdown"> |
| <button class="nav-link dropdown-btn" onclick="toggleDropdown(event)">📊 Analysis ▼</button> |
| <div class="dropdown-content"> |
| <a href="{{ url_for('live_camera') }}" onclick="showLoadingToast()">📹 Live Camera</a> |
| <a href="{{ url_for('video_analysis') }}" onclick="showLoadingToast()">📋 Video Analysis</a> |
| </div> |
| </div> |
| <span class="user-greeting">👋 Welcome, {{ username }}!</span> |
| <a href="{{ url_for('logout') }}" class="btn btn-outline">Logout</a> |
| </div> |
| </div> |
| </nav> |
| |
| <div class="dashboard-container"> |
| |
| <div class="dashboard-header reveal" style="animation: slideInDown 0.6s ease both;"> |
| <h1>📊 Video Surveillance Dashboard</h1> |
| <p>Real-time threat detection and analysis</p> |
| </div> |
|
|
| |
| <div class="info-section reveal" style="margin-bottom: 2rem;"> |
| <div class="info-card" style="animation: slideInUp 0.6s ease 0.1s both; animation-fill-mode: both;"> |
| <h3>✅ System Health</h3> |
| <p>All monitoring services are active and ready</p> |
| <span class="status-chip ok">Operational</span> |
| </div> |
| <div class="info-card" style="animation: slideInUp 0.6s ease 0.2s both; animation-fill-mode: both;"> |
| <h3>⚡ Threat Engine</h3> |
| <p>YOLO and weapon detection pipeline initialized</p> |
| <span class="status-chip info">Realtime Enabled</span> |
| </div> |
| <div class="info-card" style="animation: slideInUp 0.6s ease 0.3s both; animation-fill-mode: both;"> |
| <h3>🚨 Incident Response</h3> |
| <p>Critical events are prioritized with immediate alerts</p> |
| <span class="status-chip warn">High Priority</span> |
| </div> |
| </div> |
| |
| |
| <div class="dashboard-grid reveal"> |
| |
| <div class="dashboard-card" style="animation: slideInLeft 0.6s ease 0.2s both;"> |
| <div class="card-icon"> |
| <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="animation: slideInDown 0.5s ease;"> |
| <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path> |
| <circle cx="12" cy="13" r="4"></circle> |
| </svg> |
| </div> |
| <h2>Live Camera Feed</h2> |
| <p>Monitor real-time camera feeds with advanced AI detection and instant alerts</p> |
| <ul class="feature-list"> |
| <li>🎯 Real-time object detection</li> |
| <li>⚠️ Violence & activity recognition</li> |
| <li>🚨 Instant alert notifications</li> |
| <li>🤖 Multi-model AI analysis</li> |
| </ul> |
| <a href="{{ url_for('live_camera') }}" class="btn btn-primary" style="width: 100%; margin-top: 1rem;" onclick="showLoadingToast()">▶️ Start Live Monitoring</a> |
| </div> |
| |
| |
| <div class="dashboard-card" style="animation: slideInRight 0.6s ease 0.2s both;"> |
| <div class="card-icon"> |
| <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="animation: slideInDown 0.5s ease;"> |
| <polygon points="23 7 16 12 23 17 23 7"></polygon> |
| <rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect> |
| </svg> |
| </div> |
| <h2>Video Analysis</h2> |
| <p>Upload and analyze pre-recorded video files with comprehensive detection reports</p> |
| <ul class="feature-list"> |
| <li>📁 Upload video files (MP4, AVI, MOV)</li> |
| <li>🔍 Frame-by-frame analysis</li> |
| <li>📈 Comprehensive detection reports</li> |
| <li>⏱️ Detection timeline visualization</li> |
| </ul> |
| <a href="{{ url_for('video_analysis') }}" class="btn btn-primary" style="width: 100%; margin-top: 1rem;" onclick="showLoadingToast()">📹 Analyze Video</a> |
| </div> |
| </div> |
| |
| |
| <div class="models-section reveal" style="animation: slideInUp 0.6s ease 0.4s both;"> |
| <h2>🤖 Active AI Models</h2> |
| <div class="models-grid" id="models-container"> |
| <div class="model-badge" style="opacity: 0.6;"> |
| <span class="spinner" style="width: 12px; height: 12px;"></span> |
| Loading models... |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="info-section reveal" style="animation: slideInUp 0.6s ease 0.5s both;"> |
| <div class="info-card"> |
| <h3>🔒 Secure & Private</h3> |
| <p>Your data is processed locally and securely stored with enterprise-grade encryption</p> |
| </div> |
| <div class="info-card"> |
| <h3>⚡ High Performance</h3> |
| <p>Real-time processing with optimized GPU-accelerated AI models for instant analysis</p> |
| </div> |
| <div class="info-card"> |
| <h3>🔧 Extensible</h3> |
| <p>Easily integrate new detection models and customize for your specific needs</p> |
| </div> |
| </div> |
|
|
| |
| <div style="margin-top: 2rem; animation: slideInUp 0.6s ease 0.6s both;"> |
| <div style="border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--glass); backdrop-filter: blur(8px); padding: 1.5rem; text-align: center;"> |
| <h3 style="color: var(--blue-900); margin-bottom: 1rem;">Quick Stats</h3> |
| <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem;"> |
| <div> |
| <div style="font-size: 2rem; color: var(--blue-700); font-weight: 800;">4+</div> |
| <div style="color: var(--slate-700); font-size: 0.9rem;">Active AI Models</div> |
| </div> |
| <div> |
| <div style="font-size: 2rem; color: var(--blue-700); font-weight: 800;">99%+</div> |
| <div style="color: var(--slate-700); font-size: 0.9rem;">Detection Accuracy</div> |
| </div> |
| <div> |
| <div style="font-size: 2rem; color: var(--blue-700); font-weight: 800;">24/7</div> |
| <div style="color: var(--slate-700); font-size: 0.9rem;">Continuous Monitoring</div> |
| </div> |
| <div> |
| <div style="font-size: 2rem; color: var(--blue-700); font-weight: 800;"><1s</div> |
| <div style="color: var(--slate-700); font-size: 0.9rem;">Detection Latency</div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| </div> |
|
|
| |
| <script src="{{ url_for('static', filename='js/ui-utils.js') }}"></script> |
| |
| <script> |
| |
| const hamburger = document.getElementById('hamburger-toggle'); |
| const navMenu = document.getElementById('nav-menu'); |
| |
| if (hamburger) { |
| hamburger.addEventListener('click', function(e) { |
| e.stopPropagation(); |
| hamburger.classList.toggle('active'); |
| navMenu.classList.toggle('active'); |
| }); |
| } |
| |
| |
| document.querySelectorAll('.nav-link, .nav-menu a').forEach(link => { |
| link.addEventListener('click', function() { |
| hamburger.classList.remove('active'); |
| navMenu.classList.remove('active'); |
| }); |
| }); |
| |
| |
| document.addEventListener('click', function(e) { |
| if (!e.target.closest('.nav-container')) { |
| hamburger?.classList.remove('active'); |
| navMenu?.classList.remove('active'); |
| } |
| }); |
| |
| |
| function toggleDropdown(e) { |
| e.preventDefault(); |
| const dropdown = e.target.closest('.dropdown'); |
| dropdown.classList.toggle('active'); |
| } |
| |
| |
| function showLoadingToast() { |
| toast.info('🔄 Loading...', 1500); |
| } |
| |
| |
| const revealItems = document.querySelectorAll('.reveal'); |
| const io = new IntersectionObserver((entries) => { |
| entries.forEach((entry) => { |
| if (entry.isIntersecting) { |
| entry.target.style.opacity = '1'; |
| entry.target.style.transform = 'translateY(0)'; |
| } |
| }); |
| }, { threshold: 0.1 }); |
| |
| revealItems.forEach((item) => { |
| item.style.opacity = '0'; |
| item.style.transform = 'translateY(20px)'; |
| item.style.transition = 'opacity 0.6s ease, transform 0.6s ease'; |
| io.observe(item); |
| }); |
| |
| |
| async function loadModels() { |
| try { |
| const response = await fetch('/api/models'); |
| const data = await response.json(); |
| const container = document.getElementById('models-container'); |
| |
| if (data.models && data.models.length > 0) { |
| container.innerHTML = data.models.map((model, index) => |
| `<div class="model-badge" style="animation: slideInRight 0.4s ease ${index * 0.1}s both;"> |
| <span style="font-size: 1rem;">🤖</span> |
| <span>${model}</span> |
| </div>` |
| ).join(''); |
| } else { |
| container.innerHTML = '<div class="model-badge">📦 No models loaded</div>'; |
| } |
| } catch (error) { |
| console.error('Error loading models:', error); |
| document.getElementById('models-container').innerHTML = |
| '<div class="model-badge" style="color: var(--danger);">⚠️ Failed to load models</div>'; |
| } |
| } |
| |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', loadModels); |
| } else { |
| loadModels(); |
| } |
| |
| |
| console.log('✅ Dashboard loaded successfully'); |
| </script> |
| </body> |
| </html> |
|
|