- seismograph list page enhanced with better visabilty, filtering, sorting, and calibration dates color coded.
138 lines
5.5 KiB
HTML
138 lines
5.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Seismographs - Seismo Fleet Manager{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="mb-8">
|
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-white">Seismographs</h1>
|
|
<p class="text-gray-600 dark:text-gray-400 mt-1">Manage and monitor seismograph units</p>
|
|
</div>
|
|
|
|
<!-- Auto-refresh stats every 30 seconds -->
|
|
<div hx-get="/api/seismo-dashboard/stats"
|
|
hx-trigger="load, every 30s"
|
|
hx-swap="innerHTML"
|
|
class="mb-8">
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
<div class="rounded-lg shadow bg-white dark:bg-slate-800 p-6">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<p class="text-gray-600 dark:text-gray-400 text-sm">Loading...</p>
|
|
<p class="text-3xl font-bold text-gray-900 dark:text-white mt-2">--</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Seismograph List -->
|
|
<div class="rounded-xl shadow-lg bg-white dark:bg-slate-800 p-6">
|
|
<div class="mb-4 flex flex-col gap-4">
|
|
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
|
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">All Seismographs</h2>
|
|
|
|
<!-- Search Box -->
|
|
<div class="relative">
|
|
<input
|
|
type="text"
|
|
id="seismo-search"
|
|
placeholder="Search seismographs..."
|
|
class="w-full sm:w-64 px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
name="search"
|
|
/>
|
|
<svg class="absolute right-3 top-2.5 w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters -->
|
|
<div class="flex flex-wrap items-center gap-3">
|
|
<span class="text-sm text-gray-600 dark:text-gray-400">Filter:</span>
|
|
|
|
<!-- Status Filter -->
|
|
<select id="seismo-status-filter" name="status"
|
|
class="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
|
<option value="">All Status</option>
|
|
<option value="deployed">Deployed</option>
|
|
<option value="benched">Benched</option>
|
|
</select>
|
|
|
|
<!-- Modem Filter -->
|
|
<select id="seismo-modem-filter" name="modem"
|
|
class="px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-transparent">
|
|
<option value="">All Modems</option>
|
|
<option value="with">With Modem</option>
|
|
<option value="without">Without Modem</option>
|
|
</select>
|
|
|
|
<!-- Clear Filters Button -->
|
|
<button id="seismo-clear-filters" type="button"
|
|
class="px-3 py-1.5 text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white">
|
|
Clear Filters
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Units List (loaded via HTMX) -->
|
|
<div id="seismo-units-list"
|
|
hx-get="/api/seismo-dashboard/units"
|
|
hx-trigger="load"
|
|
hx-swap="innerHTML">
|
|
<p class="text-gray-500 dark:text-gray-400">Loading seismographs...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const searchInput = document.getElementById('seismo-search');
|
|
const statusFilter = document.getElementById('seismo-status-filter');
|
|
const modemFilter = document.getElementById('seismo-modem-filter');
|
|
const clearBtn = document.getElementById('seismo-clear-filters');
|
|
const unitsList = document.getElementById('seismo-units-list');
|
|
|
|
// Build URL with current filter values
|
|
function buildUrl() {
|
|
const params = new URLSearchParams();
|
|
if (searchInput.value) params.set('search', searchInput.value);
|
|
if (statusFilter.value) params.set('status', statusFilter.value);
|
|
if (modemFilter.value) params.set('modem', modemFilter.value);
|
|
return '/api/seismo-dashboard/units' + (params.toString() ? '?' + params.toString() : '');
|
|
}
|
|
|
|
// Trigger HTMX refresh
|
|
function refreshList() {
|
|
htmx.ajax('GET', buildUrl(), {target: '#seismo-units-list', swap: 'innerHTML'});
|
|
}
|
|
|
|
// Search input with debounce
|
|
let debounceTimer;
|
|
searchInput.addEventListener('input', function() {
|
|
clearTimeout(debounceTimer);
|
|
debounceTimer = setTimeout(refreshList, 300);
|
|
});
|
|
|
|
// Clear search on escape
|
|
searchInput.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
this.value = '';
|
|
refreshList();
|
|
}
|
|
});
|
|
|
|
// Filter changes
|
|
statusFilter.addEventListener('change', refreshList);
|
|
modemFilter.addEventListener('change', refreshList);
|
|
|
|
// Clear all filters
|
|
clearBtn.addEventListener('click', function() {
|
|
searchInput.value = '';
|
|
statusFilter.value = '';
|
|
modemFilter.value = '';
|
|
refreshList();
|
|
});
|
|
});
|
|
</script>
|
|
|
|
{% endblock %}
|