Update dashboard filters and packet views

This commit is contained in:
sas.fajri
2026-05-07 12:04:09 +07:00
parent da419950ce
commit 11f0d0436e
17 changed files with 1008 additions and 342 deletions

View File

@@ -162,7 +162,7 @@
</style>
<!-- SSE wrapper — satu koneksi, semua section dapat update otomatis -->
<div hx-ext="sse" sse-connect="{{b "/dashboard/stream"}}?mode=daily&date={{.DateFrom}}">
<div hx-ext="sse" sse-connect="{{b "/dashboard/stream"}}?mode=daily&date={{.DateFrom}}&mcu_id={{.McuID}}">
<!-- Project Banner -->
<section class="card p-5">
@@ -184,11 +184,11 @@
</div>
<div class="flex flex-wrap items-center gap-3">
<a href="{{b "/projects"}}" class="rounded-lg border border-slate-200 bg-white px-3 py-1.5 text-xs font-semibold text-slate-600 transition hover:border-brand-400 hover:text-brand-600">
Ganti project
Change Project
</a>
<form method="get" action="{{b "/dashboard"}}" class="flex flex-wrap items-center gap-2" id="dashboard-filter-form">
<input type="hidden" name="mode" value="daily"/>
<label class="text-xs font-medium text-slate-500">Tanggal Check-in</label>
<label class="text-xs font-medium text-slate-500">Check-in Date</label>
<select name="date"
id="dashboard-date"
onchange="this.form.submit()"
@@ -204,7 +204,7 @@
</select>
<button type="submit"
class="rounded-lg bg-brand-500 px-3 py-1.5 text-xs font-semibold text-white transition hover:bg-brand-600">
Lihat
View
</button>
</form>
</div>
@@ -277,7 +277,7 @@
<span class="sse-running-bar" aria-hidden="true"></span>
<span class="sse-updating-label" aria-hidden="true">Updating...</span>
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-3">
<h2 class="text-sm font-semibold text-slate-700">Station Status</h2>
<h2 class="text-sm font-semibold text-slate-700">Station Status (Check In)</h2>
<span class="flex items-center gap-1.5 text-xs font-medium text-slate-400 animate-pulse">
<span class="h-1.5 w-1.5 rounded-full bg-slate-300"></span> Connecting...
</span>
@@ -350,7 +350,7 @@ function fmtDate(s) {
return d + '/' + m + '/' + y;
}
function openPatientsModal() {
function openPatientsModal(kpiFilter) {
const params = new URLSearchParams(window.location.search);
const modal = document.getElementById('patients-modal');
const body = document.getElementById('patients-modal-body');
@@ -359,6 +359,11 @@ function openPatientsModal() {
const mode = params.get('mode') || 'daily';
const date = params.get('date') || '';
const dateEnd = params.get('date_end') || '';
if (kpiFilter) {
params.set('kpi_filter', kpiFilter);
} else {
params.delete('kpi_filter');
}
if (mode === 'daily') {
subtitle.textContent = date ? 'Tanggal: ' + fmtDate(date) : 'Hari ini';
@@ -375,6 +380,31 @@ function openPatientsModal() {
.catch(() => { body.innerHTML = '<p class="p-6 text-sm text-red-500">Gagal memuat data.</p>'; });
}
window.clearPatientsKpiFilter = function () {
const form = document.getElementById('patients-filter-form');
const body = document.getElementById('patients-modal-body');
if (!form || !body) return;
const params = new URLSearchParams(window.location.search);
const searchInput = form.querySelector('input[name="search"]');
const progressSelect = form.querySelector('select[name="progress_status"]');
const kpiInput = form.querySelector('input[name="kpi_filter"]');
const search = searchInput ? searchInput.value.trim() : '';
const progressStatus = progressSelect ? progressSelect.value.trim() : '';
if (search) params.set('search', search); else params.delete('search');
if (progressStatus) params.set('progress_status', progressStatus); else params.delete('progress_status');
params.delete('kpi_filter');
params.set('page', '1');
if (kpiInput) kpiInput.value = '';
body.innerHTML = '<div class="flex items-center justify-center py-16 text-slate-400"><svg class="h-5 w-5 animate-spin mr-2 text-brand-400" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v8H4z"></path></svg>Memuat data...</div>';
fetch('{{b "/dashboard/patients"}}?' + params.toString())
.then(r => r.text())
.then(html => { body.innerHTML = html; })
.catch(() => { body.innerHTML = '<p class="p-6 text-sm text-red-500">Gagal memuat data.</p>'; });
};
(function() {
const sseTargets = new Set(['sse-kpi', 'sse-stations', 'sse-arrivals']);
const sseEventTargetMap = {