ChickSense / static /index.html
IceKhoffi's picture
Update static/index.html
4592459 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ChickSense</title>
<meta name="description" content="Automatic Health and Welfare Monitoring System for Chickens" />
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body class="p-4 lg:p-5">
<div class="max-w-screen-2x1 mx-auto">
<header class="flex flex-col md:flex-row justify-between items-start md:items-center mb-4 gap-3">
<div class="flex items-center gap-3">
<div class="w-12 h-12 bg-amber-100 rounded-lg flex items-center justify-center border border-amber-200" aria-hidden="true">
<img src="/static/assets/logo-.jpeg" alt="ChickSense Logo" class="rounded-lg">
</div>
<div>
<h1 class="text-xl md:text-2xl font-bold text-slate-800">ChickSense Dashboard</h1>
<p id="datetime" class="text-xs md:text-sm text-slate-500" aria-live="polite">Loading Time...</p>
</div>
</div>
</header>
<main class="grid grid-cols-1 lg:grid-cols-12 gap-4">
<section class="lg:col-span-9 flex flex-col gap-4" aria-label="Video streams and controls">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4" role="region">
<div class="card relative">
<div class="p-2">
<div class="aspect-video bg-slate-800 rounded-md">
<canvas id="video-canvas-0" class="w-full h-full rounded-md"></canvas>
</div>
<div class="cam-badge">CAM 1</div>
</div>
</div>
<div class="card relative">
<div class="p-2">
<div class="aspect-video bg-slate-800 rounded-md">
<canvas id="video-canvas-1" class="w-full h-full rounded-md"></canvas>
</div>
<div class="cam-badge">CAM 2</div>
</div>
</div>
<div class="card relative">
<div class="p-2">
<div class="aspect-video bg-slate-800 rounded-md">
<canvas id="video-canvas-2" class="w-full h-full rounded-md"></canvas>
</div>
<div class="cam-badge">CAM 3</div>
</div>
</div>
<div class="card relative">
<div class="p-2">
<div class="aspect-video bg-slate-800 rounded-md">
<canvas id="video-canvas-3" class="w-full h-full rounded-md"></canvas>
</div>
<div class="cam-badge">CAM 4</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="card" role="region">
<div class="card-header flex items-center justify-between">
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-slate-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5" />
</svg>
<h3 class="font-semibold text-slate-700 text-sm">View Controls</h3>
</div>
<button id="settings-button" title="Double-click to change camera URLs" class="p-1 text-slate-500 hover:text-blue-600 hover:bg-slate-300 rounded-md transition-colors">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg>
</button>
</div>
<div id="toggle-controls" class="p-3 grid grid-cols-3 gap-3">
<button id="toggle-detected" data-control="show_detected" class="control-button flex items-center justify-center gap-2 p-2.5 rounded-lg text-xs md:text-sm font-medium" aria-pressed="true">
<svg class="w-6 h-6 icon-outline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"/>
</svg>
<svg class="w-6 h-6 icon-solid" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" d="M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z" clip-rule="evenodd"/>
</svg>
<span>Detection</span>
</button>
</button>
<button id="toggle-density" data-control="show_density" class="control-button flex items-center justify-center gap-2 p-2.5 rounded-lg text-xs md:text-sm font-medium" aria-pressed="false">
<svg class="w-6 h-6 icon-outline" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512" fill="none" stroke="currentColor" stroke-width="24">
<circle cx="256" cy="256" r="240"/> <circle cx="220" cy="120" r="64"/> <circle cx="356" cy="92" r="34"/> <circle cx="420" cy="160" r="26"/> <circle cx="120" cy="100" r="28"/> <circle cx="104" cy="196" r="44"/> <circle cx="208" cy="240" r="28"/>
<circle cx="320" cy="236" r="44"/> <circle cx="420" cy="236" r="52"/> <circle cx="180" cy="372" r="88"/> <circle cx="300" cy="372" r="40"/> <circle cx="408" cy="372" r="52"/>
<circle cx="272" cy="460" r="28"/> <circle cx="88" cy="288" r="20"/>
</svg>
<svg class="w-6 h-6 icon-solid" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512" fill="none" stroke="currentColor" stroke-width="24">
<circle cx="256" cy="256" r="240"/> <circle cx="220" cy="120" r="64"/> <circle cx="356" cy="92" r="34"/> <circle cx="420" cy="160" r="26"/> <circle cx="120" cy="100" r="28"/> <circle cx="104" cy="196" r="44"/> <circle cx="208" cy="240" r="28"/>
<circle cx="320" cy="236" r="44"/> <circle cx="420" cy="236" r="52"/> <circle cx="180" cy="372" r="88"/> <circle cx="300" cy="372" r="40"/> <circle cx="408" cy="372" r="52"/>
<circle cx="272" cy="460" r="28"/> <circle cx="88" cy="288" r="20"/>
</svg>
<span>Density</span>
</button>
<button id="toggle-inactive" data-control="show_inactive" class="control-button flex items-center justify-center gap-2 p-2.5 rounded-lg text-xs md:text-sm font-medium" aria-pressed="false">
<svg class="w-6 h-6 icon-outline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
<svg class="w-6 h-6 icon-solid" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zM12.75 6a.75.75 0 00-1.5 0v6c0 .414.336.75.75.75h4.5a.75.75 0 000-1.5h-3.75V6z" clip-rule="evenodd"/>
</svg>
<span>Inactivity</span>
</button>
</div>
</div>
<div class="card" role="region">
<div class="card-header flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-slate-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9 5.25h.008v.008H12v-.008z" />
</svg>
<h3 class="font-semibold text-slate-700 text-sm">System Log</h3>
</div>
<div id="system-log" class="p-4 text-xs text-slate-500 space-y-2 h-28 overflow-y-auto" role="log" aria-live="polite"></div>
</div>
</div>
</section>
<aside class="lg:col-span-3 flex flex-col gap-4" aria-label="Analysis and export panels">
<div class="card" role="region">
<div class="card-header flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-blue-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z" />
</svg>
<h3 class="font-semibold text-slate-700 text-sm">Analysis Summary</h3>
</div>
<div class="p-4 space-y-3 text-sm">
<div class="flex items-center gap-3 p-2.5 bg-slate-50 rounded-lg">
<div class="w-9 h-9 bg-blue-100 text-blue-600 rounded-md flex items-center justify-center flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z" />
</svg>
</div>
<div>
<p class="text-slate-500 text-xs font-medium">Total Detected</p>
<p id="detected-count" class="text-lg font-bold text-slate-800">0</p>
</div>
</div>
<div class="flex items-center gap-3 p-2.5 bg-slate-50 rounded-lg">
<div class="w-9 h-9 bg-amber-100 text-amber-600 rounded-md flex items-center justify-center flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="none" stroke="currentColor" stroke-width="24">
<circle cx="256" cy="256" r="240"/> <circle cx="220" cy="120" r="64"/> <circle cx="356" cy="92" r="34"/> <circle cx="420" cy="160" r="26"/> <circle cx="120" cy="100" r="28"/> <circle cx="104" cy="196" r="44"/>
<circle cx="208" cy="240" r="28"/> <circle cx="320" cy="236" r="44"/> <circle cx="420" cy="236" r="52"/> <circle cx="180" cy="372" r="88"/> <circle cx="300" cy="372" r="40"/> <circle cx="408" cy="372" r="52"/>
<circle cx="272" cy="460" r="28"/> <circle cx="88" cy="288" r="20"/>
</svg>
</div>
<div>
<p class="text-slate-500 text-xs font-medium">Density Clusters</p>
<p id="density-count" class="text-lg font-bold text-slate-800">0</p>
</div>
</div>
<div class="flex items-center gap-3 p-2.5 bg-slate-50 rounded-lg">
<div class="w-9 h-9 bg-red-100 text-red-600 rounded-md flex items-center justify-center flex-shrink-0">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div>
<p class="text-slate-500 text-xs font-medium">Inactive Chickens</p>
<p id="inactive-count" class="text-lg font-bold text-slate-800">0</p>
</div>
</div>
</div>
</div>
<div class="card" role="region">
<div class="card-header flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-green-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z" />
</svg>
<h3 class="font-semibold text-slate-700 text-sm">Vocalization Analysis</h3>
</div>
<div id="vocalization-content" class="p-4">
</div>
</div>
<div class="card" role="region">
<div class="card-header flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-slate-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
<h3 class="font-semibold text-slate-700 text-sm">Export Metric Data (CSV)</h3>
</div>
<div class="p-4">
<button id="open-export-modal-btn" class="btn btn-primary w-full text-sm">
Export CSV
</button>
<p class="text-[11px] text-slate-500 mt-2 text-center">Export data by double-clicking the button above.</p>
</div>
</div>
</aside>
</main>
</div>
<div id="settings-modal" class="modal z-50" role="dialog" aria-labelledby="settings-modal-title" aria-hidden="true">
<div class="modal-backdrop"></div>
<div class="modal-container">
<div class="card w-full max-w-lg">
<div class="card-header flex items-center justify-between">
<h3 id="settings-modal-title" class="font-semibold text-slate-700 text-sm">URL Settings</h3>
<button class="modal-close-btn" aria-label="Close">βœ•</button>
</div>
<div class="p-4 space-y-4 text-sm">
<div>
<label for="cam1-url" class="block text-xs font-medium text-slate-600 mb-1">Camera 1 URL</label>
<input type="text" id="cam1-url" class="modal-input" placeholder="Enter URL for Camera 1">
</div>
<div>
<label for="cam2-url" class="block text-xs font-medium text-slate-600 mb-1">Camera 2 URL</label>
<input type="text" id="cam2-url" class="modal-input" placeholder="Enter URL for Camera 2">
</div>
<div>
<label for="cam3-url" class="block text-xs font-medium text-slate-600 mb-1">Camera 3 URL</label>
<input type="text" id="cam3-url" class="modal-input" placeholder="Enter URL for Camera 3">
</div>
<div>
<label for="cam4-url" class="block text-xs font-medium text-slate-600 mb-1">Camera 4 URL</label>
<input type="text" id="cam4-url" class="modal-input" placeholder="Enter URL for Camera 4">
</div>
<hr class="border-slate-200">
<div>
<label for="audio-url" class="block text-xs font-medium text-slate-600 mb-1">Audio URL</label>
<input type="text" id="audio-url" class="modal-input" placeholder="Enter URL for Audio Source">
</div>
<div class="flex justify-end gap-2 pt-2">
<button id="stop-all-streams-btn" class="btn bg-red-600 hover:bg-red-700 text-white text-sm">Stop All Streams</button>
<button id="save-settings-btn" class="btn btn-primary text-sm">Save & Restart</button>
</div>
</div>
</div>
</div>
</div>
<div id="export-modal" class="modal z-50" role="dialog" aria-labelledby="export-modal-title" aria-hidden="true">
<div class="modal-backdrop"></div>
<div class="modal-container">
<div class="card w-full max-w-md">
<div class="card-header flex items-center justify-between">
<h3 id="export-modal-title" class="font-semibold text-slate-700 text-sm">Export Metric Data</h3>
<button class="modal-close-btn" aria-label="Close">βœ•</button>
</div>
<div class="p-4 space-y-3 text-sm">
<div>
<label for="start-date" class="block text-xs font-medium text-slate-600 mb-1">Start Date</label>
<input type="date" id="start-date" class="modal-input">
</div>
<div>
<label for="end-date" class="block text-xs font-medium text-slate-600 mb-1">End Date</label>
<input type="date" id="end-date" class="modal-input">
</div>
<div>
<label for="camera-select" class="block text-xs font-medium text-slate-600 mb-1">Select Camera</label>
<select id="camera-select" class="modal-input bg-white">
<option value="">All Cameras</option>
<option value="1">Camera 1</option>
<option value="2">Camera 2</option>
<option value="3">Camera 3</option>
<option value="4">Camera 4</option>
</select>
</div>
<button id="download-csv-btn" class="btn btn-primary w-full">Download CSV</button>
</div>
</div>
</div>
</div>
<script src="/static/js/app.js"></script>
</body>
</html>