Initial commit
This commit is contained in:
182
cpone-dashboard/templates/abnormal/index.html
Normal file
182
cpone-dashboard/templates/abnormal/index.html
Normal file
@@ -0,0 +1,182 @@
|
||||
{{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}}
|
||||
Reference in New Issue
Block a user