From 0c8b9d16671359bc884bec8c43d5ae7fdce6beba Mon Sep 17 00:00:00 2001 From: amal Date: Tue, 17 Mar 2026 15:38:44 +0800 Subject: [PATCH] upd: api noc --- src/server/routes/noc_route.ts | 164 +++++++++++++++++++++++++++++++-- 1 file changed, 154 insertions(+), 10 deletions(-) diff --git a/src/server/routes/noc_route.ts b/src/server/routes/noc_route.ts index 9fd3aa4..869a1a4 100644 --- a/src/server/routes/noc_route.ts +++ b/src/server/routes/noc_route.ts @@ -58,13 +58,13 @@ const NocRoute = new Elysia({ }, { detail: { - summary: "Get jumlah surat minggu ini dan kenaikan dari minggu lalu", + summary: "Jumlah surat minggu ini dan kenaikan dari minggu lalu", description: `tool untuk mendapatkan jumlah surat minggu ini dan persentase kenaikan dibandingkan minggu lalu`, } }) .get("/pengaduan-count", async () => { - const [antrian, diterima, dikerjakan] = await Promise.all([ + const [antrian, diterima, dikerjakan, ditolak, selesai] = await Promise.all([ prisma.pengaduan.count({ where: { isActive: true, @@ -82,6 +82,18 @@ const NocRoute = new Elysia({ isActive: true, status: "diterima", } + }), + prisma.pengaduan.count({ + where: { + isActive: true, + status: "ditolak", + } + }), + prisma.pengaduan.count({ + where: { + isActive: true, + status: "selesai", + } }) ]); @@ -89,18 +101,21 @@ const NocRoute = new Elysia({ antrian, diterima, dikerjakan, - total: antrian + diterima + dikerjakan + ditolak, + selesai, + aktif: antrian + diterima + dikerjakan, + total: antrian + diterima + dikerjakan + ditolak + selesai }; }, { detail: { - summary: "Get jumlah pengaduan antrian, diterima dan dikerjakan", - description: "Menghitung jumlah pengaduan yang berstatus antrian dan sedang dikerjakan (diproses)", + summary: "Jumlah pengaduan antrian, diterima, dikerjakan, ditolak dan selesai", + description: "Menghitung jumlah pengaduan yang sedang aktif (antrian, diterima, dikerjakan), dan total (termasuk ditolak dan selesai)", } }) .get("/pelayanan-count", async () => { const now = new Date(); - + // Bulan ini const startOfThisMonth = new Date(now.getFullYear(), now.getMonth(), 1); const endOfThisMonth = new Date(now.getFullYear(), now.getMonth() + 1, 1); @@ -145,8 +160,8 @@ const NocRoute = new Elysia({ }; }, { detail: { - summary: "Get total pelayananAjuan selesai bulan ini dan kenaikan dari bulan lalu", - description: "Menampilkan total pelayananAjuan yang telah berstatus selesai bulan ini dan persentase kenaikan dari bulan lalu", + summary: "Total pelayanan selesai bulan ini dan kenaikan dari bulan lalu", + description: "Menampilkan total pelayanan yang telah berstatus selesai bulan ini dan persentase kenaikan dari bulan lalu", } }) @@ -166,7 +181,7 @@ const NocRoute = new Elysia({ for (let i = 3; i >= 0; i--) { const startOfWeek = new Date(startOfCurrentWeek); startOfWeek.setDate(startOfCurrentWeek.getDate() - (i * 7)); - + const endOfWeek = new Date(startOfWeek); endOfWeek.setDate(startOfWeek.getDate() + 7); @@ -207,9 +222,138 @@ const NocRoute = new Elysia({ return results; }, { detail: { - summary: "Get history total pengajuan surat", + summary: "Total pengajuan surat 6 bulan / 4 minggu", description: "Menampilkan total pengajuan surat selama 6 bulan terakhir atau 4 minggu terakhir", } }) + .get("/pengaduan-history", async ({ query }) => { + const { period = "6months" } = query as { period?: string }; + const now = new Date(); + const results: { label: string; total: number }[] = []; + + if (period === "7days") { + for (let i = 6; i >= 0; i--) { + const startOfDay = new Date(now); + startOfDay.setDate(now.getDate() - i); + startOfDay.setHours(0, 0, 0, 0); + + const endOfDay = new Date(startOfDay); + endOfDay.setDate(startOfDay.getDate() + 1); + + const count = await prisma.pengaduan.count({ + where: { + isActive: true, + createdAt: { + gte: startOfDay, + lt: endOfDay, + } + } + }); + + const label = startOfDay.toLocaleDateString('id-ID', { weekday: 'long' }); + results.push({ label, total: count }); + } + } else { + // Default 6 months + for (let i = 5; i >= 0; i--) { + const startOfMonth = new Date(now.getFullYear(), now.getMonth() - i, 1); + const endOfMonth = new Date(now.getFullYear(), now.getMonth() - i + 1, 1); + + const count = await prisma.pengaduan.count({ + where: { + isActive: true, + createdAt: { + gte: startOfMonth, + lt: endOfMonth, + } + } + }); + + const monthName = startOfMonth.toLocaleString('id-ID', { month: 'long' }); + results.push({ label: monthName, total: count }); + } + } + + return results; + }, { + detail: { + summary: "Total pengaduan 6 bulan / 7 hari", + description: "Menampilkan total pengaduan selama 6 bulan terakhir atau 7 hari terakhir", + } + }) + + .get("/pelayanan-perjenis", async () => { + const categories = await prisma.categoryPelayanan.findMany({ + where: { + isActive: true + }, + select: { + name: true, + _count: { + select: { + SuratPelayanan: { + where: { + isActive: true + } + } + } + } + } + }); + + return categories + .map(cat => ({ + jenis: cat.name, + jumlah: cat._count.SuratPelayanan + })) + .sort((a, b) => b.jumlah - a.jumlah); + }, { + detail: { + summary: "Jumlah surat berdasarkan jenis", + description: "Menampilkan jumlah surat berdasarkan jenis/kategori pelayanan", + } + }) + + .get("/pengajuan-terbaru", async () => { + const applications = await prisma.pelayananAjuan.findMany({ + where: { + isActive: true + }, + take: 5, + orderBy: { + createdAt: "desc" + }, + include: { + Warga: true, + CategoryPelayanan: true + } + }); + + const formatDuration = (date: Date) => { + const diff = Math.floor((new Date().getTime() - date.getTime()) / 1000); + if (diff < 60) return `${diff} detik yang lalu`; + if (diff < 3600) return `${Math.floor(diff / 60)} menit yang lalu`; + if (diff < 86400) return `${Math.floor(diff / 3600)} jam yang lalu`; + if (diff < 604800) return `${Math.floor(diff / 86400)} hari yang lalu`; + return date.toLocaleDateString("id-ID", { + day: "numeric", + month: "long", + year: "numeric" + }); + }; + + return applications.map(app => ({ + jenis: app.CategoryPelayanan.name, + status: app.status, + namaWarga: app.Warga.name, + durasi: formatDuration(app.createdAt) + })); + }, { + detail: { + summary: "5 data pengajuan surat terbaru", + description: "Menampilkan 5 data pengajuan surat terbaru beserta status, nama warga, dan durasi pengajuan", + } + }) + export default NocRoute