From 7e7856c32affb623df04822bb151c81f4659008e Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 31 Jan 2025 11:40:30 +0800 Subject: [PATCH 1/2] Add API Dashboard Donasi & Fix UI Dashboard --- .../admin/donasi/dashboard/[name]/route.ts | 5 +- src/app/dev/admin/donasi/main/page.tsx | 6 +- .../_component/comp_admin_modal_publish.tsx | 2 + .../_component/comp_admin_modal_report.tsx | 3 + .../donasi/detail/publish/detail_publish.tsx | 62 ++++---- .../donasi/lib/api_fetch_admin_donasi.ts | 26 +++- src/app_modules/admin/donasi/main/index.tsx | 145 +++++++++++++++--- .../admin/donasi/sub_menu/table_kategori.tsx | 19 +-- .../admin/donasi/sub_menu/table_publish.tsx | 33 ++-- .../admin/donasi/sub_menu/table_reject.tsx | 29 ++-- .../admin/investasi/detail/detail_review.tsx | 4 +- .../admin/investasi/main/table_reject.tsx | 23 ++- .../admin/vote/child/riwayat/index.tsx | 33 ++-- .../admin/vote/child/table_publish/index.tsx | 32 ++-- .../admin/vote/child/table_reject/index.tsx | 37 +++-- .../admin/vote/child/table_review/index.tsx | 31 ++-- src/app_modules/admin/vote/main/index.tsx | 35 +++-- src/middleware.ts | 1 + 18 files changed, 331 insertions(+), 195 deletions(-) diff --git a/src/app/api/admin/donasi/dashboard/[name]/route.ts b/src/app/api/admin/donasi/dashboard/[name]/route.ts index 16a64c4a..61118d40 100644 --- a/src/app/api/admin/donasi/dashboard/[name]/route.ts +++ b/src/app/api/admin/donasi/dashboard/[name]/route.ts @@ -25,6 +25,9 @@ export async function GET(request: Request, { params }: { where: { DonasiMaster_Status: { name: fixStatus + }, + DonasiMaster_Ketegori: { + name: fixStatus } } }); @@ -47,4 +50,4 @@ export async function GET(request: Request, { params }: { } finally { await prisma.$disconnect(); } -} \ No newline at end of file +} diff --git a/src/app/dev/admin/donasi/main/page.tsx b/src/app/dev/admin/donasi/main/page.tsx index 2fadbc04..133a7c09 100644 --- a/src/app/dev/admin/donasi/main/page.tsx +++ b/src/app/dev/admin/donasi/main/page.tsx @@ -10,9 +10,9 @@ export default async function Page() { return ( <> ); diff --git a/src/app_modules/admin/_admin_global/_component/comp_admin_modal_publish.tsx b/src/app_modules/admin/_admin_global/_component/comp_admin_modal_publish.tsx index e64c4321..d962a119 100644 --- a/src/app_modules/admin/_admin_global/_component/comp_admin_modal_publish.tsx +++ b/src/app_modules/admin/_admin_global/_component/comp_admin_modal_publish.tsx @@ -1,3 +1,4 @@ +import { AdminColor } from '@/app_modules/_global/color/color_pallet'; import { Group, Modal, Stack } from '@mantine/core'; import React from 'react'; @@ -11,6 +12,7 @@ function Admin_ComponentModalPublish({ onClose, opened, title, buttonKiri, butto return ( <> - + - + Gambar Donasi @@ -128,7 +129,7 @@ function TampilanDetailDonasi({ </Stack> </Paper> - <Paper withBorder p={"sm"}> + <Paper p={"sm"}> <Stack spacing={5}> <Title order={4}>Detail Donasi @@ -379,25 +380,25 @@ function TampilanListDonatur({ const tableRows = lisDonatur.map((e, i) => ( -
{e?.Author.username}
+
{e?.Author.username}
-
{e?.DonasiMaster_Bank?.name}
+
{e?.DonasiMaster_Bank?.name}
-
- +
+
-
+
{new Intl.DateTimeFormat("id-ID", { dateStyle: "full" }).format( e?.createdAt )}
-
+
{e?.DonasiMaster_StatusInvoice?.name} @@ -458,7 +459,7 @@ function TampilanListDonatur({ {/*
{JSON.stringify(dataDonasi, null, 2)}
*/} - + @@ -697,15 +696,15 @@ function TampilanListPencairan({ const rowTable = data.map((e) => ( @@ -755,7 +754,7 @@ function TampilanListPencairan({ - +
-
Nama Donatur
+
Nama Donatur
-
Nama Bank
+
Nama Bank
-
Jumlah Donasi
+
Jumlah Donasi
-
Tanggal
+
Tanggal
-
Status
+
Status
-
Bukti Transfer
+
Bukti Transfer
-
Aksi
+
Aksi
-
+
-
{moment(e.createdAt).format("ll")}
+
{moment(e.createdAt).format("ll")}
-
+
{e.title}
- + diff --git a/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts b/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts index f1852371..deff9dba 100644 --- a/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts +++ b/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts @@ -1,9 +1,13 @@ +export { + apiGetDonasiStatusCountDashboard, + apiGetDonasiKategoriCountDashboard +}; const apiGetDonasiStatusCountDashboard = async ({ name }: { name: "Publish" | "Review" | "Reject" }) => { const { token } = await fetch("/api/get-cookie").then((res) => res.json()); if (!token) return await token.json().catch(() => null); - - const response = await fetch(`api/admin/donasi/dashboard/${name}`, { + + const response = await fetch(`/api/admin/donasi/dashboard/${name}`, { method: "GET", headers: { "Content-Type": "application/json", @@ -13,4 +17,20 @@ const apiGetDonasiStatusCountDashboard = async ({ name }: } }); return await response.json().catch(() => null); -}; \ No newline at end of file +}; + +const apiGetDonasiKategoriCountDashboard = async ({ name }: { name: "Kategori" }) => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/donasi/dashboard/${name}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control_Allow-Origin": "*", + Authorization: `Bearer ${token}` + } + }); + return await response.json().catch(() => null); +} \ No newline at end of file diff --git a/src/app_modules/admin/donasi/main/index.tsx b/src/app_modules/admin/donasi/main/index.tsx index 1ef0f5a8..8521ae7c 100644 --- a/src/app_modules/admin/donasi/main/index.tsx +++ b/src/app_modules/admin/donasi/main/index.tsx @@ -20,51 +20,150 @@ import { useRouter } from "next/navigation"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; import { AccentColor, MainColor } from "@/app_modules/_global/color"; import { AdminColor } from "@/app_modules/_global/color/color_pallet"; +import { useState } from "react"; +import { clientLogger } from "@/util/clientLogger"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import global_limit from "@/app/lib/limit"; +import { useShallowEffect } from "@mantine/hooks"; +import { apiGetDonasiKategoriCountDashboard, apiGetDonasiStatusCountDashboard } from "../lib/api_fetch_admin_donasi"; export default function AdminDonasi_Main({ - countPublish, - countReview, - - countReject, + // countPublish, + // countReview, + + // countReject, }: { - countPublish: number; - countReview: number; + // countPublish: number; + // countReview: number; + + // countReject: number; + }) { + + const [countPublish, setCountPublish] = useState(null); + const [countReview, setCountReview] = useState(null); + const [countReject, setCountReject] = useState(null); + const [countKategori, setCountKategori] = useState(null); - countReject: number; -}) { + useShallowEffect(() => { + handlerLoadData(); + }, []); + async function handlerLoadData() { + try { + const listLoadData = [ + global_limit(() => onLoadCountPublish()), + global_limit(() => onLoadCountReview()), + global_limit(() => onLoadCountReject()), + global_limit(() => onLoadCountKategori()), + ]; + const result = await Promise.all(listLoadData); + } catch (error) { + clientLogger.error("Error handler load data", error); + } + } + async function onLoadCountPublish() { + try { + const response = await apiGetDonasiStatusCountDashboard({ + name: "Publish", + }) + + if (response) { + setCountPublish(response.data); + } + } catch (error) { + clientLogger.error("Error get count publish", error); + } + } + async function onLoadCountReview() { + try { + const response = await apiGetDonasiStatusCountDashboard({ + name: "Review", + }) + if (response) { + setCountReview(response.data); + } + } catch (error) { + clientLogger.error("Error get count review", error); + } + } + async function onLoadCountReject() { + try { + const response = await apiGetDonasiStatusCountDashboard({ + name: "Reject", + }) + if (response) { + setCountReject(response.data); + } + } catch (error) { + clientLogger.error("Error get count reject", error); + } + } + async function onLoadCountKategori() { + try { + const response = await apiGetDonasiKategoriCountDashboard({ + name: "Kategori" + }) + if (response) { + setCountKategori(response.data); + } + } catch (error) { + clientLogger.error("Error get count kategori", error); + } + } + + const router = useRouter(); const listBox = [ { id: 1, name: "Publish", - jumlah: countPublish, - link: RouterAdminDonasi_OLD.table_publish, + jumlah: countPublish == null ? ( + + ) : countPublish ? ( + countPublish + ) : ( + "-" + ), color: MainColor.green, - icon: , + icon: , }, { id: 2, name: "Review", - jumlah: countReview, - link: RouterAdminDonasi_OLD.table_review, + jumlah: countReview == null ? ( + + ) : countReview ? ( + countReview + ) : ( + "-" + ), color: MainColor.orange, - icon: + icon: }, { id: 3, name: "Reject", - jumlah: countReject, - link: RouterAdminDonasi_OLD.table_reject, + jumlah: countReject == null ? ( + + ) : countReject ? ( + countReject + ) : ( + "-" + ), color: MainColor.red, icon: }, { id: 4, name: "Kategori", - jumlah: 5, - link: RouterAdminDonasi_OLD.table_kategori, + jumlah: countKategori == null ? ( + + ) : countKategori ? ( + countKategori + ) : ( + "-" + ), color: AccentColor.softblue, - icon: + icon: } ]; @@ -89,9 +188,9 @@ export default function AdminDonasi_Main({ shadow="md" radius="md" p="md" - // sx={{ borderColor: e.color, borderStyle: "solid" }} + // sx={{ borderColor: e.color, borderStyle: "solid" }} > - + {e.name} {e.jumlah ? e.jumlah : 0} @@ -99,8 +198,8 @@ export default function AdminDonasi_Main({ {e.icon} - - + + ))} diff --git a/src/app_modules/admin/donasi/sub_menu/table_kategori.tsx b/src/app_modules/admin/donasi/sub_menu/table_kategori.tsx index e1d8fca4..b852816b 100644 --- a/src/app_modules/admin/donasi/sub_menu/table_kategori.tsx +++ b/src/app_modules/admin/donasi/sub_menu/table_kategori.tsx @@ -30,6 +30,8 @@ import adminDonasi_funDeleteKategori from "../fun/delete/fun_delete_by_id"; import adminDonasi_funUpdatekategoriById from "../fun/update/fun_update_kategori_by_id"; import _ from "lodash"; import { ComponentAdminGlobal_TitlePage } from "../../_admin_global/_component"; +import { AccentColor } from "@/app_modules/_global/color"; +import { AdminColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminDonasi_TableKategori({ listKategori, @@ -115,7 +117,7 @@ function TableView({ list }: { list: MODEL_NEW_DEFAULT_MASTER[] }) { const rowTable = data.map((e, i) => ( @@ -149,7 +151,7 @@ function TableView({ list }: { list: MODEL_NEW_DEFAULT_MASTER[] }) { }); }} > - + @@ -162,7 +164,7 @@ function TableView({ list }: { list: MODEL_NEW_DEFAULT_MASTER[] }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} - +
-
Nominal
+
Nominal
-
Tanggal
+
Tanggal
-
Judul
+
Judul
DeskripsiDeskripsi -
Bukti Transfer
+
Bukti Transfer
-
+
{e?.name}
diff --git a/src/app_modules/admin/donasi/sub_menu/table_publish.tsx b/src/app_modules/admin/donasi/sub_menu/table_publish.tsx index b6048cef..21c053cb 100644 --- a/src/app_modules/admin/donasi/sub_menu/table_publish.tsx +++ b/src/app_modules/admin/donasi/sub_menu/table_publish.tsx @@ -72,23 +72,23 @@ function TableStatus({ listPublish }: { listPublish: any }) { const TableRows = data.map((e, i) => (
-
Kategori
+
Kategori
-
Status
+
Status
-
Aksi
+
Aksi
-
{e.title}
+
{e.title}
-
- +
+
-
- +
+
-
{e.DonasiMaster_Ketegori.name}
+
{e.DonasiMaster_Ketegori.name}
-
{e.DonasiMaster_Durasi.name} hari
+
{e.DonasiMaster_Durasi.name} hari
@@ -118,7 +118,7 @@ function TableStatus({ listPublish }: { listPublish: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -147,35 +147,34 @@ function TableStatus({ listPublish }: { listPublish: any }) { /> */} - + diff --git a/src/app_modules/admin/donasi/sub_menu/table_reject.tsx b/src/app_modules/admin/donasi/sub_menu/table_reject.tsx index c6d354d9..a71bfd1e 100644 --- a/src/app_modules/admin/donasi/sub_menu/table_reject.tsx +++ b/src/app_modules/admin/donasi/sub_menu/table_reject.tsx @@ -75,21 +75,21 @@ function TableStatus({ dataReject }: { dataReject: any }) { const TableRows = data.map((e, i) => (
-
Judul
+
Judul
-
Target
+
Target
-
Terkumpul
+
Terkumpul
-
Ketegori
+
Ketegori
-
Durasi
+
Durasi
-
Aksi
+
Aksi
-
{e?.Author?.username}
+
{e?.Author?.username}
-
{e?.title}
+
{e?.title}
-
+
-
{e?.DonasiMaster_Ketegori.name}
+
{e?.DonasiMaster_Ketegori.name}
-
{e?.DonasiMaster_Durasi.name} hari
+
{e?.DonasiMaster_Durasi.name} hari
@@ -117,7 +117,7 @@ function TableStatus({ dataReject }: { dataReject: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -146,35 +146,34 @@ function TableStatus({ dataReject }: { dataReject: any }) { /> */} - + diff --git a/src/app_modules/admin/investasi/detail/detail_review.tsx b/src/app_modules/admin/investasi/detail/detail_review.tsx index a3ee11ec..3ed91740 100644 --- a/src/app_modules/admin/investasi/detail/detail_review.tsx +++ b/src/app_modules/admin/investasi/detail/detail_review.tsx @@ -212,7 +212,7 @@ export default function AdminInvestasi_DetailReview({ buttonKanan={ @@ -193,7 +193,7 @@ function TableView({ listData }: { listData: any }) { } @@ -227,7 +227,7 @@ function TableView({ listData }: { listData: any }) { {_.isEmpty(data) ? ( ) : ( - +
-
Username
+
Username
-
Judul
+
Judul
-
Target
+
Target
-
Ketegori
+
Ketegori
-
Durasi
+
Durasi
-
Alasan
+
Alasan
- {e.author.username} + {e.author.username}
- {e.title} + {e.title}
- {e.catatan} + {e.catatan}
diff --git a/src/app_modules/admin/vote/child/riwayat/index.tsx b/src/app_modules/admin/vote/child/riwayat/index.tsx index 976f0ffc..7d261e09 100644 --- a/src/app_modules/admin/vote/child/riwayat/index.tsx +++ b/src/app_modules/admin/vote/child/riwayat/index.tsx @@ -26,6 +26,8 @@ import ComponentAdminVote_DetailHasil from "../../component/detail_hasil"; import { adminVote_funGetListRiwayat } from "../../fun"; import { AdminVote_getHasilById } from "../../fun/get/get_hasil_by_id"; import { AdminVote_getListKontributorById } from "../../fun/get/get_list_kontributor_by_id"; +import { AccentColor } from "@/app_modules/_global/color"; +import { AdminColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminVote_Riwayat({ dataVote, @@ -98,10 +100,10 @@ function TableStatus({ listPublish }: { listPublish: any }) { @@ -143,7 +145,7 @@ function TableStatus({ listPublish }: { listPublish: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -172,38 +174,37 @@ function TableStatus({ listPublish }: { listPublish: any }) { /> */} - +
-
Username
+
Username
-
Nama Proyek
+
Nama Proyek
-
Catatan Penolakan
+
Catatan Penolakan
-
Aksi
+
Aksi
-
{e?.Author?.username}
+
{e?.Author?.username}
-
{e?.title}
+
{e?.title}
@@ -119,18 +121,18 @@ function TableStatus({ listPublish }: { listPublish: any }) { {e?.Voting_DaftarNamaVote.map((v) => ( - - {v?.value} + - {v?.value} ))}
-
+
{e?.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
-
+
{e?.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
diff --git a/src/app_modules/admin/vote/child/table_publish/index.tsx b/src/app_modules/admin/vote/child/table_publish/index.tsx index 8e23b3fc..226acca4 100644 --- a/src/app_modules/admin/vote/child/table_publish/index.tsx +++ b/src/app_modules/admin/vote/child/table_publish/index.tsx @@ -28,7 +28,7 @@ import { AdminVote_getListKontributorById } from "../../fun/get/get_list_kontrib import { adminVote_funGetListPublish } from "../../fun/get/status/get_list_publish"; import { ComponentAdminGlobal_TitlePage } from "@/app_modules/admin/_admin_global/_component"; import { MainColor } from "@/app_modules/_global/color"; -import { AdminColor } from "@/app_modules/_global/color/color_pallet"; +import { AccentColor, AdminColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminVote_TablePublish({ dataVote, @@ -101,10 +101,10 @@ function TableStatus({ listPublish }: { listPublish: any }) { @@ -146,7 +146,7 @@ function TableStatus({ listPublish }: { listPublish: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -175,38 +175,36 @@ function TableStatus({ listPublish }: { listPublish: any }) { /> */} - +
-
Aksi
+
Aksi
-
Username
+
Username
-
Judul
+
Judul
-
Deskripsi
+
Deskripsi
-
Pilihan
+
Pilihan
-
Mulai Vote
+
Mulai Vote
-
Selesai Vote
+
Selesai Vote
-
{e?.Author?.username}
+
{e?.Author?.username}
-
{e?.title}
+
{e?.title}
@@ -122,18 +122,18 @@ function TableStatus({ listPublish }: { listPublish: any }) { {e?.Voting_DaftarNamaVote.map((v) => ( - - {v?.value} + - {v?.value} ))}
-
+
{e?.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
-
+
{e?.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
diff --git a/src/app_modules/admin/vote/child/table_reject/index.tsx b/src/app_modules/admin/vote/child/table_reject/index.tsx index 8bbf07d0..96337d24 100644 --- a/src/app_modules/admin/vote/child/table_reject/index.tsx +++ b/src/app_modules/admin/vote/child/table_reject/index.tsx @@ -29,7 +29,7 @@ import { adminVote_funGetListReject } from "../../fun"; import { AdminVote_funEditCatatanRejectById } from "../../fun/edit/fun_edit_catatan_reject_by_id"; import { ComponentAdminGlobal_TitlePage } from "@/app_modules/admin/_admin_global/_component"; import { MainColor } from "@/app_modules/_global/color"; -import { AdminColor } from "@/app_modules/_global/color/color_pallet"; +import { AccentColor, AdminColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminVote_TableReject({ dataVote }: { dataVote: any }) { return ( @@ -109,7 +109,7 @@ function TableStatus({ listData }: { listData: any }) { setCatatan(e.catatan); }} > - + Tambah Catatan @@ -129,10 +129,10 @@ function TableStatus({ listData }: { listData: any }) { @@ -174,7 +174,7 @@ function TableStatus({ listData }: { listData: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -203,41 +203,40 @@ function TableStatus({ listData }: { listData: any }) { /> */} - +
-
Aksi
+
Aksi
-
Username
+
Username
-
Judul
+
Judul
-
Deskripsi
+
Deskripsi
-
Pilihan
+
Pilihan
-
Mulai Vote
+
Mulai Vote
-
Selesai Vote
+
Selesai Vote
-
{e?.Author?.Profile?.name}
+
{e?.Author?.Profile?.name}
-
{e.title}
+
{e.title}
@@ -150,18 +150,18 @@ function TableStatus({ listData }: { listData: any }) { {e.Voting_DaftarNamaVote.map((v) => ( - - {v.value} + - {v.value} ))}
-
+
{e.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
-
+
{e.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
diff --git a/src/app_modules/admin/vote/child/table_review/index.tsx b/src/app_modules/admin/vote/child/table_review/index.tsx index 584499fa..5f944ceb 100644 --- a/src/app_modules/admin/vote/child/table_review/index.tsx +++ b/src/app_modules/admin/vote/child/table_review/index.tsx @@ -123,10 +123,10 @@ function TableStatus({ listData }: { listData: any }) { const TableRows = data.map((e, i) => ( @@ -212,7 +212,7 @@ function TableStatus({ listData }: { listData: any }) { {/*
{JSON.stringify(listUser, null, 2)}
*/} } @@ -241,7 +241,7 @@ function TableStatus({ listData }: { listData: any }) { /> */} - + {isShowReload && (
@@ -270,32 +270,31 @@ function TableStatus({ listData }: { listData: any }) { horizontalSpacing={"md"} p={"md"} w={1500} - striped - highlightOnHover + >
diff --git a/src/app_modules/admin/vote/main/index.tsx b/src/app_modules/admin/vote/main/index.tsx index 883ad486..d2667d44 100644 --- a/src/app_modules/admin/vote/main/index.tsx +++ b/src/app_modules/admin/vote/main/index.tsx @@ -1,8 +1,10 @@ "use client"; -import { Stack, SimpleGrid, Paper, Group, Title, Text } from "@mantine/core"; +import { Stack, SimpleGrid, Paper, Group, Title, Text, Flex, ThemeIcon } from "@mantine/core"; import { useRouter } from "next/navigation"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; +import { IconAlertTriangle, IconBookmark, IconHistory, IconUpload } from "@tabler/icons-react"; +import { AccentColor, AdminColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminVote_Main({ countPublish, @@ -25,18 +27,21 @@ export default function AdminVote_Main({ name: "Publish", jumlah: countPublish, color: "green", + icon: }, { id: 2, name: "Review", jumlah: countReview, color: "orange", + icon: }, { id: 3, name: "Reject", jumlah: countReject, color: "red", + icon: }, { id: 4, @@ -44,6 +49,7 @@ export default function AdminVote_Main({ jumlah: countDraft, path: "", color: "gray", + icon: }, ]; @@ -64,22 +70,31 @@ export default function AdminVote_Main({ {listStatus.map((e, i) => ( - - - {e.name} - {e.jumlah ? e.jumlah : 0} - - + + + {e.name} + + {e.jumlah ? e.jumlah : 0} + + {e.icon} + + + + ))} - + ); diff --git a/src/middleware.ts b/src/middleware.ts index b20103f3..a6d0687c 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -39,6 +39,7 @@ const middlewareConfig: MiddlewareConfig = { // ADMIN API // "/api/admin/event/*", // "/api/admin/investasi/*", + // "/api/admin/donasi/dashboard/*", // Akses awal From d2a1f85ec0445c9753b96f10d3e09b1f25e382bf Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 31 Jan 2025 17:48:35 +0800 Subject: [PATCH 2/2] Add API Dashboard ADMIN Doasi, Job, dan Voting --- .../admin/donasi/dashboard/[name]/route.ts | 3 - .../admin/donasi/dashboard/kategori/route.ts | 39 ++++++ .../api/admin/job/dashboard/[status]/route.ts | 50 +++++++ .../api/admin/job/dashboard/arsip/route.ts | 44 ++++++ .../admin/voting/dashboard/[name]/route.ts | 51 +++++++ .../admin/voting/dashboard/riwayat/route.ts | 44 ++++++ src/app/dev/admin/job/main/page.tsx | 16 +-- src/app/dev/admin/vote/main/page.tsx | 16 +-- .../donasi/lib/api_fetch_admin_donasi.ts | 4 +- src/app_modules/admin/donasi/main/index.tsx | 4 +- src/app_modules/admin/job/main/index.tsx | 32 +++-- .../admin/vote/lib/api_fetch_admin_voting.ts | 36 +++++ src/app_modules/admin/vote/main/index.tsx | 125 +++++++++++++++--- .../job/lib/api_fetch_admin_job.ts | 30 +++++ src/middleware.ts | 2 + 15 files changed, 443 insertions(+), 53 deletions(-) create mode 100644 src/app/api/admin/donasi/dashboard/kategori/route.ts create mode 100644 src/app/api/admin/job/dashboard/[status]/route.ts create mode 100644 src/app/api/admin/job/dashboard/arsip/route.ts create mode 100644 src/app/api/admin/voting/dashboard/[name]/route.ts create mode 100644 src/app/api/admin/voting/dashboard/riwayat/route.ts create mode 100644 src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts create mode 100644 src/app_modules/job/lib/api_fetch_admin_job.ts diff --git a/src/app/api/admin/donasi/dashboard/[name]/route.ts b/src/app/api/admin/donasi/dashboard/[name]/route.ts index 61118d40..8b164d12 100644 --- a/src/app/api/admin/donasi/dashboard/[name]/route.ts +++ b/src/app/api/admin/donasi/dashboard/[name]/route.ts @@ -26,9 +26,6 @@ export async function GET(request: Request, { params }: { DonasiMaster_Status: { name: fixStatus }, - DonasiMaster_Ketegori: { - name: fixStatus - } } }); return NextResponse.json({ diff --git a/src/app/api/admin/donasi/dashboard/kategori/route.ts b/src/app/api/admin/donasi/dashboard/kategori/route.ts new file mode 100644 index 00000000..ed0063d8 --- /dev/null +++ b/src/app/api/admin/donasi/dashboard/kategori/route.ts @@ -0,0 +1,39 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const method = request.method; + if (method !== 'GET') { + return NextResponse.json({ + success: false, + message: 'Method not allowed', + }, + { status: 405 } + ) + } + + try { + let fixData; + fixData = await prisma.donasiMaster_Kategori.count({}); + return NextResponse.json({ + success: true, + message: 'Success get data donasi dashboard', + data: fixData + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error('Error get data donasi dashboard >>', error); + return NextResponse.json({ + success: false, + message: 'Error get data donasi dashboard', + reason: (error as Error).message + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/api/admin/job/dashboard/[status]/route.ts b/src/app/api/admin/job/dashboard/[status]/route.ts new file mode 100644 index 00000000..dd45ec7e --- /dev/null +++ b/src/app/api/admin/job/dashboard/[status]/route.ts @@ -0,0 +1,50 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request, { params }: { + params: { status: string } +}) { + const method = request.method; + if (method !== "GET") { + return NextResponse.json({ + success: false, + message: "Method not allowed", + }, + { status: 405 } + ) + } + const { status } = params; + try { + let fixData; + const fixStatus = _.startCase(status); + fixData = await prisma.job.count({ + where: { + MasterStatus: { + name: fixStatus, + }, + isArsip: false, + } + }); + + return NextResponse.json({ + success: true, + message: "Success get data job-vacancy dashboard", + data: fixData + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error get data job-vacancy dashboard", error); + return NextResponse.json({ + success: false, + message: "Error get data job-vacancy dashboard", + reason: (error as Error).message, + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/api/admin/job/dashboard/arsip/route.ts b/src/app/api/admin/job/dashboard/arsip/route.ts new file mode 100644 index 00000000..fd1d45c5 --- /dev/null +++ b/src/app/api/admin/job/dashboard/arsip/route.ts @@ -0,0 +1,44 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const method = request.method; + if (method !== "GET") { + return NextResponse.json({ + success: false, + message: "Method not allowed", + }, + { status: 405 } + ); + } + try { + let fixData; + fixData = await prisma.job.count({ + where: { + MasterStatus: { + name: "Publish" + }, + isArsip: true + } + }) + return NextResponse.json({ + success: true, + message: "Success get data job-vacancy dashboard", + data: fixData + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error("Error get data job-vacancy dashboard", error); + return NextResponse.json({ + success: false, + message: "Error get data job-vacancy dashboard", + reason: (error as Error).message + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/api/admin/voting/dashboard/[name]/route.ts b/src/app/api/admin/voting/dashboard/[name]/route.ts new file mode 100644 index 00000000..3f498707 --- /dev/null +++ b/src/app/api/admin/voting/dashboard/[name]/route.ts @@ -0,0 +1,51 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request, { params }: { + params: { name: string } +}) { + const method = request.method; + if (method !== "GET") { + return NextResponse.json({ + success: false, + message: "Method not allowed", + }, + { status: 405 } + ) + } + + const { name } = params; + try { + let fixData; + const fixStatus = _.startCase(name); + fixData = await prisma.voting.count({ + where: { + Voting_Status: { + name: fixStatus + }, + isArsip: false + }, + }) + + return NextResponse.json({ + success: true, + message: "Success get data voting dashboard", + data: fixData + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error("Error get data voting dashboard >>", error); + return NextResponse.json({ + success: false, + message: "Error get data voting dashboard", + reason: (error as Error).message + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/api/admin/voting/dashboard/riwayat/route.ts b/src/app/api/admin/voting/dashboard/riwayat/route.ts new file mode 100644 index 00000000..3857af0e --- /dev/null +++ b/src/app/api/admin/voting/dashboard/riwayat/route.ts @@ -0,0 +1,44 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const method = request.method; + if (method !== "GET") { + return NextResponse.json({ + success: false, + message: "Method not allowed", + }, + { status: 405 } + ) + } + try { + let fixData; + fixData = await prisma.voting.count({ + where: { + Voting_Status: { + name: "Publish", + }, + isArsip: true, + } + }) + return NextResponse.json({ + success: true, + message: 'Success get data voting dashboard', + data: fixData + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error('Error get data voting dashboard >>', error); + NextResponse.json({ + success: false, + message: 'Error get data voting dashboard', + reason: (error as Error).message + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/dev/admin/job/main/page.tsx b/src/app/dev/admin/job/main/page.tsx index 140eb795..ce9c1d7b 100644 --- a/src/app/dev/admin/job/main/page.tsx +++ b/src/app/dev/admin/job/main/page.tsx @@ -2,10 +2,10 @@ import { AdminJob_Main } from "@/app_modules/admin/job"; import { AdminJob_funCountStatusByStatusId } from "@/app_modules/admin/job/fun/count/fun_count_job_by_status_id"; export default async function Page() { - const countPublish = await AdminJob_funCountStatusByStatusId("1") - const countReview = await AdminJob_funCountStatusByStatusId("2"); - const countReject = await AdminJob_funCountStatusByStatusId("4"); - const countArsip = await AdminJob_funCountStatusByStatusId("0") + // const countPublish = await AdminJob_funCountStatusByStatusId("1") + // const countReview = await AdminJob_funCountStatusByStatusId("2"); + // const countReject = await AdminJob_funCountStatusByStatusId("4"); + // const countArsip = await AdminJob_funCountStatusByStatusId("0") @@ -13,10 +13,10 @@ export default async function Page() { return ( <> ); diff --git a/src/app/dev/admin/vote/main/page.tsx b/src/app/dev/admin/vote/main/page.tsx index 6fefc7ff..cf2dd932 100644 --- a/src/app/dev/admin/vote/main/page.tsx +++ b/src/app/dev/admin/vote/main/page.tsx @@ -2,18 +2,18 @@ import { AdminVote_Main } from "@/app_modules/admin/vote"; import AdminVote_funCountByStatusId from "@/app_modules/admin/vote/fun/count/fun_count_vote_by_status_id"; export default async function Page() { - const countPublish = await AdminVote_funCountByStatusId("1"); - const countReview = await AdminVote_funCountByStatusId("2"); - const countDraft = await AdminVote_funCountByStatusId("0"); - const countReject = await AdminVote_funCountByStatusId("4"); + // const countPublish = await AdminVote_funCountByStatusId("1"); + // const countReview = await AdminVote_funCountByStatusId("2"); + // const countDraft = await AdminVote_funCountByStatusId("0"); + // const countReject = await AdminVote_funCountByStatusId("4"); return ( <> ); diff --git a/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts b/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts index deff9dba..be1e50e4 100644 --- a/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts +++ b/src/app_modules/admin/donasi/lib/api_fetch_admin_donasi.ts @@ -19,11 +19,11 @@ const apiGetDonasiStatusCountDashboard = async ({ name }: return await response.json().catch(() => null); }; -const apiGetDonasiKategoriCountDashboard = async ({ name }: { name: "Kategori" }) => { +const apiGetDonasiKategoriCountDashboard = async () => { const { token } = await fetch("/api/get-cookie").then((res) => res.json()); if (!token) return await token.json().catch(() => null); - const response = await fetch(`/api/admin/donasi/dashboard/${name}`, { + const response = await fetch(`/api/admin/donasi/dashboard/kategori`, { method: "GET", headers: { "Content-Type": "application/json", diff --git a/src/app_modules/admin/donasi/main/index.tsx b/src/app_modules/admin/donasi/main/index.tsx index 8521ae7c..27f17de1 100644 --- a/src/app_modules/admin/donasi/main/index.tsx +++ b/src/app_modules/admin/donasi/main/index.tsx @@ -99,9 +99,7 @@ export default function AdminDonasi_Main({ } async function onLoadCountKategori() { try { - const response = await apiGetDonasiKategoriCountDashboard({ - name: "Kategori" - }) + const response = await apiGetDonasiKategoriCountDashboard() if (response) { setCountKategori(response.data); } diff --git a/src/app_modules/admin/job/main/index.tsx b/src/app_modules/admin/job/main/index.tsx index 79a1fd27..6f36fe71 100644 --- a/src/app_modules/admin/job/main/index.tsx +++ b/src/app_modules/admin/job/main/index.tsx @@ -3,20 +3,34 @@ import { Group, Paper, SimpleGrid, Stack, Text, Title } from "@mantine/core"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { clientLogger } from "@/util/clientLogger"; export default function AdminJob_Main({ - countPublish, - countReview, - countReject, - countArsip, + // countPublish, + // countReview, + // countReject, + // countArsip, }: { - countPublish: number; - countReview: number; - countReject: number; - countArsip: number -}) { + // countPublish: number; + // countReview: number; + // countReject: number; + // countArsip: number + }) { + const [countPublish, setCountPublish] = useState(null); + const [countReview, setCountReview] = useState(null); + const [countReject, setCountReject] = useState(null); + const [countArsip, setCountArsip] = useState(null); const router = useRouter(); + async function onLoadCountPublish() { + try { + + } catch (error) { + clientLogger.error("Error get count publish", error) + } +} + const listStatus = [ { id: 1, diff --git a/src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts b/src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts new file mode 100644 index 00000000..f916bbb3 --- /dev/null +++ b/src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts @@ -0,0 +1,36 @@ +export { + apiGetVoteStatusCountDashboard, + apiGetVoteRiwayatCount +} +const apiGetVoteStatusCountDashboard = async ({ name }: { + name: "Publish" | "Review" | "Reject"; +}) => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/voting/dashboard/${name}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + } + }); + return await response.json().catch(() => null); +} +const apiGetVoteRiwayatCount = async () => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/voting/dashboard/riwayat`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + } + }); + return await response.json().catch(() => null); +} \ No newline at end of file diff --git a/src/app_modules/admin/vote/main/index.tsx b/src/app_modules/admin/vote/main/index.tsx index d2667d44..6296f016 100644 --- a/src/app_modules/admin/vote/main/index.tsx +++ b/src/app_modules/admin/vote/main/index.tsx @@ -5,49 +5,134 @@ import { useRouter } from "next/navigation"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; import { IconAlertTriangle, IconBookmark, IconHistory, IconUpload } from "@tabler/icons-react"; import { AccentColor, AdminColor } from "@/app_modules/_global/color/color_pallet"; +import { useState } from "react"; +import { clientLogger } from "@/util/clientLogger"; +import { apiGetVoteRiwayatCount, apiGetVoteStatusCountDashboard } from "../lib/api_fetch_admin_voting"; +import global_limit from "@/app/lib/limit"; +import { useShallowEffect } from "@mantine/hooks"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; + +export default function AdminVote_Main() { + const [countPublish, setCountPublish] = useState(null); + const [countReview, setCountReview] = useState(null); + const [countReject, setCountReject] = useState(null); + const [countRiwayat, setCountRiwayat] = useState(null); + + useShallowEffect(() => { + handlerLoadData(); + }, []); + async function handlerLoadData() { + try { + const listLoadData = [ + global_limit(() => onLoadCountPublish()), + global_limit(() => onLoadCountReview()), + global_limit(() => onLoadCountReject()), + global_limit(() => onLoadCountRiwayat()), + ]; + const result = await Promise.all(listLoadData); + } catch (error) { + clientLogger.error("Error handler load data", error); + } + } + async function onLoadCountPublish() { + try { + const response = await apiGetVoteStatusCountDashboard({ + name: "Publish", + }) + if (response) { + setCountPublish(response.data); + } + } catch (error) { + clientLogger.error("Error get count publish", error); + } + } + async function onLoadCountReview() { + try { + const response = await apiGetVoteStatusCountDashboard({ + name: "Review", + }) + + if (response) { + setCountReview(response.data); + } + } catch (error) { + clientLogger.error("Error get count review", error); + } + } + async function onLoadCountReject() { + try { + const response = await apiGetVoteStatusCountDashboard({ + name: "Reject", + }) + if (response) { + setCountReject(response.data); + } + } catch (error) { + clientLogger.error("Error get count reject", error); + } + } + async function onLoadCountRiwayat() { + try { + const response = await apiGetVoteRiwayatCount() + if (response) { + setCountRiwayat(response.data); + } + } catch (error) { + clientLogger.error("Error get count riwayat", error); + } + } -export default function AdminVote_Main({ - countPublish, - countReview, - countDraft, - countReject, - countRiwayat, -}: { - countPublish?: number; - countReview?: number; - countDraft?: number; - countReject?: number; - countRiwayat?: number; -}) { const router = useRouter(); - const listStatus = [ { id: 1, name: "Publish", - jumlah: countPublish, + jumlah: countPublish == null ? ( + + ) : countPublish ? ( + countPublish + ) : ( + "-" + ), color: "green", - icon: + icon: }, { id: 2, name: "Review", - jumlah: countReview, + jumlah: countReview == null ? ( + + ) : countReview ? ( + countReview + ) : ( + "-" + ), color: "orange", icon: }, { id: 3, name: "Reject", - jumlah: countReject, + jumlah: countReject == null ? ( + + ) : countReject ? ( + countReject + ) : ( + "-" + ), color: "red", icon: }, { id: 4, name: "Riwayat", - jumlah: countDraft, - path: "", + jumlah: countRiwayat == null ? ( + + ) : countRiwayat ? ( + countRiwayat + ) : ( + "-" + ), color: "gray", icon: }, diff --git a/src/app_modules/job/lib/api_fetch_admin_job.ts b/src/app_modules/job/lib/api_fetch_admin_job.ts new file mode 100644 index 00000000..ba61c164 --- /dev/null +++ b/src/app_modules/job/lib/api_fetch_admin_job.ts @@ -0,0 +1,30 @@ +const apiGetJobStatuCountDashboard = async ({ name }: { name: "Publish" | "Review" | "Reject" }) => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/job/dashboard/${name}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }) + return await response.json().catch(() => null) +} +const apiGetJobStatusCountArsip = async () => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/job/dashboard/arsip`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }) + return await response.json().catch(() => null); +} \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index a6d0687c..0251f643 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -40,6 +40,8 @@ const middlewareConfig: MiddlewareConfig = { // "/api/admin/event/*", // "/api/admin/investasi/*", // "/api/admin/donasi/dashboard/*", + // "/api/admin/voting/dashboard/*", + // "/api/admin/job/dashboard/*", // Akses awal
-
Aksi
+
Aksi
-
Catatan
+
Catatan
-
Author
+
Author
-
Judul
+
Judul
-
Deskripsi
+
Deskripsi
-
Pilihan
+
Pilihan
-
Mulai Vote
+
Mulai Vote
-
Selesai Vote
+
Selesai Vote
-
{e?.Author?.username}
+
{e?.Author?.username}
-
{e.title}
+
{e.title}
@@ -144,18 +144,18 @@ function TableStatus({ listData }: { listData: any }) { {e.Voting_DaftarNamaVote.map((v) => ( - - {v.value} + - {v.value} ))}
-
+
{e.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
-
+
{e.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
-
Username
+
Username
-
Judul
+
Judul
-
Deskripsi
+
Deskripsi
-
Pilihan
+
Pilihan
-
Mulai Vote
+
Mulai Vote
-
Selesai Vote
+
Selesai Vote
-
Aksi
+
Aksi