183 lines
7.0 KiB
HTML
183 lines
7.0 KiB
HTML
{{define "title"}}Abnormal Monitoring — CpOne{{end}}
|
|
{{define "header-title"}}Abnormal Monitoring{{end}}
|
|
|
|
{{define "content"}}
|
|
{{$proj := .CurrentProject}}
|
|
{{$group := .Group}}
|
|
|
|
<section class="card p-5">
|
|
<div class="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between">
|
|
<div>
|
|
<p class="text-xs font-semibold uppercase tracking-widest text-brand-500">Ongoing Project</p>
|
|
<h2 class="mt-1 text-lg font-semibold text-slate-900">
|
|
{{if $proj.Label}}{{$proj.Label}}{{else}}MCU #{{$proj.McuID}}{{end}}
|
|
</h2>
|
|
<p class="mt-0.5 text-sm text-slate-500">
|
|
{{$proj.Number}} • {{$proj.CorporateName}} •
|
|
<span class="num">{{$proj.StartDate | fmtDate}}</span> – <span class="num">{{$proj.EndDate | fmtDate}}</span>
|
|
</p>
|
|
</div>
|
|
<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
|
|
</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="card p-3">
|
|
<div class="flex flex-wrap items-center gap-2 text-sm">
|
|
<a href="{{b "/abnormal"}}"
|
|
class="rounded-xl px-4 py-2 font-semibold transition
|
|
{{if eq $group ""}}bg-brand-500 text-white{{else}}border border-brand-500 text-brand-500 hover:bg-brand-50{{end}}">
|
|
Semua Kelainan
|
|
</a>
|
|
{{range .Groups}}
|
|
<a href="{{b "/abnormal"}}?group={{. | urlquery}}"
|
|
class="rounded-xl px-4 py-2 font-semibold transition
|
|
{{if eq . $group}}bg-brand-500 text-white{{else}}border border-brand-500 text-brand-500 hover:bg-brand-50{{end}}">
|
|
{{.}}
|
|
</a>
|
|
{{end}}
|
|
</div>
|
|
</section>
|
|
|
|
<section class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
|
<article class="card border-l-4 border-l-brand-400 p-4">
|
|
<p class="text-xs font-semibold uppercase tracking-widest text-slate-400">Total Peserta</p>
|
|
<p class="num mt-2 text-3xl font-semibold text-slate-900">{{.Summary.Total}}</p>
|
|
<p class="mt-1 text-xs text-slate-400">Peserta aktif dalam project</p>
|
|
</article>
|
|
<article class="card border-l-4 border-l-emerald-400 p-4">
|
|
<p class="text-xs font-semibold uppercase tracking-widest text-slate-400">Normal</p>
|
|
<p class="num mt-2 text-3xl font-semibold text-emerald-600">{{.Summary.Normal}}</p>
|
|
<p class="mt-1 text-xs text-slate-400">Tanpa temuan kelainan</p>
|
|
</article>
|
|
<article class="card border-l-4 border-l-red-400 p-4">
|
|
<p class="text-xs font-semibold uppercase tracking-widest text-slate-400">Abnormal</p>
|
|
<p class="num mt-2 text-3xl font-semibold text-red-500">{{.Summary.Abnormal}}</p>
|
|
<p class="mt-1 text-xs text-slate-400">
|
|
{{if eq $group ""}}Ada temuan kelainan{{else}}Kelainan: {{$group}}{{end}}
|
|
</p>
|
|
</article>
|
|
<article class="card border-l-4 border-l-amber-400 p-4">
|
|
<p class="text-xs font-semibold uppercase tracking-widest text-slate-400">Abnormal Rate</p>
|
|
<p class="num mt-2 text-3xl font-semibold text-amber-600">{{.Summary.AbnormalRate}}%</p>
|
|
<p class="mt-1 text-xs text-slate-400">Persentase dari total peserta</p>
|
|
</article>
|
|
</section>
|
|
|
|
<section class="grid gap-5 xl:grid-cols-2">
|
|
<article class="card p-5">
|
|
<p class="mb-3 text-sm font-semibold text-slate-700">Normal vs Abnormal</p>
|
|
<div id="staff-chart" class="h-72 w-full"></div>
|
|
</article>
|
|
|
|
<article class="card p-5">
|
|
<p class="mb-3 text-sm font-semibold text-slate-700">Distribusi Kelompok Usia</p>
|
|
<div id="age-chart" class="h-72 w-full"></div>
|
|
</article>
|
|
|
|
<article class="card p-5">
|
|
<p class="mb-3 text-sm font-semibold text-slate-700">Gender</p>
|
|
<div id="gender-chart" class="h-72 w-full"></div>
|
|
</article>
|
|
|
|
<article id="dept-wrap" class="card p-5">
|
|
<p class="mb-3 text-sm font-semibold text-slate-700">Departemen</p>
|
|
<div id="dept-chart" class="h-72 w-full"></div>
|
|
</article>
|
|
</section>
|
|
|
|
<script>
|
|
const staffData = {{.StaffJSON}};
|
|
const ageData = {{.AgeJSON}};
|
|
const genderData = {{.GenderJSON}};
|
|
const deptData = {{.DeptJSON}};
|
|
|
|
const normalColor = '#3b50a0';
|
|
const abnormalColor = '#EF4444';
|
|
|
|
const staffEl = document.getElementById('staff-chart');
|
|
const ageEl = document.getElementById('age-chart');
|
|
const genderEl = document.getElementById('gender-chart');
|
|
const deptEl = document.getElementById('dept-chart');
|
|
const deptWrap = document.getElementById('dept-wrap');
|
|
|
|
if (staffEl && typeof echarts !== 'undefined') {
|
|
const staffChart = echarts.init(staffEl);
|
|
staffChart.setOption({
|
|
color: [normalColor, abnormalColor],
|
|
tooltip: { trigger: 'item' },
|
|
legend: { bottom: 0 },
|
|
series: [{
|
|
type: 'pie',
|
|
radius: ['45%', '70%'],
|
|
itemStyle: { borderRadius: 6, borderColor: '#fff', borderWidth: 2 },
|
|
label: { formatter: '{b}: {c}' },
|
|
data: [
|
|
{ value: staffData.normal, name: 'Normal' },
|
|
{ value: staffData.abnormal, name: 'Abnormal' }
|
|
]
|
|
}]
|
|
});
|
|
window.addEventListener('resize', () => staffChart.resize());
|
|
}
|
|
|
|
if (ageEl && ageData && typeof echarts !== 'undefined') {
|
|
const ageChart = echarts.init(ageEl);
|
|
ageChart.setOption({
|
|
color: [abnormalColor],
|
|
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
|
grid: { left: 40, right: 20, top: 20, bottom: 30 },
|
|
xAxis: { type: 'category', data: ageData.labels },
|
|
yAxis: { type: 'value' },
|
|
series: [{ name: 'Abnormal', type: 'bar', data: ageData.abnormal, barMaxWidth: 48 }]
|
|
});
|
|
window.addEventListener('resize', () => ageChart.resize());
|
|
}
|
|
|
|
if (genderEl && genderData && typeof echarts !== 'undefined') {
|
|
const genderChart = echarts.init(genderEl);
|
|
genderChart.setOption({
|
|
color: [normalColor, abnormalColor],
|
|
tooltip: { trigger: 'item' },
|
|
legend: { bottom: 0 },
|
|
series: [{
|
|
type: 'pie',
|
|
radius: ['45%', '70%'],
|
|
itemStyle: { borderRadius: 6, borderColor: '#fff', borderWidth: 2 },
|
|
label: { formatter: '{b}: {c}' },
|
|
data: genderData.labels.map(function(l, i) {
|
|
return { name: l, value: genderData.abnormal[i] };
|
|
})
|
|
}]
|
|
});
|
|
window.addEventListener('resize', () => genderChart.resize());
|
|
}
|
|
|
|
if (deptEl && deptData && deptData.labels && deptData.labels.length > 0 && typeof echarts !== 'undefined') {
|
|
const deptChart = echarts.init(deptEl);
|
|
deptChart.setOption({
|
|
color: [normalColor],
|
|
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
|
|
grid: { left: 8, right: 24, top: 8, bottom: 8, containLabel: true },
|
|
xAxis: { type: 'value' },
|
|
yAxis: {
|
|
type: 'category',
|
|
data: deptData.labels.slice().reverse(),
|
|
axisLabel: { overflow: 'truncate', width: 160 }
|
|
},
|
|
series: [{
|
|
name: 'Abnormal',
|
|
type: 'bar',
|
|
data: deptData.abnormal.slice().reverse(),
|
|
barMaxWidth: 32,
|
|
label: { show: true, position: 'right' }
|
|
}]
|
|
});
|
|
window.addEventListener('resize', () => deptChart.resize());
|
|
} else if (deptWrap) {
|
|
deptWrap.classList.add('hidden');
|
|
}
|
|
</script>
|
|
{{end}}
|