Deskripsi: - view file pada detail pengaduan - view file pada detail pelayanan surat - close modal file jika error No Issues
279 lines
7.3 KiB
TypeScript
279 lines
7.3 KiB
TypeScript
import Elysia from "elysia";
|
|
import { getLastUpdated } from "../lib/get-last-updated";
|
|
import { prisma } from "../lib/prisma";
|
|
|
|
const DashboardRoute = new Elysia({
|
|
prefix: "dashboard",
|
|
tags: ["dashboard"],
|
|
})
|
|
|
|
.get("/count", async () => {
|
|
// ---- RANGE HARI INI ----
|
|
const now = new Date();
|
|
|
|
const startOfToday = new Date(now);
|
|
startOfToday.setHours(0, 0, 0, 0);
|
|
|
|
const endOfToday = new Date(now);
|
|
endOfToday.setHours(23, 59, 59, 999);
|
|
|
|
// ---- RANGE KEMARIN ----
|
|
const yesterday = new Date(now);
|
|
yesterday.setDate(yesterday.getDate() - 1);
|
|
|
|
const startOfYesterday = new Date(yesterday);
|
|
startOfYesterday.setHours(0, 0, 0, 0);
|
|
|
|
const endOfYesterday = new Date(yesterday);
|
|
endOfYesterday.setHours(23, 59, 59, 999);
|
|
|
|
// ---- QUERY ----
|
|
|
|
const dataWarga = await prisma.warga.count();
|
|
|
|
// Pengaduan
|
|
const dataPengaduanToday = await prisma.pengaduan.count({
|
|
where: {
|
|
isActive: true,
|
|
status: "antrian",
|
|
createdAt: {
|
|
gte: startOfToday,
|
|
lte: endOfToday,
|
|
},
|
|
},
|
|
});
|
|
|
|
const dataPengaduanYesterday = await prisma.pengaduan.count({
|
|
where: {
|
|
isActive: true,
|
|
status: "antrian",
|
|
createdAt: {
|
|
gte: startOfYesterday,
|
|
lte: endOfYesterday,
|
|
},
|
|
},
|
|
});
|
|
|
|
const kenaikanPengaduan =
|
|
dataPengaduanYesterday === 0
|
|
? dataPengaduanToday > 0
|
|
? dataPengaduanToday * 100
|
|
: 0
|
|
: ((dataPengaduanToday - dataPengaduanYesterday) / dataPengaduanYesterday) * 100;
|
|
|
|
// Pelayanan
|
|
const dataPelayananToday = await prisma.pelayananAjuan.count({
|
|
where: {
|
|
isActive: true,
|
|
status: "antrian",
|
|
createdAt: {
|
|
gte: startOfToday,
|
|
lte: endOfToday,
|
|
},
|
|
},
|
|
});
|
|
|
|
const dataPelayananYesterday = await prisma.pelayananAjuan.count({
|
|
where: {
|
|
isActive: true,
|
|
status: "antrian",
|
|
createdAt: {
|
|
gte: startOfYesterday,
|
|
lte: endOfYesterday,
|
|
},
|
|
},
|
|
});
|
|
|
|
const kenaikanPelayanan =
|
|
dataPelayananYesterday === 0
|
|
? dataPelayananToday > 0
|
|
? dataPelayananToday * 100
|
|
: 0
|
|
: ((dataPelayananToday - dataPelayananYesterday) / dataPelayananYesterday) * 100;
|
|
|
|
// ---- FINAL OUTPUT ----
|
|
|
|
const dataFix = {
|
|
warga: dataWarga,
|
|
pengaduan: {
|
|
today: dataPengaduanToday,
|
|
yesterday: dataPengaduanYesterday,
|
|
kenaikan: Number(kenaikanPengaduan.toFixed(2)), // dalam persen
|
|
},
|
|
pelayanan: {
|
|
today: dataPelayananToday,
|
|
yesterday: dataPelayananYesterday,
|
|
kenaikan: Number(kenaikanPelayanan.toFixed(2)), // dalam persen
|
|
},
|
|
};
|
|
|
|
return dataFix;
|
|
|
|
}, {
|
|
detail: {
|
|
summary: "Dashboard - Menghitung Data",
|
|
description: `tool untuk menghitung data pengaduan dan pelayanan yg masuk hari ini dan data warga`,
|
|
}
|
|
})
|
|
.get("/last-update", async () => {
|
|
const dataPengaduan = await prisma.pengaduan.findMany({
|
|
skip: 0,
|
|
take: 5,
|
|
orderBy: {
|
|
updatedAt: "desc",
|
|
},
|
|
})
|
|
|
|
const dataPengaduanFix = dataPengaduan.map((item) => {
|
|
return {
|
|
noPengaduan: item.noPengaduan,
|
|
id: item.id,
|
|
title: item.title,
|
|
status: item.status,
|
|
updatedAt: 'terakhir diperbarui ' + getLastUpdated(item.updatedAt),
|
|
}
|
|
})
|
|
|
|
const dataPelayanan = await prisma.pelayananAjuan.findMany({
|
|
skip: 0,
|
|
take: 5,
|
|
orderBy: {
|
|
updatedAt: "desc",
|
|
},
|
|
select: {
|
|
id: true,
|
|
status: true,
|
|
noPengajuan: true,
|
|
updatedAt: true,
|
|
CategoryPelayanan: {
|
|
select: {
|
|
name: true,
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
const dataPelayananFix = dataPelayanan.map((item) => {
|
|
return {
|
|
id: item.id,
|
|
noPengajuan: item.noPengajuan,
|
|
title: item.CategoryPelayanan.name,
|
|
status: item.status,
|
|
updatedAt: 'terakhir diperbarui ' + getLastUpdated(item.updatedAt),
|
|
}
|
|
})
|
|
|
|
|
|
|
|
const dataFix = {
|
|
pengaduan: dataPengaduanFix,
|
|
pelayanan: dataPelayananFix,
|
|
}
|
|
|
|
return dataFix;
|
|
}, {
|
|
detail: {
|
|
summary: "Dashboard - List data pengaduan dan pelayanan terupdate",
|
|
description: `tool untuk mendapatkan list data pengaduan dan pelayanan yg terupdate`,
|
|
}
|
|
})
|
|
.get("/grafik", async () => {
|
|
const now = new Date();
|
|
|
|
const start7Days = new Date(now);
|
|
start7Days.setDate(start7Days.getDate() - 7);
|
|
start7Days.setHours(0, 0, 0, 0);
|
|
|
|
const endToday = new Date(now);
|
|
endToday.setHours(23, 59, 59, 999);
|
|
|
|
// Ambil semua data pengaduan & pelayanan dalam 7 hari
|
|
const pengaduan = await prisma.pengaduan.findMany({
|
|
where: {
|
|
createdAt: {
|
|
gte: start7Days,
|
|
lte: endToday,
|
|
},
|
|
isActive: true
|
|
},
|
|
select: {
|
|
createdAt: true
|
|
}
|
|
});
|
|
|
|
|
|
const pelayanan = await prisma.pelayananAjuan.findMany({
|
|
where: {
|
|
createdAt: {
|
|
gte: start7Days,
|
|
lte: endToday,
|
|
},
|
|
isActive: true
|
|
},
|
|
select: {
|
|
createdAt: true
|
|
}
|
|
});
|
|
|
|
// --- BUAT RANGE TANGGAL 7 HARI ---
|
|
const resultMap: Record<string, { pengaduan: number; pelayanan: number }> = {};
|
|
|
|
for (let i = 0; i < 8; i++) {
|
|
const d = new Date(start7Days);
|
|
d.setDate(d.getDate() + i);
|
|
|
|
const formatted = d.toLocaleDateString("id-ID", {
|
|
day: "numeric",
|
|
month: "long"
|
|
});
|
|
|
|
resultMap[formatted] = { pengaduan: 0, pelayanan: 0 };
|
|
}
|
|
|
|
// --- HITUNG PENGADUAN PER HARI ---
|
|
pengaduan.forEach((item) => {
|
|
const t = item.createdAt.toLocaleDateString("id-ID", {
|
|
day: "numeric",
|
|
month: "long"
|
|
});
|
|
|
|
if (resultMap[t]) {
|
|
resultMap[t].pengaduan += 1;
|
|
}
|
|
});
|
|
|
|
// --- HITUNG PELAYANAN PER HARI ---
|
|
pelayanan.forEach((item) => {
|
|
const t = item.createdAt.toLocaleDateString("id-ID", {
|
|
day: "numeric",
|
|
month: "long"
|
|
});
|
|
|
|
if (resultMap[t]) {
|
|
resultMap[t].pelayanan += 1;
|
|
}
|
|
});
|
|
|
|
// --- KONVERSI KE FORMAT FINAL ---
|
|
const source = Object.keys(resultMap).map((tanggal) => ({
|
|
tanggal,
|
|
pengaduan: resultMap[tanggal]?.pengaduan,
|
|
pelayanan: resultMap[tanggal]?.pelayanan,
|
|
}));
|
|
|
|
return {
|
|
dimensions: ["tanggal", "pengaduan", "pelayanan"],
|
|
source,
|
|
};
|
|
}, {
|
|
detail: {
|
|
summary: "Dashboard - Grafik data pengaduan dan pelayanan",
|
|
description: `tool untuk mendapatkan grafik data pengaduan dan pelayanan`,
|
|
}
|
|
})
|
|
;
|
|
|
|
;
|
|
|
|
export default DashboardRoute
|