Change: user sets date of previous calibration, not upcoming expire dates.

- seismograph list page enhanced with better visabilty, filtering, sorting, and calibration dates color coded.
This commit is contained in:
serversdwn
2026-02-06 21:17:14 +00:00
parent eb0a99796d
commit 89662d2fa5
8 changed files with 408 additions and 86 deletions

View File

@@ -27,25 +27,50 @@
<!-- Seismograph List -->
<div class="rounded-xl shadow-lg bg-white dark:bg-slate-800 p-6">
<div class="mb-4 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>
<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"
hx-get="/api/seismo-dashboard/units"
hx-trigger="keyup changed delay:300ms"
hx-target="#seismo-units-list"
hx-include="[name='search']"
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>
<!-- 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>
@@ -59,17 +84,53 @@
</div>
<script>
// Clear search input on escape key
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('seismo-search');
if (searchInput) {
searchInput.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
this.value = '';
htmx.trigger(this, 'keyup');
}
});
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>