diff --git a/src/app/api/monitoring/[[...slug]]/route.ts b/src/app/api/monitoring/[[...slug]]/route.ts index 12c7fa5..63a79ef 100644 --- a/src/app/api/monitoring/[[...slug]]/route.ts +++ b/src/app/api/monitoring/[[...slug]]/route.ts @@ -1,4 +1,5 @@ import formatDateTime from "@/lib/formatDateTime"; +import timeAgo from "@/lib/timeAgo"; import { prisma } from "@/module/_global"; import cors from "@elysiajs/cors"; import { swagger } from "@elysiajs/swagger"; @@ -452,7 +453,7 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) }, } ) - .get("/log-villages", async ({ query, set }) => { + .get("/graph-log-villages", async ({ query, set }) => { const { id, time } = query; try { @@ -589,7 +590,7 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) data: result, }; } catch (error) { - console.error("[log-villages] error:", error); + console.error("[graph-log-villages] error:", error); set.status = 500; return { success: false, @@ -612,11 +613,136 @@ const MonitoringServer = new Elysia({ prefix: "/api/monitoring" }) } ), }), + detail: { + summary: "Graph Log Villages", + description: + "Mendapatkan data grafik log aktivitas desa berdasarkan rentang waktu (harian, bulanan, tahunan)", + tags: ["detail-villages"], + }, + } + ) + .get("/log-all-villages", async ({ query, set }) => { + const { page = 1, search } = query; + const pageNum = Number(page) || 1; + const take = 15; + const skip = (pageNum - 1) * take; + + try { + const dataLog = await prisma.userLog.findMany({ + where: { + ...(search && { + OR: [ + { + User: { + name: { + contains: search, + mode: "insensitive", + }, + }, + }, + { + User: { + Village: { + name: { + contains: search, + mode: "insensitive", + }, + }, + }, + }, + ], + }), + }, + select: { + id: true, + createdAt: true, + action: true, + desc: true, + User: { + select: { + name: true, + Village: { + select: { + name: true, + }, + }, + }, + }, + }, + orderBy: { + createdAt: "desc", + }, + skip, + take, + }); + + const total = await prisma.userLog.count({ + where: { + ...(search && { + OR: [ + { + User: { + name: { + contains: search, + mode: "insensitive", + }, + }, + }, + { + User: { + Village: { + name: { + contains: search, + mode: "insensitive", + }, + }, + }, + }, + ], + }), + }, + }); + + const result = dataLog.map((item) => ({ + id: item.id, + createdAt: timeAgo(item.createdAt), + action: item.action, + desc: item.desc, + username: item.User.name, + village: item.User.Village.name, + })); + + + return { + success: true, + message: "Berhasil mendapatkan data", + data: { + log: result, + total, + totalPage: Math.ceil(total / take), + currentPage: pageNum, + }, + }; + } catch (error) { + console.error("[log-villages] error:", error); + set.status = 500; + return { + success: false, + message: "Terjadi kesalahan pada server", + data: null, + }; + } + }, + { + query: t.Object({ + page: t.Optional(t.String({ description: "Halaman" })), + search: t.Optional(t.String({ description: "Pencarian" })), + }), detail: { summary: "Log Villages", description: - "Mendapatkan data log aktivitas desa berdasarkan rentang waktu (harian, bulanan, tahunan)", - tags: ["detail-villages"], + "Mendapatkan data log aktivitas desa berdasarkan halaman dan pencarian", + tags: ["log-activity"], }, } ); diff --git a/src/lib/timeAgo.ts b/src/lib/timeAgo.ts new file mode 100644 index 0000000..9695f78 --- /dev/null +++ b/src/lib/timeAgo.ts @@ -0,0 +1,38 @@ +function timeAgo(date: Date) { + const now = new Date(); + const d = new Date(date); + + const diffMs = now.getTime() - d.getTime(); + const seconds = Math.floor(diffMs / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + + // 🔥 cek apakah masih hari yang sama + const isToday = + now.getDate() === d.getDate() && + now.getMonth() === d.getMonth() && + now.getFullYear() === d.getFullYear(); + + if (isToday) { + if (seconds < 60) return `${seconds} detik lalu`; + if (minutes < 60) return `${minutes} menit lalu`; + return `${hours} jam lalu`; + } + + // 🔥 kalau bukan hari ini → tampil tanggal + jam + const time = d.toLocaleTimeString("id-ID", { + hour: "2-digit", + minute: "2-digit", + }); + + const datePart = d.toLocaleDateString("id-ID", { + day: "2-digit", + month: "short", + year: "numeric", + }); + + return `${time} ${datePart}`; +} + + +export default timeAgo \ No newline at end of file