From 5fd5c15394bd0837be5a4643071b61e6cb8faa99 Mon Sep 17 00:00:00 2001 From: amal Date: Tue, 7 Apr 2026 17:25:14 +0800 Subject: [PATCH] upd: api monitoring detail desa --- src/app/api/monitoring/[[...slug]]/route.ts | 331 +++++++++++++++++++- 1 file changed, 330 insertions(+), 1 deletion(-) diff --git a/src/app/api/monitoring/[[...slug]]/route.ts b/src/app/api/monitoring/[[...slug]]/route.ts index ee629c8..12c7fa5 100644 --- a/src/app/api/monitoring/[[...slug]]/route.ts +++ b/src/app/api/monitoring/[[...slug]]/route.ts @@ -291,8 +291,337 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) }, } ) + .get( + "/info-villages", + async ({ query, set }) => { + const { id } = query; + try { + const data = await prisma.village.findUnique({ + where: { + id: id, + }, + select: { + id: true, + name: true, + isActive: true, + createdAt: true, + User: { + where: { + idUserRole: "supadmin" + }, + select: { + name: true, + }, + take: 1, + }, + }, + }) - ; + if (!data) { + set.status = 404; + return { + success: false, + message: "Desa tidak ditemukan", + data: null, + }; + } + + const result = data ? { + id: data?.id, + name: data?.name, + isActive: data?.isActive, + createdAt: data?.createdAt ? formatDateTime(data.createdAt) : null, + perbekel: data?.User[0]?.name || null, + } : null; + + return { + success: true, + message: "Berhasil mendapatkan data", + data: result, + }; + } catch (error) { + console.error("[detail-villages] info-villages error:", error); + set.status = 500; + return { + success: false, + message: "Terjadi kesalahan pada server", + data: null, + }; + } + }, + { + query: t.Object({ + id: t.Optional(t.String({ description: "ID desa" })), + }), + detail: { + summary: "Info Villages", + description: "Menu Detail Villages - Mendapatkan info data desa untuk header dan kolom Informasi Sistem.", + tags: ["detail-villages"], + }, + } + ) + .get( + "/grid-villages", + async ({ query, set }) => { + const { id } = query; + + try { + const village = await prisma.village.findUnique({ + where: { id: id } + }); + + if (!village) { + set.status = 404; + return { + success: false, + message: "Desa tidak ditemukan", + data: null, + }; + } + + const dataUser = await prisma.user.findMany({ + where: { + idVillage: id, + NOT: { + idUserRole: "developer" + } + } + }) + + const dataGroup = await prisma.group.findMany({ + where: { + idVillage: id, + } + }) + + const dataDivision = await prisma.division.findMany({ + where: { + idVillage: id, + } + }) + + const dataProject = await prisma.project.findMany({ + where: { + idVillage: id + } + }) + + + const result = { + user: { + active: dataUser.filter((user) => user.isActive).length, + nonActive: dataUser.filter((user) => !user.isActive).length, + }, + group: { + active: dataGroup.filter((group) => group.isActive).length, + nonActive: dataGroup.filter((group) => !group.isActive).length, + }, + division: { + active: dataDivision.filter((division) => division.isActive).length, + nonActive: dataDivision.filter((division) => !division.isActive).length, + }, + project: { + active: dataProject.filter((project) => project.isActive).length, + nonActive: dataProject.filter((project) => !project.isActive).length, + } + }; + + return { + success: true, + message: "Berhasil mendapatkan data", + data: result, + }; + } catch (error) { + console.error("[detail-villages] grid-villages error:", error); + set.status = 500; + return { + success: false, + message: "Terjadi kesalahan pada server", + data: null, + }; + } + }, + { + query: t.Object({ + id: t.Optional(t.String({ description: "ID desa" })), + }), + detail: { + summary: "Grid Villages", + description: "Menu Grid Villages - Mendapatkan info data desa untuk 4 grid untuk halaman detail desa.", + tags: ["detail-villages"], + }, + } + ) + .get("/log-villages", async ({ query, set }) => { + const { id, time } = query; + + try { + const village = await prisma.village.findUnique({ + where: { id }, + }); + + if (!village) { + set.status = 404; + return { + success: false, + message: "Desa tidak ditemukan", + data: null, + }; + } + + const now = new Date(); + let startDate: Date; + + if (time === "daily") { + startDate = new Date(); + startDate.setDate(now.getDate() - 13); // 14 hari + } else if (time === "monthly") { + startDate = new Date(now.getFullYear(), 0, 1); // awal tahun + } else if (time === "yearly") { + startDate = new Date(now.getFullYear() - 4, 0, 1); // 5 tahun terakhir (opsional) + } else { + startDate = new Date(0); + } + + const dataLog = await prisma.userLog.findMany({ + where: { + createdAt: { + gte: startDate, + }, + User: { + idVillage: id, + }, + }, + select: { + createdAt: true, + }, + }); + + // ========================= + // 🔥 GROUPING + // ========================= + const map: Record = {}; + + dataLog.forEach((log) => { + const date = new Date(log.createdAt); + + let label = ""; + + if (time === "daily") { + label = date.toLocaleDateString("id-ID", { + day: "2-digit", + month: "short", + }); + } else if (time === "monthly") { + label = date.toLocaleDateString("id-ID", { + month: "short", + }); + } else if (time === "yearly") { + label = date.getFullYear().toString(); + } + + map[label] = (map[label] || 0) + 1; + }); + + // ========================= + // 🔥 FORMAT FINAL + // ========================= + let result: any[] = []; + + if (time === "daily") { + for (let i = 13; i >= 0; i--) { + const d = new Date(); + d.setDate(d.getDate() - i); + + const label = d.toLocaleDateString("id-ID", { + day: "2-digit", + month: "short", + }); + + result.push({ + label, + aktivitas: map[label] || 0, + }); + } + } else if (time === "monthly") { + const year = now.getFullYear(); + for (let m = 0; m <= 11; m++) { + const d = new Date(year, m, 1); + + const label = d.toLocaleDateString("id-ID", { + month: "short", + }); + + result.push({ + label, + aktivitas: map[label] || 0, + }); + } + } else if (time === "yearly") { + const years = Object.keys(map).map(Number); + + if (years.length === 0) { + const currentYear = new Date().getFullYear(); + + result = [ + { label: currentYear.toString(), aktivitas: 0 } + ]; + } else { + const minYear = Math.min(...years); + const maxYear = Math.max(...years); + + result = []; + + for (let y = minYear; y <= maxYear; y++) { + const label = y.toString(); + + result.push({ + label, + aktivitas: map[label] || 0, + }); + } + } + } + + return { + success: true, + message: "Berhasil mendapatkan data", + data: result, + }; + } catch (error) { + console.error("[log-villages] error:", error); + set.status = 500; + return { + success: false, + message: "Terjadi kesalahan pada server", + data: null, + }; + } + }, + { + query: t.Object({ + id: t.String({ description: "ID desa" }), + time: t.Enum( + { + daily: "daily", + monthly: "monthly", + yearly: "yearly", + }, + { + description: "Rentang waktu (daily = 14 hari, monthly = 1 tahun, yearly = per tahun)", + } + ), + }), + detail: { + summary: "Log Villages", + description: + "Mendapatkan data log aktivitas desa berdasarkan rentang waktu (harian, bulanan, tahunan)", + tags: ["detail-villages"], + }, + } + ); + +; export const GET = MonitoringServer.handle;