diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5279ac..28f38c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. +## [1.2.58](https://github.com/bipproduction/hipmi/compare/v1.2.57...v1.2.58) (2025-02-25) + ## [1.2.57](https://github.com/bipproduction/hipmi/compare/v1.2.56...v1.2.57) (2025-02-20) ## [1.2.56](https://github.com/bipproduction/hipmi/compare/v1.2.55...v1.2.56) (2025-02-19) diff --git a/package.json b/package.json index ae122692..37c69a2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hipmi", - "version": "1.2.57", + "version": "1.2.58", "private": true, "type": "module", "prisma": { diff --git a/src/app/api/admin/user/route.ts b/src/app/api/admin/user/route.ts new file mode 100644 index 00000000..d5e06798 --- /dev/null +++ b/src/app/api/admin/user/route.ts @@ -0,0 +1,72 @@ +import _ from "lodash"; +import { NextResponse } from "next/server"; +import prisma from "@/lib/prisma"; + +export async function GET(request: Request) { + try { + let fixData; + const { searchParams } = new URL(request.url); + const search = searchParams.get("search"); + const page = searchParams.get("page"); + const takeData = 10; + const skipData = Number(page) * takeData - takeData; + + if (!page) { + fixData = await prisma.user.findMany({ + where: { + masterUserRoleId: "1", + username: { + contains: search || "", + mode: "insensitive", + }, + }, + }); + } else { + const getData = await prisma.user.findMany({ + skip: skipData, + take: takeData, + orderBy: { + active: "asc", + }, + where: { + masterUserRoleId: "1", + username: { + contains: search || "", + mode: "insensitive", + }, + }, + }); + + const nCount = await prisma.user.count({ + where: { + masterUserRoleId: "1", + username: { + contains: search || "", + mode: "insensitive", + }, + }, + }); + + fixData = { + data: getData, + nPage: _.ceil(nCount / takeData), + }; + } + + return NextResponse.json( + { + success: true, + message: "Success get data", + data: fixData, + }, + { + status: 200, + } + ); + } catch (error) { + return NextResponse.json( + { success: false, message: "Internal Server Error" }, + { status: 500 } + ); + } +} diff --git a/src/app/api/admin/vote/status/[name]/route.ts b/src/app/api/admin/vote/status/[name]/route.ts index 19c4871b..e2cd0b6b 100644 --- a/src/app/api/admin/vote/status/[name]/route.ts +++ b/src/app/api/admin/vote/status/[name]/route.ts @@ -4,152 +4,216 @@ import _ from "lodash"; import moment from "moment"; import { NextResponse } from "next/server"; -export async function GET(request: Request, - { params }: { params: { name: string } } +export async function GET( + request: Request, + { params }: { params: { name: string } } ) { - + + try { + let fixData; const { name } = params; const { searchParams } = new URL(request.url); const search = searchParams.get("search"); const page = searchParams.get("page"); - const takeData = 10; + const takeData = 10 const skipData = Number(page) * takeData - takeData; + + const fixStatus = _.startCase(name); - try { - let fixData; - const fixStatus = _.startCase(name); + if (!page) { + fixData = await prisma.voting.findMany({ + orderBy: { + createdAt: "desc", + }, + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + isArsip: false, + }, + include: { + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + }, + }, + }, + }, + Voting_Kontributor: true, + Voting_DaftarNamaVote: true, + }, + }); + } else { + if (fixStatus === "Publish") { + const getAllData = await prisma.voting.findMany({ + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + isArsip: false, + akhirVote: { + gte: new Date(), + }, + }, + }); - if (!page) { - fixData = await prisma.voting.findMany({ - orderBy: { - createdAt: "desc", - }, - where: { - Voting_Status: { - name: fixStatus, - }, - isActive: true, - title: { - contains: search ? search : "", - mode: "insensitive", - }, - isArsip: false, - }, - include: { - Author: { - select: { - id: true, - username: true, - Profile: { - select: { - id: true, - name: true, - }, - }, - }, - }, - Voting_Kontributor: true, - Voting_DaftarNamaVote: true, - }, + for (let i of getAllData) { + if (moment(i.akhirVote).diff(moment(), "minutes") < 0) { + await prisma.event.update({ + where: { + id: i.id, + }, + data: { + isArsip: true, + }, }); - } else { - fixData = await prisma.voting.findMany({ - take: takeData, - skip: skipData, - orderBy: { - createdAt: "desc", - }, - where: { - Voting_Status: { - name: fixStatus, - }, - isActive: true, - title: { - contains: search ? search : "", - mode: "insensitive", - }, - isArsip: false, - }, - include: { - Author: { - select: { - id: true, - username: true, - Profile: { - select: { - id: true, - name: true, - }, - }, - }, - }, - Voting_Kontributor: true, - Voting_DaftarNamaVote: true, - }, - }); - - if (fixStatus === "Publish") { - const data = await prisma.voting.findMany({ - where: { - Voting_Status: { - name: fixStatus, - }, - isActive: true, - title: { - contains: search ? search : "", - mode: "insensitive", - }, - isArsip: false, - }, - }); - - for (let i of data) { - if (moment(i.akhirVote).diff(moment(), "minutes") < 0) { - await prisma.event.update({ - where: { - id: i.id, - }, - data: { - isArsip: true, - }, - }); - } - } - const nCount = await prisma.voting.count({ - where: { - Voting_Status: { - name: fixStatus, - }, - isActive: true, - title: { - contains: search ? search : "", - mode: "insensitive", - }, - }, - }); - - fixData = { - data: data, - count: _.ceil(nCount / takeData) - } - } + } } - 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 } - ) + const data = await prisma.voting.findMany({ + take: takeData, + skip: skipData, + orderBy: { + createdAt: "desc", + }, + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + akhirVote: { + gte: new Date(), + }, + isArsip: false, + }, + include: { + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + }, + }, + }, + }, + Voting_Kontributor: true, + Voting_DaftarNamaVote: true, + }, + }); + + const nCount = await prisma.voting.count({ + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + akhirVote: { + gte: new Date(), + }, + isArsip: false, + }, + }); + + fixData = { + data: data, + nPage: _.ceil(nCount / takeData), + }; + } else { + const data = await prisma.voting.findMany({ + take: takeData, + skip: skipData, + orderBy: { + createdAt: "desc", + }, + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + isArsip: false, + }, + include: { + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + }, + }, + }, + }, + Voting_Kontributor: true, + Voting_DaftarNamaVote: true, + }, + }); + + const nCount = await prisma.voting.count({ + where: { + Voting_Status: { + name: fixStatus, + }, + isActive: true, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + isArsip: false, + }, + }); + + fixData = { + data: data, + nPage: _.ceil(nCount / takeData), + }; + } } -} \ No newline at end of file + + return NextResponse.json( + { + success: true, + message: "Success get data voting status", + data: fixData, + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error get data voting status ", error); + return NextResponse.json( + { + success: false, + message: "Error get data voting status", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} diff --git a/src/app/api/admin/vote/status/riwayat/route.ts b/src/app/api/admin/vote/status/riwayat/route.ts new file mode 100644 index 00000000..a818bf22 --- /dev/null +++ b/src/app/api/admin/vote/status/riwayat/route.ts @@ -0,0 +1,123 @@ +import { prisma } from "@/lib"; +import backendLogger from "@/util/backendLogger"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + try { + let fixData; + const { searchParams } = new URL(request.url); + const search = searchParams.get("search"); + const page = searchParams.get("page"); + const takeData = 2; + const skipData = Number(page) * takeData - takeData; + + if (!page) { + fixData = await prisma.voting.findMany({ + orderBy: { + updatedAt: "desc", + }, + where: { + voting_StatusId: "1", + isActive: true, + akhirVote: { + lte: new Date(), + }, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + }, + include: { + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + }, + }, + }, + }, + Voting_Kontributor: true, + Voting_DaftarNamaVote: true, + }, + }); + } else { + const data = await prisma.voting.findMany({ + skip: skipData, + take: takeData, + orderBy: { + updatedAt: "desc", + }, + where: { + voting_StatusId: "1", + isActive: true, + akhirVote: { + lte: new Date(), + }, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + }, + include: { + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + id: true, + name: true, + }, + }, + }, + }, + Voting_Kontributor: true, + Voting_DaftarNamaVote: true, + }, + }); + + const nCount = await prisma.voting.count({ + where: { + voting_StatusId: "1", + isActive: true, + akhirVote: { + lte: new Date(), + }, + title: { + contains: search ? search : "", + mode: "insensitive", + }, + }, + }); + + fixData = { + data: data, + nPage: _.ceil(nCount / takeData), + }; + } + + return NextResponse.json( + { + success: true, + message: "Success get data voting riwayat", + data: fixData, + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error get data voting riwayat ", error); + return NextResponse.json( + { + success: false, + message: "Error get data voting riwayat", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} diff --git a/src/app/api/master/admin-contact/route.ts b/src/app/api/master/admin-contact/route.ts new file mode 100644 index 00000000..7c6f4f55 --- /dev/null +++ b/src/app/api/master/admin-contact/route.ts @@ -0,0 +1,32 @@ +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; +import prisma from "@/lib/prisma"; + +export async function GET(request: Request) { + try { + const data = await prisma.nomorAdmin.findFirst({ + where: { + isActive: true, + }, + }); + + return NextResponse.json( + { + success: true, + message: "Success get admin contact", + data: data, + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error get admin contact", error); + return NextResponse.json( + { + success: false, + message: "Error get admin contact", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} diff --git a/src/app/dev/admin/app-information/main/page.tsx b/src/app/dev/admin/app-information/main/page.tsx index 42c3b5de..b163150f 100644 --- a/src/app/dev/admin/app-information/main/page.tsx +++ b/src/app/dev/admin/app-information/main/page.tsx @@ -4,14 +4,12 @@ import adminAppInformation_getNomorAdmin from "@/app_modules/admin/app_info/fun/ import { AdminAppInformation_UiMain } from "@/app_modules/admin/app_info/ui"; export default async function Page() { - const nomorAdmin = await adminAppInformation_getNomorAdmin(); const listBank = await adminAppInformation_getMasterBank(); const dataBidangBisnis = await adminAppInformation_funGetBidangBisnis() return ( <> diff --git a/src/app/dev/admin/user-access/page.tsx b/src/app/dev/admin/user-access/page.tsx index ed337fdd..78c1534b 100644 --- a/src/app/dev/admin/user-access/page.tsx +++ b/src/app/dev/admin/user-access/page.tsx @@ -2,11 +2,11 @@ import { AdminUserAccess_View } from "@/app_modules/admin/user-access"; import adminUserAccess_getListUser from "@/app_modules/admin/user-access/fun/get/get_list_all_user"; export default async function Page() { - const listUser = await adminUserAccess_getListUser({ page: 1 }); + // const listUser = await adminUserAccess_getListUser({ page: 1 }); return ( <> - + ); } diff --git a/src/app/dev/admin/vote/child/riwayat/page.tsx b/src/app/dev/admin/vote/child/riwayat/page.tsx index df211c60..32d281ea 100644 --- a/src/app/dev/admin/vote/child/riwayat/page.tsx +++ b/src/app/dev/admin/vote/child/riwayat/page.tsx @@ -1,13 +1,9 @@ import { AdminVote_Riwayat } from "@/app_modules/admin/vote"; -import { adminVote_funGetListRiwayat } from "@/app_modules/admin/vote/fun"; -import { AdminVote_getListTableByStatusId } from "@/app_modules/admin/vote/fun/get/get_list_table_by_status_id"; export default async function Page() { - const dataVote = await adminVote_funGetListRiwayat({page: 1}); - return ( <> - + ); } diff --git a/src/app/dev/admin/vote/child/table_publish/page.tsx b/src/app/dev/admin/vote/child/table_publish/page.tsx index 485a1e7b..94d2b239 100644 --- a/src/app/dev/admin/vote/child/table_publish/page.tsx +++ b/src/app/dev/admin/vote/child/table_publish/page.tsx @@ -1,13 +1,9 @@ import { AdminVote_TablePublish } from "@/app_modules/admin/vote"; -import { AdminVote_getListTableByStatusId } from "@/app_modules/admin/vote/fun/get/get_list_table_by_status_id"; -import { adminVote_funGetListPublish } from "@/app_modules/admin/vote/fun/get/status/get_list_publish"; export default async function Page() { - const dataVote = await adminVote_funGetListPublish({page: 1}); - - return ( - <> - - - ); -} \ No newline at end of file + return ( + <> + + + ); +} diff --git a/src/app/dev/admin/vote/child/table_reject/page.tsx b/src/app/dev/admin/vote/child/table_reject/page.tsx index a941804b..7d26522b 100644 --- a/src/app/dev/admin/vote/child/table_reject/page.tsx +++ b/src/app/dev/admin/vote/child/table_reject/page.tsx @@ -1,11 +1,9 @@ import { AdminVote_TableReject } from "@/app_modules/admin/vote"; -import { adminVote_funGetListReject } from "@/app_modules/admin/vote/fun"; export default async function Page() { - const dataVote = await adminVote_funGetListReject({ page: 1 }); return ( <> - + ); } diff --git a/src/app/dev/admin/vote/child/table_review/page.tsx b/src/app/dev/admin/vote/child/table_review/page.tsx index 2ce5111a..d6417422 100644 --- a/src/app/dev/admin/vote/child/table_review/page.tsx +++ b/src/app/dev/admin/vote/child/table_review/page.tsx @@ -1,12 +1,9 @@ import { AdminVote_TableReview } from "@/app_modules/admin/vote"; -import { adminVote_funGetListReview } from "@/app_modules/admin/vote/fun"; export default async function Page() { - const listVote = await adminVote_funGetListReview({ page: 1 }); - return ( <> - + ); } diff --git a/src/app_modules/_global/lib/api_fetch_master.ts b/src/app_modules/_global/lib/api_fetch_master.ts index 404f7094..4c1e5743 100644 --- a/src/app_modules/_global/lib/api_fetch_master.ts +++ b/src/app_modules/_global/lib/api_fetch_master.ts @@ -1,4 +1,9 @@ -export { apiGetMasterBank, apiGetMasterBidangBisnis, apiGetMasterStatusTransaksi }; +export { + apiGetMasterBank, + apiGetMasterBidangBisnis, + apiGetMasterStatusTransaksi, + apiGetAdminContact, +}; const apiGetMasterBank = async () => { const { token } = await fetch("/api/get-cookie").then((res) => res.json()); @@ -37,14 +42,51 @@ const apiGetMasterStatusTransaksi = async () => { if (!token) return await token.json().catch(() => null); const response = await fetch(`/api/master/status_transaksi`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }); + + return await response.json().catch(() => null); +}; + +const apiGetAdminContact = async () => { + try { + // Fetch token from cookie + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) { + console.error("No token found"); + return null; + } + + // Send PUT request to update portfolio logo + const response = await fetch(`/api/master/admin-contact`, { 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 + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Error get admin contact:", + errorData?.message || "Unknown error" + ); + + return null; + } + + return await response.json(); + } catch (error) { + console.error("Error get admin contact:", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/admin/app_info/fun/update/fun_update_nomor.ts b/src/app_modules/admin/app_info/fun/update/fun_update_nomor.ts index c2ea5a8f..8d4334aa 100644 --- a/src/app_modules/admin/app_info/fun/update/fun_update_nomor.ts +++ b/src/app_modules/admin/app_info/fun/update/fun_update_nomor.ts @@ -7,15 +7,23 @@ export default async function adminAppInformation_funUpdateNomorAdmin({ }: { data: any; }) { - const updt = await prisma.nomorAdmin.update({ - where: { - id: data.id, - }, - data: { - nomor: data.nomor, - }, - }); + try { + const updt = await prisma.nomorAdmin.update({ + where: { + id: data.id, + }, + data: { + nomor: data.nomor, + }, + }); - if (!updt) return { status: 400, message: "Gagal update" }; - return { status: 200, message: "Berhasil update" }; + if (!updt) return { status: 400, message: "Gagal update" }; + return { status: 200, message: "Berhasil update" }; + } catch (error) { + return { + status: 500, + message: "Error update", + error: (error as Error).message, + }; + } } diff --git a/src/app_modules/admin/app_info/ui/ui_main.tsx b/src/app_modules/admin/app_info/ui/ui_main.tsx index e682dc73..9a6a2759 100644 --- a/src/app_modules/admin/app_info/ui/ui_main.tsx +++ b/src/app_modules/admin/app_info/ui/ui_main.tsx @@ -12,11 +12,9 @@ import { import { AccentColor, AdminColor, MainColor } from "@/app_modules/_global/color/color_pallet"; export default function AdminAppInformation_UiMain({ - nomorAdmin, listBank, dataBidangBisnis, }: { - nomorAdmin: any; listBank: any[]; dataBidangBisnis: any[]; }) { @@ -61,7 +59,7 @@ export default function AdminAppInformation_UiMain({ {selectPage === "1" && ( - + )} {selectPage === "2" && ( diff --git a/src/app_modules/admin/app_info/view/view_info_whatsapp.tsx b/src/app_modules/admin/app_info/view/view_info_whatsapp.tsx index 00bb9129..893b2a7c 100644 --- a/src/app_modules/admin/app_info/view/view_info_whatsapp.tsx +++ b/src/app_modules/admin/app_info/view/view_info_whatsapp.tsx @@ -1,9 +1,17 @@ " use client"; +import { + AccentColor, + AdminColor, +} from "@/app_modules/_global/color/color_pallet"; +import { apiGetAdminContact } from "@/app_modules/_global/lib/api_fetch_master"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { clientLogger } from "@/util/clientLogger"; import { ActionIcon, Button, Collapse, + Grid, Group, Paper, Stack, @@ -11,41 +19,57 @@ import { Title, Tooltip, } from "@mantine/core"; +import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import { IconEdit, IconPhone } from "@tabler/icons-react"; import { useState } from "react"; import { ComponentAdminGlobal_NotifikasiBerhasil } from "../../_admin_global/admin_notifikasi/notifikasi_berhasil"; import { ComponentAdminGlobal_NotifikasiGagal } from "../../_admin_global/admin_notifikasi/notifikasi_gagal"; -import adminAppInformation_getNomorAdmin from "../fun/master/get_nomor_admin"; import adminAppInformation_funUpdateNomorAdmin from "../fun/update/fun_update_nomor"; -import { useDisclosure } from "@mantine/hooks"; -import { AccentColor, AdminColor, MainColor } from "@/app_modules/_global/color/color_pallet"; -export default function AdminAppInformation_ViewInformasiWhatApps({ - nomorAdmin, -}: { - nomorAdmin: any; -}) { - const [dataNomor, setDataNomor] = useState(nomorAdmin); +export default function AdminAppInformation_ViewInformasiWhatApps() { + const [dataNomor, setDataNomor] = useState(null); const [updateNomor, setUpdateNomor] = useState(""); const [opened, { toggle }] = useDisclosure(false); - async function onUpdate() { - const newNumber = (dataNomor.nomor = updateNomor); - setDataNomor({ - ...dataNomor, - nomor: newNumber, - }); + useShallowEffect(() => { + handleLoadData(); + }, []); - const updt = await adminAppInformation_funUpdateNomorAdmin({ - data: dataNomor, - }); - if (updt.status === 200) { - const loadDdata = await adminAppInformation_getNomorAdmin(); - setDataNomor(loadDdata); - toggle(); - ComponentAdminGlobal_NotifikasiBerhasil(updt.message); - } else { - ComponentAdminGlobal_NotifikasiGagal(updt.message); + const handleLoadData = async () => { + try { + const response = await apiGetAdminContact(); + + if (response) { + setDataNomor(response.data); + } else { + setDataNomor(""); + } + } catch (error) { + clientLogger.error("Error get admin contact", error); + setDataNomor(""); + } + }; + + async function onUpdate() { + try { + const newNumber = (dataNomor.nomor = updateNomor); + setDataNomor({ + ...dataNomor, + nomor: newNumber, + }); + + const updt = await adminAppInformation_funUpdateNomorAdmin({ + data: dataNomor, + }); + if (updt.status === 200) { + handleLoadData(); + toggle(); + ComponentAdminGlobal_NotifikasiBerhasil(updt.message); + } else { + ComponentAdminGlobal_NotifikasiGagal(updt.message); + } + } catch (error) { + clientLogger.error("Error update nomor admin", error); } } @@ -59,78 +83,96 @@ export default function AdminAppInformation_ViewInformasiWhatApps({ p={"xs"} style={{ borderRadius: "6px" }} > - Informasi WhatsApp + + Informasi WhatsApp + - - - - - {`+${dataNomor.nomor}`} - - { - toggle(); - setUpdateNomor(dataNomor.nomor); - }} + + + {!dataNomor ? ( + + ) : ( + + + - - - - - + + {`+${dataNomor?.nomor}`} + + { + toggle(); + setUpdateNomor(dataNomor?.nomor); + }} + > + + + + + - - - } - value={updateNomor} - label={Nomor Aktif Admin} - onChange={(val) => { - setUpdateNomor(val.currentTarget.value); - }} - /> - - - - - - - - + + } + value={updateNomor} + label={ + + Nomor Aktif Admin + + } + onChange={(val) => { + setUpdateNomor(val.currentTarget.value); + }} + /> + + + + + + + + + )} + + ); diff --git a/src/app_modules/admin/user-access/_lib/api_fetch_user_access.ts b/src/app_modules/admin/user-access/_lib/api_fetch_user_access.ts new file mode 100644 index 00000000..e8c96da7 --- /dev/null +++ b/src/app_modules/admin/user-access/_lib/api_fetch_user_access.ts @@ -0,0 +1,45 @@ +export { apiGetUserAccess }; + +const apiGetUserAccess = async ({ + page, + search, +}: { + page: string; + search?: string; +}) => { + try { + // Fetch token from cookie + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) { + console.error("No token found"); + return null; + } + + // Fetch data + const isPage = `?page=${page}`; + const isSearch = search ? `&search=${search}` : ""; + const response = await fetch(`/api/admin/user${isPage}${isSearch}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Error get data user access:", + errorData?.message || "Unknown error" + ); + return null; + } + + return response.json(); + } catch (error) { + console.error("Error get data user access:", error); + throw error; + } +}; diff --git a/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts b/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts index ba438e97..a7708deb 100644 --- a/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts +++ b/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts @@ -10,41 +10,50 @@ export default async function adminUserAccess_funEditAccess( value: boolean, nomor?: string ) { - const updt = await prisma.user.update({ - where: { - id: userId, - }, - data: { - active: value, - }, - }); + try { + const updt = await prisma.user.update({ + where: { + id: userId, + }, + data: { + active: value, + }, + }); - const headersList = headers(); - const host = headersList.get("host"); - const protocol = headersList.get("x-forwarded-proto") || "http"; - const path = headersList.get("x-invoke-path"); - const baseUrl = `${protocol}://${host}`; - // const fullUrl = `${protocol}://${host}${path}`; + const headersList = headers(); + const host = headersList.get("host"); + const protocol = headersList.get("x-forwarded-proto") || "http"; + const path = headersList.get("x-invoke-path"); + const baseUrl = `${protocol}://${host}`; + // const fullUrl = `${protocol}://${host}${path}`; - if (value === true) { - const message = `Hallo rekan HIPMI, Anda telah diberikan akses ke HIPMI Apps. Silakan mulai jelajahi fitur-fitur yang tersedia melalui link berikut: ${baseUrl}`; - const encodedMessage = encodeURIComponent(message); + if (value === true) { + const message = `Hallo rekan HIPMI, Anda telah diberikan akses ke HIPMI Apps. Silakan mulai jelajahi fitur-fitur yang tersedia melalui link berikut: ${baseUrl}`; + const encodedMessage = encodeURIComponent(message); - const res = await fetch( - `https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMessage} + const res = await fetch( + `https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMessage} ` - ); + ); - if (!res.ok) { - backendLogger.error("Error send message", res); + if (!res.ok) { + backendLogger.error("Error send message", res); + } + + const result = await res.json(); + + backendLogger.info("Success send message", result); } - const result = await res.json(); - - backendLogger.info("Success send message", result); + if (!updt) return { status: 400, message: "Update gagal" }; + revalidatePath("/dev/admin/user-access"); + return { status: 200, message: "Update berhasil" }; + } catch (error) { + backendLogger.error("Error update user", error); + return { + status: 500, + message: "Error udpate user", + error: (error as Error).message, + }; } - - if (!updt) return { status: 400, message: "Update gagal" }; - revalidatePath("/dev/admin/user-access"); - return { status: 200, message: "Update berhasil" }; } diff --git a/src/app_modules/admin/user-access/view/index.tsx b/src/app_modules/admin/user-access/view/index.tsx index f4edcf5d..34f9c827 100644 --- a/src/app_modules/admin/user-access/view/index.tsx +++ b/src/app_modules/admin/user-access/view/index.tsx @@ -24,28 +24,58 @@ import { WibuRealtime } from "wibu-pkg"; import { gs_access_user, IRealtimeData } from "@/lib/global_state"; import { useAtom } from "jotai"; import { AdminColor } from "@/app_modules/_global/color/color_pallet"; +import { useShallowEffect } from "@mantine/hooks"; +import { apiGetUserAccess } from "../_lib/api_fetch_user_access"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; -export default function AdminUserAccess_View({ listUser }: { listUser: any }) { - const [data, setData] = useState(listUser.data); +export default function AdminUserAccess_View() { + const [data, setData] = useState([]); + const [nPage, setNPage] = useState(1); const [isActivePage, setActivePage] = useState(1); - const [isNPage, setNPage] = useState(listUser.nPage); const [isSearch, setSearch] = useState(""); + const [isLoadingAccess, setIsLoadingAccess] = useState(false); const [isLoadingDelete, setIsLoadingDelete] = useState(false); const [userId, setUserId] = useState(""); + useShallowEffect(() => { + handleLoadData(); + }, [isActivePage, isSearch]); + + const handleLoadData = async () => { + try { + const response = await apiGetUserAccess({ + page: `${isActivePage}`, + search: isSearch, + }); + + if (response.success) { + setData(response.data.data); + setNPage(response.data.nPage); + } else { + setData([]); + } + } catch (error) { + console.error("Error get user access", error); + setData([]); + } + }; + + async function onSearch(s: any) { + setSearch(s); + } + + async function onPageClick(p: any) { + setActivePage(p); + } + async function onAccess(id: string, nomor: string) { try { setUserId(id); setIsLoadingAccess(true); await adminUserAccess_funEditAccess(id, true, nomor).then(async (res) => { if (res.status === 200) { - const value = await adminUserAccess_getListUser({ - page: 1, - search: isSearch, - }); - setData(value.data as any); - setNPage(value.nPage); + handleLoadData(); const dataNotifikasi: IRealtimeData = { status: true as any, @@ -78,12 +108,8 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { setIsLoadingDelete(true); await adminUserAccess_funEditAccess(id, false).then(async (res) => { if (res.status === 200) { - const value = await adminUserAccess_getListUser({ - page: 1, - search: isSearch, - }); - setData(value.data as any); - setNPage(value.nPage); + handleLoadData(); + ComponentGlobal_NotifikasiBerhasil(res.message); } else { ComponentGlobal_NotifikasiGagal(res.message); @@ -97,27 +123,6 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { } } - async function onSearch(s: any) { - setSearch(s); - setActivePage(1); - const loadData = await adminUserAccess_getListUser({ - search: s, - page: 1, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); - } - - async function onPageClick(p: any) { - setActivePage(p); - const loadData = await adminUserAccess_getListUser({ - search: isSearch, - page: p, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); - } - const tableBody = data.map((e, i) => ( @@ -181,40 +186,39 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { /> - - - - - - - - - - - {tableBody} -
-
Username
-
-
Nomor
-
-
Aksi
-
-
-
- { - onPageClick(val); - }} - /> -
-
+ {!data.length ? ( + + ) : ( + + + + + + + + + + + {tableBody} +
+
Username
+
+
Nomor
+
+
Aksi
+
+
+
+ { + onPageClick(val); + }} + /> +
+
+ )} ); diff --git a/src/app_modules/admin/vote/child/riwayat/index.tsx b/src/app_modules/admin/vote/child/riwayat/index.tsx index 7d261e09..2baf90a6 100644 --- a/src/app_modules/admin/vote/child/riwayat/index.tsx +++ b/src/app_modules/admin/vote/child/riwayat/index.tsx @@ -14,130 +14,161 @@ import { Stack, Table, Text, - TextInput + TextInput, } from "@mantine/core"; -import { useDisclosure } from "@mantine/hooks"; +import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import { IconReportAnalytics, IconSearch } from "@tabler/icons-react"; import { useRouter } from "next/navigation"; -import { ComponentAdminGlobal_TitlePage } from "@/app_modules/admin/_admin_global/_component"; -import { useState } from "react"; -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"; +import { ComponentAdminGlobal_TitlePage } from "@/app_modules/admin/_admin_global/_component"; +import ComponentAdminGlobal_IsEmptyData from "@/app_modules/admin/_admin_global/is_empty_data"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { clientLogger } from "@/util/clientLogger"; +import _ from "lodash"; +import { useState } from "react"; +import ComponentAdminVote_DetailHasil from "../../component/detail_hasil"; +import { AdminVote_getHasilById } from "../../fun/get/get_hasil_by_id"; +import { AdminVote_getListKontributorById } from "../../fun/get/get_list_kontributor_by_id"; +import { apiGetAdminVotingRiwayat } from "../../lib/api_fetch_admin_voting"; -export default function AdminVote_Riwayat({ - dataVote, -}: { - dataVote: MODEL_VOTING[]; -}) { +export default function AdminVote_Riwayat() { return ( <> - + ); } -function TableStatus({ listPublish }: { listPublish: any }) { +function TableStatus() { const router = useRouter(); const [opened, { open, close }] = useDisclosure(false); - const [data, setData] = useState(listPublish.data); const [hasil, setHasil] = useState(); const [kontributor, setKontributor] = useState(); const [voteId, setVoteId] = useState(""); const [loading, setLoading] = useState(false); - const [isNPage, setNPage] = useState(listPublish.nPage); + const [data, setData] = useState(null); + const [isNPage, setNPage] = useState(1); const [isActivePage, setActivePage] = useState(1); const [isSearch, setSearch] = useState(""); + useShallowEffect(() => { + handleLoadData(); + }, [isActivePage, isSearch]); + + const handleLoadData = async () => { + try { + const response = await apiGetAdminVotingRiwayat({ + page: `${isActivePage}`, + search: isSearch, + }); + + if (response?.success && response?.data?.data) { + setData(response.data.data); + setNPage(response.data.nPage || 1); + } else { + console.error("Invalid data format received:", response); + setData([]); + } + } catch (error) { + clientLogger.error("Error get data table publish", error); + setData([]); + } + }; + async function onSearch(s: string) { setSearch(s); - const loadData = await adminVote_funGetListRiwayat({ - page: 1, - search: s, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } async function onPageClick(p: any) { setActivePage(p); - const loadData = await adminVote_funGetListRiwayat({ - search: isSearch, - page: p, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } - const TableRows = data.map((e, i) => ( - - -
- -
- - -
{e?.Author?.username}
- - -
{e?.title}
- - -
- - {e?.deskripsi} - -
- - - - {e?.Voting_DaftarNamaVote.map((v) => ( - - - {v?.value} - - ))} - - - -
- {e?.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - -
- {e?.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - - )); + const renderTableBody = () => { + if (!Array.isArray(data) || data.length === 0) { + return ( + + +
+ Tidak ada data +
+ + + ); + } + + return data.map((e, i) => ( + + +
+ +
+ + +
{e?.Author?.username}
+ + +
{e?.title}
+ + +
+ + {e?.deskripsi} + +
+ + + + {e?.Voting_DaftarNamaVote.map((v) => ( + + - {v?.value} + + ))} + + + + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.awalVote))} +
+ + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.akhirVote))} +
+ + + )); + }; return ( <> @@ -148,80 +179,69 @@ function TableStatus({ listPublish }: { listPublish: any }) { color={AdminColor.softBlue} component={ } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - } - /> - {/* - Riwayat - } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - */} - - - - - - - - - - - - - - - - {TableRows} -
-
Aksi
-
-
Username
-
-
Judul
-
-
Deskripsi
-
-
Pilihan
-
-
Mulai Vote
-
-
Selesai Vote
-
-
- -
- } + radius={"xl"} + placeholder="Masukan judul" onChange={(val) => { - onPageClick(val); + onSearch(val.currentTarget.value); }} /> -
-
+ } + /> + + {!data ? ( + + ) : _.isEmpty(data) ? ( + + ) : ( + + + + + + + + + + + + + + + {renderTableBody()} +
+
Aksi
+
+
Username
+
+
Judul
+
+
Deskripsi
+
+
Pilihan
+
+
Mulai Vote
+
+
Selesai Vote
+
+
+ +
+ { + onPageClick(val); + }} + /> +
+
+ )} - + ); } -function TableStatus({ listPublish }: { listPublish: any }) { +function TableStatus() { const router = useRouter(); const [opened, { open, close }] = useDisclosure(false); - const [data, setData] = useState(listPublish.data); const [hasil, setHasil] = useState(); const [kontributor, setKontributor] = useState(); const [voteId, setVoteId] = useState(""); const [loading, setLoading] = useState(false); - const [isNPage, setNPage] = useState(listPublish.nPage); + const [data, setData] = useState(null); + const [isNPage, setNPage] = useState(1); const [isActivePage, setActivePage] = useState(1); const [isSearch, setSearch] = useState(""); + useShallowEffect(() => { + handleLoadData(); + }, [isActivePage, isSearch]); + + const handleLoadData = async () => { + try { + const response = await apiGetAdminVotingByStatus({ + name: "Publish", + page: `${isActivePage}`, + search: isSearch, + }); + + if (response?.success && response?.data?.data) { + setData(response.data.data); + setNPage(response.data.nPage || 1); + } else { + console.error("Invalid data format received:", response); + setData([]); + } + } catch (error) { + clientLogger.error("Error get data table publish", error); + setData([]); + } + }; + async function onSearch(s: string) { setSearch(s); - const loadData = await adminVote_funGetListPublish({ - page: 1, - search: s, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } async function onPageClick(p: any) { setActivePage(p); - const loadData = await adminVote_funGetListPublish({ - search: isSearch, - page: p, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } - const TableRows = data.map((e, i) => ( - - -
- -
- - -
{e?.Author?.username}
- - -
{e?.title}
- - -
- - {e?.deskripsi} - -
- - - - {e?.Voting_DaftarNamaVote.map((v) => ( - - - {v?.value} - - ))} - - - -
- {e?.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - -
- {e?.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - - )); + const renderTableBody = () => { + if (!Array.isArray(data) || data.length === 0) { + return ( + + +
+ Tidak ada data +
+ + + ); + } + + return data?.map((e, i) => ( + + +
+ +
+ + +
{e?.Author?.username}
+ + +
{e?.title}
+ + +
+ + {e?.deskripsi} + +
+ + + + {e?.Voting_DaftarNamaVote.map((v) => ( + + - {v?.value} + + ))} + + + + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.awalVote))} +
+ + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.akhirVote))} +
+ + + + )); + }; return ( <> - {/*
{JSON.stringify(listUser, null, 2)}
*/} } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - } - /> - {/* - Publish - } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - */} - - - - - - - - - - - - - - - - {TableRows} -
-
Aksi
-
-
Username
-
-
Judul
-
-
Deskripsi
-
-
Pilihan
-
-
Mulai Vote
-
-
Selesai Vote
-
-
- -
- } + radius={"xl"} + placeholder="Masukan judul" onChange={(val) => { - onPageClick(val); + onSearch(val.currentTarget.value); }} /> -
-
+ } + /> + + {!data ? ( + + ) : _.isEmpty(data) ? ( + + ) : ( + + + + + + + + + + + + + + + {renderTableBody()} +
+
Aksi
+
+
Username
+
+
Judul
+
+
Deskripsi
+
+
Pilihan
+
+
Mulai Vote
+
+
Selesai Vote
+
+
+ +
+ { + onPageClick(val); + }} + /> +
+
+ )}
- + ); } -function TableStatus({ listData }: { listData: any }) { +function TableStatus() { const router = useRouter(); const [opened, { open, close }] = useDisclosure(false); - const [data, setData] = useState(listData.data); const [votingId, setVotingId] = useState(""); const [catatan, setCatatan] = useState(""); + const [isLoading, setLoading] = useState(false); - const [isNPage, setNPage] = useState(listData.nPage); + const [data, setData] = useState(null); + const [nPage, setNPage] = useState(1); const [isActivePage, setActivePage] = useState(1); const [isSearch, setSearch] = useState(""); + useShallowEffect(() => { + handleLoadData(); + }, [isActivePage, isSearch]); + + const handleLoadData = async () => { + try { + const response = await apiGetAdminVotingByStatus({ + name: "Reject", + page: `${isActivePage}`, + search: isSearch, + }); + + if (response?.success && response?.data?.data) { + setData(response.data.data); + setNPage(response.data.nPage || 1); + } else { + console.error("Invalid data format received:", response); + setData([]); + } + } catch (error) { + clientLogger.error("Error get data table publish", error); + setData([]); + } + }; + async function onSearch(s: string) { setSearch(s); - const loadData = await adminVote_funGetListReject({ - page: 1, - search: s, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } async function onPageClick(p: any) { setActivePage(p); - const loadData = await adminVote_funGetListReject({ - search: isSearch, - page: p, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); } - async function onReject( - votingId: string, - catatan: string, - close: any, - setData: any - ) { - const res = await AdminVote_funEditCatatanRejectById(votingId, catatan); - if (res.status === 200) { - const loadData = await adminVote_funGetListReject({ - page: 1, - search: isSearch, - }); - setData(loadData.data as any); - setNPage(loadData.nPage); - setActivePage(1); - ComponentAdminGlobal_NotifikasiBerhasil(res.message); + async function onReject() { + try { + setLoading(true); + const res = await AdminVote_funEditCatatanRejectById(votingId, catatan); + if (res.status === 200) { + handleLoadData(); + ComponentAdminGlobal_NotifikasiBerhasil(res.message); + } else { + ComponentAdminGlobal_NotifikasiGagal(res.message); + } + } catch (error) { + console.log("Error get data voting review", error); + setVotingId(""); + } finally { close(); - } else { - ComponentAdminGlobal_NotifikasiGagal(res.message); + setLoading(false); + setVotingId(""); } } - const TableRows = data.map((e, i) => ( - - -
- -
- - -
- - {e.catatan} - -
- - -
{e?.Author?.Profile?.name}
- - -
{e.title}
- - -
- - {e.deskripsi} - -
- - - - {e.Voting_DaftarNamaVote.map((v) => ( - - - {v.value} - - ))} - - - -
- {e.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - -
- {e.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })} -
- - - )); + const renderTableBody = () => { + if (!Array.isArray(data) || data.length === 0) { + return ( + + +
+ Tidak ada data +
+ + + ); + } + + return data?.map((e, i) => ( + + +
+ +
+ + +
+ + {e.catatan} + +
+ + +
{e?.Author?.Profile?.name}
+ + +
{e.title}
+ + +
+ + {e.deskripsi} + +
+ + + + {e.Voting_DaftarNamaVote.map((v) => ( + + - {v.value} + + ))} + + + + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.awalVote))} +
+ + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.akhirVote))} +
+ + + )); + }; return ( <> - {/*
{JSON.stringify(listUser, null, 2)}
*/} } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - } - /> - {/* - Reject - } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - */} - - - - - - - - - - - - - - - - - {TableRows} -
-
Aksi
-
-
Catatan
-
-
Author
-
-
Judul
-
-
Deskripsi
-
-
Pilihan
-
-
Mulai Vote
-
-
Selesai Vote
-
-
- -
- } + radius={"xl"} + placeholder="Masukan judul" onChange={(val) => { - onPageClick(val); + onSearch(val.currentTarget.value); }} /> -
-
+ } + /> + + {!data ? ( + + ) : _.isEmpty(data) ? ( + + ) : ( + + + + + + + + + + + + + + + + {renderTableBody()} +
+
Aksi
+
+
Catatan
+
+
Author
+
+
Judul
+
+
Deskripsi
+
+
Pilihan
+
+
Mulai Vote
+
+
Selesai Vote
+
+
+ +
+ { + onPageClick(val); + }} + /> +
+
+ )}
- - - - - )); + return data?.map((e, i) => ( + + +
{e?.Author?.username}
+ + +
{e.title}
+ + +
+ + {e.deskripsi} + +
+ + + + {e.Voting_DaftarNamaVote.map((v) => ( + + - {v.value} + + ))} + + + + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.awalVote))} +
+ + +
+ {new Intl.DateTimeFormat("id-ID", { + dateStyle: "long", + }).format(new Date(e?.akhirVote))} +
+ + + + + + + + + + )); + }; return ( <> - {/*
{JSON.stringify(listUser, null, 2)}
*/} } /> - {/* - Review - } - radius={"xl"} - placeholder="Masukan judul" - onChange={(val) => { - onSearch(val.currentTarget.value); - }} - /> - */} - - {isShowReload && ( - -
- -
-
- )} + {!data ? ( + + ) : _.isEmpty(data) ? ( + + ) : ( + + {isShowReload && ( + +
+ +
+
+ )} - - - - - - - - - - + +
-
Username
-
-
Judul
-
-
Deskripsi
-
-
Pilihan
-
-
Mulai Vote
-
-
Selesai Vote
-
+ + + + + + + + + + + + {renderTableBody()} +
+
Username
+
+
Judul
+
+
Deskripsi
+
+
Pilihan
+
+
Mulai Vote
+
+
Selesai Vote
+
+
Aksi
+
+
- -
Aksi
- - - - {TableRows} - - - -
- { - onPageClick(val); - }} - /> -
-
+
+ { + onPageClick(val); + }} + /> +
+
+ )}
{ - onReject({ - catatan: catatan, - voteId: votingId, - setData(val) { - setData(val.data); - setNPage(val.nPage); - }, - close: () => { - closeReject(); - }, - setSaveLoading(val) { - setSaveLoading(val); - }, - }); + onReject(); }} - style={{ - backgroundColor: MainColor.green + style={{ + backgroundColor: MainColor.green, }} > Simpan @@ -384,23 +470,7 @@ function TableStatus({ listData }: { listData: any }) { loading={isLoadingPublish ? true : false} radius={"xl"} onClick={() => { - onPublish({ - awalVote: data[0].awalVote, - voteId: votingId, - setData(val) { - setData(val.data); - setNPage(val.nPage); - }, - close: () => { - closePublish(); - }, - setLoadingPublish: (val) => { - setLoadingPublish(val); - }, - setVotingId: (val) => { - setVotingId(val); - }, - }); + onPublish(); }} style={{ backgroundColor: MainColor.green, @@ -414,132 +484,3 @@ function TableStatus({ listData }: { listData: any }) { ); } - -async function onPublish({ - close, - voteId, - setData, - awalVote, - setLoadingPublish, - setVotingId, -}: { - close: any, - voteId: string; - setData: (val: { data: any[]; nPage: number }) => void; - awalVote: Date; - setLoadingPublish: (val: boolean) => void; - setVotingId: (val: string) => void; -}) { - const hariIni = new Date(); - const cekHari = moment(awalVote).diff(hariIni, "days"); - - if (cekHari < 0) - return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat"); - - setVotingId(voteId); - const res = await AdminVote_funEditStatusPublishById(voteId); - if (res.status === 200) { - setLoadingPublish(true); - - const dataNotifikasi: IRealtimeData = { - appId: res.data?.id as string, - status: res.data?.Voting_Status?.name as any, - userId: res.data?.authorId as any, - pesan: res.data?.title as any, - kategoriApp: "VOTING", - title: "Voting publish", - }; - - const notif = await adminNotifikasi_funCreateToUser({ - data: dataNotifikasi as any, - }); - - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, - }); - - WibuRealtime.setData({ - type: "trigger", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, - }); - } - const loadData = await adminVote_funGetListReview({ page: 1 }); - setData({ - data: loadData.data, - nPage: loadData.nPage, - }); - - ComponentGlobal_NotifikasiBerhasil(res.message); - setLoadingPublish(false); - } else { - ComponentGlobal_NotifikasiGagal(res.message); - } -} - -async function onReject({ - voteId, - catatan, - close, - setSaveLoading, - setData, -}: { - voteId: string; - catatan: string; - close: any; - setSaveLoading: (val: boolean) => void; - setData: (val: { data: any[]; nPage: number }) => void; -}) { - const data = { - id: voteId, - catatan: catatan, - }; - - const res = await AdminEvent_funEditCatatanById(data as any); - if (res.status === 200) { - setSaveLoading(true); - // const dataNotif = { - // appId: res.data?.id, - // status: res.data?.Voting_Status?.name as any, - // userId: res.data?.authorId as any, - // pesan: res.data?.title as any, - // kategoriApp: "VOTING", - // title: "Voting anda di tolak !", - // }; - - const dataNotifikasi: IRealtimeData = { - appId: res.data?.id as string, - status: res.data?.Voting_Status?.name as any, - userId: res.data?.authorId as any, - pesan: res.data?.title as any, - kategoriApp: "VOTING", - title: "Voting anda di tolak !", - }; - - const notif = await adminNotifikasi_funCreateToUser({ - data: dataNotifikasi as any, - }); - - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "USER", - dataMessage: dataNotifikasi, - }); - } - - const loadData = await adminVote_funGetListReview({ page: 1 }); - setData({ - data: loadData.data, - nPage: loadData.nPage, - }); - setSaveLoading(false); - ComponentGlobal_NotifikasiBerhasil(res.message); - close(); - } else { - ComponentGlobal_NotifikasiGagal(res.message); - } -} \ No newline at end of file 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 index 451fdfdd..89ad159f 100644 --- a/src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts +++ b/src/app_modules/admin/vote/lib/api_fetch_admin_voting.ts @@ -1,64 +1,135 @@ export { - apiGetAdminVoteStatusCountDashboard, - apiGetAdminVoteRiwayatCount, - apiGetAdminVotingByStatus -} -const apiGetAdminVoteStatusCountDashboard = async ({ name }: { - name: "Publish" | "Review" | "Reject"; + apiGetAdminVoteStatusCountDashboard, + apiGetAdminVoteRiwayatCount, + apiGetAdminVotingByStatus, + apiGetAdminVotingRiwayat, +}; +const apiGetAdminVoteStatusCountDashboard = 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 { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/vote/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 response = await fetch(`/api/admin/vote/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 apiGetAdminVoteRiwayatCount = async () => { - const { token } = await fetch("/api/get-cookie").then((res) => res.json()); - if (!token) return await token.json().catch(() => null); + 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/vote/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); -} + const response = await fetch(`/api/admin/vote/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); +}; -const apiGetAdminVotingByStatus = async ({ - name, - page, - search }: { - name: "Publish" | "Review" | "Reject"; - page: string; - search: string; - }) => { +const apiGetAdminVotingByStatus = async ({ + name, + page, + search, +}: { + name: "Publish" | "Review" | "Reject"; + page: string; + search: string; +}) => { + try { + // Fetch token from cookie const { token } = await fetch("/api/get-cookie").then((res) => res.json()); - if (!token) return await token.json().catch(() => null); + if (!token) { + console.error("No token found"); + return null; + } const isPage = page ? `?page=${page}` : ""; const isSearch = search ? `&search=${search}` : ""; const response = await fetch( - `/api/admin/vote/status/${name}${isPage}${isSearch}`, - { - 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 + `/api/admin/vote/status/${name}${isPage}${isSearch}`, + { + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${token}`, + }, + } + ); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Error get data voting admin", + errorData?.message || "Unknown error" + ); + return null; + } + + return response.json(); + } catch (error) { + console.log("Error get data voting admin", error); + throw error; + } +}; + + +const apiGetAdminVotingRiwayat = async ({ + page, + search, +}: { + page: string; + search: string; +}) => { + try { + // Fetch token from cookie + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) { + console.error("No token found"); + return null; + } + + const isPage = page ? `?page=${page}` : ""; + const isSearch = search ? `&search=${search}` : ""; + const response = await fetch( + `/api/admin/vote/status/riwayat${isPage}${isSearch}`, + { + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${token}`, + }, + } + ); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Error get data voting admin", + errorData?.message || "Unknown error" + ); + return null; + } + + return response.json(); + } catch (error) { + console.log("Error get data voting admin", error); + throw error; + } +}; + diff --git a/src/app_modules/auth/_lib/api_fetch_auth.ts b/src/app_modules/auth/_lib/api_fetch_auth.ts index 2e859a41..0bd42e65 100644 --- a/src/app_modules/auth/_lib/api_fetch_auth.ts +++ b/src/app_modules/auth/_lib/api_fetch_auth.ts @@ -37,7 +37,7 @@ const apiPostVerifikasiCodeOtp = async ({ nomor }: { nomor: string }) => { }; const apiDeleteAktivasiKodeOtpByNomor = async ({ id }: { id: string }) => { - const respone = await fetch(`/api/auth/code/${id}/peserta`, { + const respone = await fetch(`/api/auth/code/${id}`, { method: "DELETE", headers: { "Content-Type": "application/json",