Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>FocusFlow | Real-Time Meeting Analytics</title> | |
| <link rel="stylesheet" href="/static/style.css?v=1.3"> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Playfair+Display:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet"> | |
| <script src="https://unpkg.com/lucide@latest"></script> | |
| </head> | |
| <body> | |
| <div class="ambient-glow top-right"></div> | |
| <div class="ambient-glow bottom-left"></div> | |
| <div class="app-container"> | |
| <!-- Sidebar --> | |
| <aside class="sidebar"> | |
| <div class="logo"> | |
| <div class="logo-icon"><i data-lucide="target" style="width:28px; height:28px; stroke-width: 2;"></i></div> | |
| <h1 >FocusFlow</h1> | |
| </div> | |
| <nav class="nav-menu"> | |
| <button class="nav-btn active" id="btn-dashboard"> | |
| <span class="icon"><i data-lucide="layout-dashboard"></i></span> Dashboard | |
| </button> | |
| <button class="nav-btn" id="btn-live"> | |
| <span class="icon"><i data-lucide="video"></i></span> Live Analysis | |
| </button> | |
| <button class="nav-btn" id="btn-meeting"> | |
| <span class="icon"><i data-lucide="users"></i></span> Meeting Intel | |
| </button> | |
| <button class="nav-btn" id="btn-history"> | |
| <span class="icon"><i data-lucide="history"></i></span> History | |
| </button> | |
| </nav> | |
| <div class="tech-stack glass-panel"> | |
| <h3>TECH STACK</h3> | |
| <ul> | |
| <li><span class="icon"><i data-lucide="server" style="width:16px;height:16px;"></i></span> FastAPI Backend</li> | |
| <li><span class="icon"><i data-lucide="eye" style="width:16px;height:16px;"></i></span> MediaPipe Vision</li> | |
| <li><span class="icon"><i data-lucide="zap" style="width:16px;height:16px;"></i></span> C++ / PyBind11</li> | |
| <li><span class="icon"><i data-lucide="database" style="width:16px;height:16px;"></i></span> SQLite Storage</li> | |
| </ul> | |
| </div> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="main-content"> | |
| <!-- Header --> | |
| <header class="top-header"> | |
| <div class="header-titles"> | |
| <h2 id="page-title">Live Analysis</h2> | |
| <p id="page-subtitle">Real-Time Engagement Tracking</p> | |
| </div> | |
| <div class="session-controls"> | |
| <div id="status-indicator" class="status-indicator"> | |
| <div class="dot red"></div> <span id="recording-time">00:00</span> | |
| </div> | |
| <button class="btn btn-primary" id="btn-start"><i data-lucide="play" style="width: 16px; height: 16px;"></i> Start Session</button> | |
| <button class="btn btn-danger hidden" id="btn-stop"><i data-lucide="square" style="width: 16px; height: 16px;"></i> Stop Session</button> | |
| </div> | |
| </header> | |
| <!-- Dashboard View --> | |
| <section id="view-dashboard" class="view hidden"> | |
| <div class="welcome-box glass-panel"> | |
| <h2>Welcome to FocusFlow</h2> | |
| <p>FocusFlow is a real-time meeting analytics tool that tracks visual engagement during video calls. It uses advanced computer vision and C++ extensions to compute your focus score dynamically.</p> | |
| </div> | |
| <div class="dashboard-grid"> | |
| <div class="stat-card glass-panel highlight"> | |
| <span class="icon"><i data-lucide="check-circle"></i></span> | |
| <div class="value" id="dash-total-sessions">0</div> | |
| <div class="label">Total Sessions</div> | |
| </div> | |
| <div class="stat-card glass-panel highlight"> | |
| <span class="icon"><i data-lucide="trending-up"></i></span> | |
| <div class="value" id="dash-avg-focus">0%</div> | |
| <div class="label">Avg. Focus</div> | |
| </div> | |
| <div class="stat-card glass-panel highlight"> | |
| <span class="icon"><i data-lucide="clock"></i></span> | |
| <div class="value" id="dash-focus-time">0m</div> | |
| <div class="label">Focus Time</div> | |
| </div> | |
| </div> | |
| <div class="quick-actions" style="display: flex; justify-content: center; margin-top: 24px;"> | |
| <button class="btn btn-primary" onclick="document.getElementById('btn-live').click()">Start New Session</button> | |
| <button class="btn btn-secondary" onclick="document.getElementById('btn-meeting').click()" style="margin-left: 12px;">Meeting Intelligence</button> | |
| </div> | |
| </section> | |
| <!-- Live Analysis View --> | |
| <section id="view-live" class="view active"> | |
| <div class="grid-layout"> | |
| <!-- Video Section --> | |
| <div class="video-section"> | |
| <div class="video-container glass-panel"> | |
| <video id="webcam" autoplay playsinline muted></video> | |
| <canvas id="overlay"></canvas> | |
| <div id="video-overlay" class="video-overlay"> | |
| <div class="icon"><i data-lucide="camera-off" style="width:40px;height:40px;stroke-width:1.5;"></i></div> | |
| <p>Click Start Session to begin analyzing</p> | |
| </div> | |
| </div> | |
| <!-- Alerts --> | |
| <div id="alert-banner" class="alert-banner hidden"> | |
| ⚠️ WAKE UP ALERT | |
| </div> | |
| </div> | |
| <!-- Metrics Section --> | |
| <div class="metrics-section"> | |
| <!-- Hero Score --> | |
| <div class="hero-score-card glass-panel"> | |
| <h3 class="label">Engagement Score</h3> | |
| <div class="score-value" id="engagement-score">--</div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" id="engagement-bar" style="width: 0%"></div> | |
| </div> | |
| <p class="status-text" id="status-text">FOCUSED</p> | |
| </div> | |
| <!-- Quick Stats Grid --> | |
| <div class="stats-grid mt-20"> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="activity"></i></span> | |
| <div class="value" id="yawn-count">0</div> | |
| <div class="label">Yawns</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="moon"></i></span> | |
| <div class="value" id="drowsy-count">0</div> | |
| <div class="label">Sleep Events</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="zap"></i></span> | |
| <div class="value" id="ear-value">0.00</div> | |
| <div class="label">EAR</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon" id="emotion-icon"><i data-lucide="smile"></i></span> | |
| <div class="value emotion" id="emotion-label">Neutral</div> | |
| <div class="label">Emotion</div> | |
| </div> | |
| </div> | |
| <!-- Deep Metrics --> | |
| <div class="deep-metrics glass-panel mt-20"> | |
| <h3>Face Analytics</h3> | |
| <div class="metrics-list"> | |
| <div class="metric-item"> | |
| <span class="label">Gaze Score</span> | |
| <span class="value" id="gaze-score">--%</span> | |
| </div> | |
| <div class="metric-item"> | |
| <span class="label">Head Stability</span> | |
| <span class="value" id="stability-score">--%</span> | |
| </div> | |
| <div class="metric-item"> | |
| <span class="label">Face Quality</span> | |
| <span class="value" id="quality-score">--%</span> | |
| </div> | |
| <div class="metric-item"> | |
| <span class="label">Attention</span> | |
| <span class="value" id="attention-score">--%</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Meeting View --> | |
| <section id="view-meeting" class="view hidden"> | |
| <div class="grid-layout"> | |
| <div class="video-section"> | |
| <div id="meeting-setup" class="welcome-box glass-panel"> | |
| <h3><i data-lucide="users" style="vertical-align: middle; margin-right: 8px;"></i> Meeting Intelligence</h3> | |
| <p>Track aggregate engagement for professional meetings. This mode is optimized for multiple participants and provides group dynamics analysis.</p> | |
| <div class="mt-20"> | |
| <label style="font-size: 14px; color: var(--text-muted);">Meeting Title</label> | |
| <input type="text" id="meeting-title" placeholder="Project Sync..." style="width: 100%; padding: 12px; margin-top: 8px; border: 1px solid var(--border); border-radius: 8px; background: white; font-family: inherit;"> | |
| </div> | |
| <div class="mt-20" style="display: flex; gap: 10px;"> | |
| <button class="btn btn-primary" id="btn-start-meeting">Start with Camera</button> | |
| <button class="btn btn-secondary" id="btn-share-screen"><i data-lucide="monitor" style="width: 16px; height: 16px; vertical-align: middle; margin-right: 4px;"></i> Share Screen</button> | |
| </div> | |
| </div> | |
| <!-- Video container for active meeting --> | |
| <div id="meeting-active-video" class="video-container glass-panel hidden" style="height: 400px; position:relative;"> | |
| <video id="meeting-video" autoplay playsinline muted style="width: 100%; height: 100%; object-fit: cover; border-radius: 12px;"></video> | |
| <div class="video-overlay" id="meeting-video-label" style="background: rgba(0,0,0,0.4); color: white; position: absolute; bottom: 10px; left: 10px; padding: 5px 10px; border-radius: 4px; font-size: 12px;">Active Meeting Feed</div> | |
| </div> | |
| </div> | |
| <div class="metrics-section"> | |
| <div class="hero-score-card glass-panel"> | |
| <h3 class="label">Group Engagement</h3> | |
| <div class="score-value" id="meeting-avg-score">--</div> | |
| <div class="progress-bar"> | |
| <div class="progress-fill" id="meeting-engagement-bar" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| <!-- Same stats grid as Live view --> | |
| <div class="stats-grid mt-20"> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="user-check"></i></span> | |
| <div class="value" id="participant-count">0</div> | |
| <div class="label">Participants</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="alert-circle"></i></span> | |
| <div class="value" id="meeting-warnings">0</div> | |
| <div class="label">Distractions</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="activity"></i></span> | |
| <div class="value" id="meeting-yawn-count">0</div> | |
| <div class="label">Yawns</div> | |
| </div> | |
| <div class="stat-card glass-panel"> | |
| <span class="icon"><i data-lucide="moon"></i></span> | |
| <div class="value" id="meeting-drowsy-count">0</div> | |
| <div class="label">Sleep</div> | |
| </div> | |
| </div> | |
| <!-- Same deep metrics as Live view --> | |
| <div class="deep-metrics glass-panel mt-20"> | |
| <h3>Meeting Analytics</h3> | |
| <div class="metrics-list"> | |
| <div class="metric-item"> | |
| <span class="label">Group Gaze</span> | |
| <span class="value" id="meeting-gaze-score">--%</span> | |
| </div> | |
| <div class="metric-item"> | |
| <span class="label">Avg Attention</span> | |
| <span class="value" id="meeting-attention-score">--%</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- History View --> | |
| <section id="view-history" class="view hidden"> | |
| <div class="history-container glass-panel"> | |
| <div class="history-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;"> | |
| <h2>Recent Sessions</h2> | |
| <div class="tabs" style="display: flex; gap: 10px;"> | |
| <button class="btn btn-sm active" id="tab-individual">Individual</button> | |
| <button class="btn btn-sm" id="tab-meetings">Meetings</button> | |
| </div> | |
| </div> | |
| <div id="history-list" class="history-list"> | |
| <!-- Sessions inserted dynamically --> | |
| <div class="text-center" style="padding: 40px; color: var(--text-muted)"> | |
| Loading sessions... | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <script src="/static/script.js"></script> | |
| </body> | |
| </html> | |