NextNVR/public/index.html
cclohmar a54ff08ebb feat: storage health monitor with UI alert on drive loss
Detect a disconnected or read-only recordings drive and surface it
without stopping recording or live view:

- storage.go: probe path existence, mount point, writability and free
  space every 30s; capture mount expectation at startup so a clean
  unmount (writes falling through to root fs) is also caught
- GET /api/storage endpoint; storage fields in /api/status
- red UI banner while storage is unavailable
- log ALERT on loss, OK on recovery
2026-10-10 07:17:28 +01:00

76 lines
3.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="nextnvr-role" content="">
<title>NextNVR</title>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<header class="topbar">
<h1>🎥 NextNVR</h1>
<nav id="tabs">
<button data-tab="live" class="tab active">Live Wall</button>
<button data-tab="playback" class="tab">Playback</button>
<button data-tab="settings" class="tab">Settings</button>
</nav>
<span id="status-dot" class="status offline" title="Server status">●</span>
</header>
<div id="storage-alert" class="storage-alert hidden"></div>
<main id="content">
<!-- Live Wall: 4×2 grid + focus overlay -->
<section id="tab-live" class="tab-panel active">
<div id="grid" class="grid-4x2"></div>
<div id="focus-overlay" class="focus-overlay hidden">
<div class="focus-bar">
<button id="focus-close">✕ Close</button>
</div>
<iframe id="focus-frame" class="focus-frame" allow="autoplay"></iframe>
</div>
</section>
<!-- Playback: clip browser -->
<section id="tab-playback" class="tab-panel">
<div class="playback-controls">
<select id="pb-camera"><option value="">— Select Camera —</option></select>
<div class="preset-group">
<button class="preset active" data-preset="today">Today</button>
<button class="preset" data-preset="yesterday">Yesterday</button>
<button class="preset" data-preset="week">Last 7 Days</button>
<button class="preset" data-preset="custom">Custom ▾</button>
</div>
<div id="pb-custom-range" class="hidden" style="display:flex;gap:8px;align-items:center">
<input type="date" id="pb-from">
<span>→</span>
<input type="date" id="pb-to">
</div>
<button id="pb-load" class="btn-primary">Load Clips</button>
</div>
<div id="pb-clips" class="clip-grid"></div>
<div id="pb-player" class="clip-player hidden">
<video id="pb-video" controls></video>
<div style="display:flex;gap:8px;margin-top:12px">
<button id="pb-download" class="btn-primary">⬇ Download</button>
<button id="pb-close">✕ Close</button>
</div>
</div>
</section>
<!-- Settings: camera configuration & onboarding -->
<section id="tab-settings" class="tab-panel">
<div class="settings-toolbar">
<button id="btn-scan" class="btn-primary">🔍 Scan Network (ONVIF)</button>
<button id="btn-save" class="btn-success">💾 Save Configuration</button>
<span id="settings-status"></span>
</div>
<div id="camera-cards"></div>
<div id="scan-results" class="scan-results hidden"></div>
</section>
</main>
<script src="/app.js"></script>
</body>
</html>