@@ -274,6 +283,7 @@
const overviewData = {{.OverviewJSON}};
const stationData = {{.DepartmentJSON}};
+ const paketData = {{.PaketChartJSON}};
const deptColors = ['#f59e0b', '#8b5cf6', '#f97316', '#06b6d4', '#ec4899', '#84cc16', '#14b8a6'];
const overviewEl = document.getElementById('arrival-overview-chart');
@@ -307,7 +317,7 @@
show: !isMobile,
type: 'scroll',
orient: 'vertical',
- left: '58%',
+ left: '68%',
right: 0,
top: 'middle',
textStyle: { color: '#64748b', fontSize: 11 },
@@ -321,7 +331,7 @@
name: 'Check-in Summary',
type: 'pie',
radius: ['28%', '45%'],
- center: isMobile ? ['50%', '50%'] : ['38%', '48%'],
+ center: isMobile ? ['50%', '50%'] : ['30%', '48%'],
label: { show: false },
labelLine: { show: false },
data: [
@@ -333,7 +343,7 @@
name: 'Dept Detail',
type: 'pie',
radius: ['55%', '72%'],
- center: isMobile ? ['50%', '50%'] : ['38%', '48%'],
+ center: isMobile ? ['50%', '50%'] : ['30%', '48%'],
label: { show: false },
labelLine: { show: false },
data: outerData
@@ -370,6 +380,63 @@
});
window.addEventListener('resize', () => stationChart.resize());
}
+
+ const paketEl = document.getElementById('paket-distribution-chart');
+ if (paketEl && paketData && typeof echarts !== 'undefined') {
+ const paketChart = echarts.init(paketEl);
+ var paketLabels = (paketData.labels || []).slice().reverse();
+ var paketDone = (paketData.done || []).slice().reverse();
+ var paketRemaining = (paketData.remaining || []).slice().reverse();
+ paketChart.setOption({
+ color: ['#10b981', '#cbd5e1'],
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ var done = 0;
+ var remaining = 0;
+ for (var i = 0; i < params.length; i++) {
+ if (params[i].seriesName === 'Completed') done = params[i].value || 0;
+ if (params[i].seriesName === 'Not Completed') remaining = params[i].value || 0;
+ }
+ var total = done + remaining;
+ return params[0].name + '
Total: ' + total + '
Completed: ' + done + '
Not Completed: ' + remaining;
+ }
+ },
+ legend: {
+ bottom: 0,
+ textStyle: { color: '#64748b', fontSize: 11 }
+ },
+ grid: { left: 10, right: 20, top: 10, bottom: 32, containLabel: true },
+ xAxis: {
+ type: 'value',
+ axisLabel: { color: '#64748b' }
+ },
+ yAxis: {
+ type: 'category',
+ axisLabel: { color: '#64748b' },
+ data: paketLabels
+ },
+ series: [
+ {
+ name: 'Completed',
+ type: 'bar',
+ stack: 'total',
+ barWidth: 18,
+ data: paketDone
+ },
+ {
+ name: 'Not Completed',
+ type: 'bar',
+ stack: 'total',
+ barWidth: 18,
+ data: paketRemaining,
+ itemStyle: { borderRadius: [0, 6, 6, 0] }
+ }
+ ]
+ });
+ window.addEventListener('resize', () => paketChart.resize());
+ }
})();
{{end}}
@@ -382,21 +449,30 @@
{{.NIP}} |
{{.Name}} |
{{.Department}} |
+
+ {{if .Pemeriksaan}}{{.Pemeriksaan}}{{else}}-{{end}}
+ |
- {{if .Stations}}
-
- {{range .Stations}}
- {{if eq .Tone "success"}}
- {{.Name}}
- {{else if eq .Tone "warning"}}
- {{.Name}}
- {{else if eq .Tone "danger"}}
- {{.Name}}
- {{else}}
- {{.Name}}
- {{end}}
- {{end}}
-
+ {{if not .InTime}}
+ Not Check-In Yet
+ {{else if .Stations}}
+
+
+
+ {{if gt .DoneCount 0}} Done ({{.DoneCount}}){{end}}
+ {{if gt .ProgressCount 0}} In Progress ({{.ProgressCount}}){{end}}
+ {{if gt .PendingCount 0}} Pending ({{.PendingCount}}){{end}}
+
+
+
+
+ {{range .Stations}}
+ {{if eq .Tone "success"}}{{.Name}}
+ {{else if eq .Tone "warning"}}{{.Name}}
+ {{else}}{{.Name}}{{end}}
+ {{end}}
+
+
{{else}}
{{if eq .StatusTone "success"}}
{{.Status}}
@@ -411,52 +487,53 @@
{{end}}
-
+
{{range .FilteredRows}}
-
+
{{.Name}}
{{if .InTime}}{{.InTime}}{{else}}-{{end}} • {{.NIP}} • {{.Department}}
-
- {{if .Stations}}
- {{range .Stations}}
- {{if eq .Tone "success"}}
-
-
- {{.Name}}
-
- {{else if eq .Tone "warning"}}
-
-
- {{.Name}}
-
- {{else if eq .Tone "danger"}}
-
-
- {{.Name}}
-
- {{else}}
-
-
- {{.Name}}
-
- {{end}}
- {{end}}
+ {{if .Pemeriksaan}} {{.Pemeriksaan}} {{end}}
+
+ {{if not .InTime}}
+ Not Check-In Yet
+ {{else if .Stations}}
+
+
+
+ {{if gt .DoneCount 0}} Done ({{.DoneCount}}){{end}}
+ {{if gt .ProgressCount 0}} In Progress ({{.ProgressCount}}){{end}}
+ {{if gt .PendingCount 0}} Pending ({{.PendingCount}}){{end}}
+
+
+
+
+ {{range .Stations}}
+ {{if eq .Tone "success"}}
+
+
+ {{.Name}}
+
+ {{else if eq .Tone "warning"}}
+
+
+ {{.Name}}
+
+ {{else}}
+
+
+ {{.Name}}
+
+ {{end}}
+ {{end}}
+
+
{{else}}
{{if eq .StatusTone "success"}}
-
-
- {{.Status}}
-
+ {{.Status}}
{{else if eq .StatusTone "warning"}}
-
-
- {{.Status}}
-
+ {{.Status}}
{{else}}
-
-
- {{.Status}}
-
+ {{.Status}}
{{end}}
{{end}}
@@ -467,7 +544,7 @@
{{if .HasMore}}
diff --git a/cpone-dashboard/templates/dashboard/index.html b/cpone-dashboard/templates/dashboard/index.html
index ecfb0bb..d8dcd55 100644
--- a/cpone-dashboard/templates/dashboard/index.html
+++ b/cpone-dashboard/templates/dashboard/index.html
@@ -162,7 +162,7 @@
-
+
@@ -277,7 +277,7 @@
Updating...
- Station Status
+ Station Status (Check In)
Connecting...
@@ -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 = ' Gagal memuat data. '; });
}
+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 = ' ';
+ fetch('{{b "/dashboard/patients"}}?' + params.toString())
+ .then(r => r.text())
+ .then(html => { body.innerHTML = html; })
+ .catch(() => { body.innerHTML = ' Gagal memuat data. '; });
+};
+
(function() {
const sseTargets = new Set(['sse-kpi', 'sse-stations', 'sse-arrivals']);
const sseEventTargetMap = {
diff --git a/cpone-dashboard/templates/dashboard/partials/arrivals.html b/cpone-dashboard/templates/dashboard/partials/arrivals.html
index 9d9fe0f..0387391 100644
--- a/cpone-dashboard/templates/dashboard/partials/arrivals.html
+++ b/cpone-dashboard/templates/dashboard/partials/arrivals.html
@@ -7,9 +7,9 @@
Live
{{end}}
-
diff --git a/cpone-dashboard/templates/dashboard/partials/kpi.html b/cpone-dashboard/templates/dashboard/partials/kpi.html
index fce8c92..ca605f8 100644
--- a/cpone-dashboard/templates/dashboard/partials/kpi.html
+++ b/cpone-dashboard/templates/dashboard/partials/kpi.html
@@ -1,6 +1,6 @@
{{define "kpi"}}
-
+
Invited Staff
|