From c057f20963df70f4ce2ac071007541678c6ff854 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Mon, 2 Jun 2025 14:28:36 +0800 Subject: [PATCH] fix: voting deskripsi - fix get user id di ssr menjadi di client --- .../api/voting/[id]/daftar-pilihan/route.ts | 27 ++++ .../(user)/vote/detail/draft/[id]/page.tsx | 7 +- .../(user)/vote/detail/reject/[id]/layout.tsx | 14 +- .../(user)/vote/detail/reject/[id]/page.tsx | 8 +- .../(user)/vote/detail/review/[id]/page.tsx | 8 +- src/app/dev/(user)/vote/edit/[id]/page.tsx | 15 +- src/app_modules/vote/_lib/api_voting.ts | 37 +++++ .../detail/detail_data_sebelum_publish.tsx | 13 +- src/app_modules/vote/detail/draft/index.tsx | 135 +++++++++------- src/app_modules/vote/detail/reject/index.tsx | 43 ++++-- src/app_modules/vote/detail/review/index.tsx | 61 +++++--- src/app_modules/vote/edit/index.tsx | 146 +++++++++--------- 12 files changed, 305 insertions(+), 209 deletions(-) create mode 100644 src/app/api/voting/[id]/daftar-pilihan/route.ts diff --git a/src/app/api/voting/[id]/daftar-pilihan/route.ts b/src/app/api/voting/[id]/daftar-pilihan/route.ts new file mode 100644 index 00000000..e2fbcdd4 --- /dev/null +++ b/src/app/api/voting/[id]/daftar-pilihan/route.ts @@ -0,0 +1,27 @@ +import { NextResponse } from "next/server"; +import prisma from "@/lib/prisma"; + +export async function GET( + request: Request, + { params }: { params: { id: string } } +) { + const { id } = params; + try { + const data = await prisma.voting_DaftarNamaVote.findMany({ + where: { + votingId: id, + isActive: true, + }, + }); + + return NextResponse.json( + { success: true, message: "Berhasil mendapatkan data", data: data }, + { status: 200 } + ); + } catch (error) { + return NextResponse.json( + { success: false, message: "Gagal mendapatkan data" }, + { status: 500 } + ); + } +} diff --git a/src/app/dev/(user)/vote/detail/draft/[id]/page.tsx b/src/app/dev/(user)/vote/detail/draft/[id]/page.tsx index 6403bd9f..72e78acd 100644 --- a/src/app/dev/(user)/vote/detail/draft/[id]/page.tsx +++ b/src/app/dev/(user)/vote/detail/draft/[id]/page.tsx @@ -1,13 +1,10 @@ import { Vote_DetailDraft } from "@/app_modules/vote"; -import { voting_funGetOneVotingbyId } from "@/app_modules/vote/fun/get/fun_get_one_by_id"; -export default async function Page({ params }: { params: { id: string } }) { - const voteId = params.id; - const dataVote = await voting_funGetOneVotingbyId(voteId); +export default async function Page() { return ( <> - + ); } diff --git a/src/app/dev/(user)/vote/detail/reject/[id]/layout.tsx b/src/app/dev/(user)/vote/detail/reject/[id]/layout.tsx index 469f132a..be22a097 100644 --- a/src/app/dev/(user)/vote/detail/reject/[id]/layout.tsx +++ b/src/app/dev/(user)/vote/detail/reject/[id]/layout.tsx @@ -1,8 +1,14 @@ import { LayoutVote_DetailReject } from "@/app_modules/vote"; import React from "react"; -export default async function Layout({children}: {children: React.ReactNode}) { - return<> - {children} +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {children} -} \ No newline at end of file + ); +} diff --git a/src/app/dev/(user)/vote/detail/reject/[id]/page.tsx b/src/app/dev/(user)/vote/detail/reject/[id]/page.tsx index e7b2ea93..ed28eb42 100644 --- a/src/app/dev/(user)/vote/detail/reject/[id]/page.tsx +++ b/src/app/dev/(user)/vote/detail/reject/[id]/page.tsx @@ -1,13 +1,9 @@ import { Vote_DetailReject } from "@/app_modules/vote"; -import { voting_funGetOneVotingbyId } from "@/app_modules/vote/fun/get/fun_get_one_by_id"; - -export default async function Page({ params }: { params: { id: string } }) { - let voteId = params.id; - const dataVote = await voting_funGetOneVotingbyId(voteId); +export default async function Page() { return ( <> - + ); } diff --git a/src/app/dev/(user)/vote/detail/review/[id]/page.tsx b/src/app/dev/(user)/vote/detail/review/[id]/page.tsx index f0febb86..6c820b2a 100644 --- a/src/app/dev/(user)/vote/detail/review/[id]/page.tsx +++ b/src/app/dev/(user)/vote/detail/review/[id]/page.tsx @@ -1,13 +1,9 @@ import { Vote_DetailReview } from "@/app_modules/vote"; -import { voting_funGetOneVotingbyId } from "@/app_modules/vote/fun/get/fun_get_one_by_id"; - -export default async function Page({ params }: { params: { id: string } }) { - let voteId = params.id; - const dataVote = await voting_funGetOneVotingbyId(voteId); +export default async function Page() { return ( <> - + ); } diff --git a/src/app/dev/(user)/vote/edit/[id]/page.tsx b/src/app/dev/(user)/vote/edit/[id]/page.tsx index a5fb255e..afceaf2e 100644 --- a/src/app/dev/(user)/vote/edit/[id]/page.tsx +++ b/src/app/dev/(user)/vote/edit/[id]/page.tsx @@ -1,20 +1,9 @@ import { Vote_Edit } from "@/app_modules/vote"; -import { Vote_getListDaftarNamaById } from "@/app_modules/vote/fun/get/get_list_daftar_vote_by_id"; -import { voting_funGetOneVotingbyId } from "@/app_modules/vote/fun/get/fun_get_one_by_id"; -import _ from "lodash"; - -export default async function Page({ params }: { params: { id: string } }) { - let voteId = params.id; - const dataVote = await voting_funGetOneVotingbyId(voteId); - const data = _.omit(dataVote, ["Voting_DaftarNamaVote"]); - const listDaftarVote = await Vote_getListDaftarNamaById(voteId); +export default async function Page() { return ( <> - + ); } diff --git a/src/app_modules/vote/_lib/api_voting.ts b/src/app_modules/vote/_lib/api_voting.ts index 82f82521..fab95764 100644 --- a/src/app_modules/vote/_lib/api_voting.ts +++ b/src/app_modules/vote/_lib/api_voting.ts @@ -74,3 +74,40 @@ export const apiGetKontributorById = async ({ const respone = await fetch(`/api/voting/kontributor?id=${id}&page=${page}`); return await respone.json().catch(() => null); }; + +export const apiGetDaftarPilihanById = async ({ id }: { id: 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 response = await fetch(`/api/voting/${id}/daftar-pilihan`, { + 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( + "Failed to get daftar pilihan:", + response.statusText, + errorData + ); + throw new Error(errorData?.message || "Failed to get daftar pilihan"); + } + + // Return the JSON response + return await response.json(); + } catch (error) { + console.error("Error get daftar pilihan", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/vote/component/detail/detail_data_sebelum_publish.tsx b/src/app_modules/vote/component/detail/detail_data_sebelum_publish.tsx index 70244c4e..1e12a3e6 100644 --- a/src/app_modules/vote/component/detail/detail_data_sebelum_publish.tsx +++ b/src/app_modules/vote/component/detail/detail_data_sebelum_publish.tsx @@ -12,7 +12,8 @@ import { IconCircle } from "@tabler/icons-react"; import { MODEL_VOTING } from "../../model/interface"; import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet"; import { Comp_SetInnerHTML } from "@/app_modules/_global/component/new/comp_set_inner_html"; - +import moment from "moment"; +import "moment/locale/id" export default function ComponentVote_DetailDataSebelumPublish ({ data, @@ -39,7 +40,7 @@ export default function ComponentVote_DetailDataSebelumPublish - +
Batas Voting @@ -57,15 +58,11 @@ export default function ComponentVote_DetailDataSebelumPublish > - {data?.awalVote.toLocaleDateString(["id-ID"], { - dateStyle: "medium", - })} + {moment(data?.awalVote).format("DD MMM YYYY")} - - {data?.akhirVote.toLocaleDateString(["id-ID"], { - dateStyle: "medium", - })} + {moment(data?.akhirVote).format("DD MMM YYYY")} diff --git a/src/app_modules/vote/detail/draft/index.tsx b/src/app_modules/vote/detail/draft/index.tsx index 173daad2..9e0cfc96 100644 --- a/src/app_modules/vote/detail/draft/index.tsx +++ b/src/app_modules/vote/detail/draft/index.tsx @@ -1,49 +1,58 @@ "use client"; -import { RouterVote } from "@/lib/router_hipmi/router_vote"; -import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet"; +import { + AccentColor, + MainColor, +} from "@/app_modules/_global/color/color_pallet"; import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin"; -import mqtt_client from "@/util/mqtt_client"; -import { Button, SimpleGrid, Stack } from "@mantine/core"; -import moment from "moment"; -import { useRouter } from "next/navigation"; -import { useState } from "react"; -import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish"; -import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id"; -import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id"; -import { MODEL_VOTING } from "../../model/interface"; import { IRealtimeData } from "@/lib/global_state"; -import { WibuRealtime } from "wibu-pkg"; -import { useShallowEffect } from "@mantine/hooks"; -import { voting_funGetOneVotingbyId } from "../../fun/get/fun_get_one_by_id"; -import _ from "lodash"; +import { RouterVote } from "@/lib/router_hipmi/router_vote"; import { clientLogger } from "@/util/clientLogger"; +import { Button, SimpleGrid, Stack } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; +import moment from "moment"; +import { useParams, useRouter } from "next/navigation"; +import { useState } from "react"; +import { WibuRealtime } from "wibu-pkg"; +import { apiGetOneVotingById } from "../../_lib/api_voting"; +import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish"; +import { MODEL_VOTING } from "../../model/interface"; +import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id"; +import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id"; -export default function Vote_DetailDraft({ - dataVote, -}: { - dataVote: MODEL_VOTING; -}) { - const [data, setData] = useState(dataVote); +export default function Vote_DetailDraft() { + const { id } = useParams(); + const [data, setData] = useState(); useShallowEffect(() => { - onLoadData(setData); - }, [setData]); + onLoadData(); + }, []); - async function onLoadData(setData: any) { - const loadData = await voting_funGetOneVotingbyId(dataVote.id); - setData(loadData); + async function onLoadData() { + try { + const response = await apiGetOneVotingById({ id: id as string }); + if (response) { + setData(response.data); + } else { + setData(null); + } + } catch (error) { + console.log(error); + } } + if (!data) return ; + return ( <> - {dataVote?.catatan && ( + {data?.catatan && ( )} @@ -72,39 +81,45 @@ function ButtonAction({ if (cekHari < 0) return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat"); - const res = await Vote_funEditStatusByStatusId(voteId, "2"); - if (res.status === 200) { - const dataNotifikasi: IRealtimeData = { - appId: res.data?.id as any, - status: res.data?.Voting_Status?.name as any, - userId: res.data?.authorId as any, - pesan: res.data?.title as any, - kategoriApp: "VOTING", - title: "Mengajukan review", - }; + setIsLoading(true); + try { + const res = await Vote_funEditStatusByStatusId(voteId, "2"); + if (res.status === 200) { + const dataNotifikasi: IRealtimeData = { + appId: res.data?.id as any, + status: res.data?.Voting_Status?.name as any, + userId: res.data?.authorId as any, + pesan: res.data?.title as any, + kategoriApp: "VOTING", + title: "Mengajukan review", + }; - const notif = await notifikasiToAdmin_funCreate({ - data: dataNotifikasi as any, - }); - - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "ADMIN", + const notif = await notifikasiToAdmin_funCreate({ + data: dataNotifikasi as any, }); - WibuRealtime.setData({ - type: "trigger", - pushNotificationTo: "ADMIN", - dataMessage: dataNotifikasi, - }); + if (notif.status === 201) { + WibuRealtime.setData({ + type: "notification", + pushNotificationTo: "ADMIN", + }); - ComponentGlobal_NotifikasiBerhasil("Berhasil Ajukan Review", 2000); - setIsLoading(true); - router.replace(RouterVote.status({ id: "2" })); + WibuRealtime.setData({ + type: "trigger", + pushNotificationTo: "ADMIN", + dataMessage: dataNotifikasi, + }); + + ComponentGlobal_NotifikasiBerhasil("Berhasil Ajukan Review", 2000); + router.replace(RouterVote.status({ id: "2" })); + } + } else { + setIsLoading(false); + ComponentGlobal_NotifikasiGagal(res.message); } - } else { - ComponentGlobal_NotifikasiGagal(res.message); + } catch (error) { + setIsLoading(false); + clientLogger.error("Error update status vote", error); } } @@ -117,7 +132,7 @@ function ButtonAction({ ComponentGlobal_NotifikasiBerhasil("Berhasil Hapus Vote", 2000); router.replace(RouterVote.status({ id: "3" })); } else { - setIsLoading(false); + setIsLoading(false); ComponentGlobal_NotifikasiGagal(res.message); } } catch (error) { @@ -163,7 +178,8 @@ function ButtonAction({ onClick={() => { setOpenModal1(false); }} - style={{ backgroundColor: AccentColor.blue}} c={AccentColor.white} + style={{ backgroundColor: AccentColor.blue }} + c={AccentColor.white} > Batal @@ -177,7 +193,7 @@ function ButtonAction({ onUpdate(); }} c={MainColor.darkblue} - style={{ backgroundColor: AccentColor.yellow }} + style={{ backgroundColor: AccentColor.yellow }} > Ajukan @@ -191,7 +207,8 @@ function ButtonAction({ close={() => setOpenModal2(false)} buttonKiri={ } diff --git a/src/app_modules/vote/edit/index.tsx b/src/app_modules/vote/edit/index.tsx index 7b3b8e9c..cf924ec2 100644 --- a/src/app_modules/vote/edit/index.tsx +++ b/src/app_modules/vote/edit/index.tsx @@ -3,8 +3,14 @@ import { MainColor } from "@/app_modules/_global/color/color_pallet"; import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input"; import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; +import Component_V3_Label_TextInput from "@/app_modules/_global/component/new/comp_V3_label_text_input"; +import { Component_V3_TextEditor } from "@/app_modules/_global/component/new/comp_V3_text_editor"; +import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html"; +import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { clientLogger } from "@/util/clientLogger"; import { ActionIcon, Box, @@ -14,16 +20,17 @@ import { Stack, Text, TextInput, - Textarea, } from "@mantine/core"; -import { DatePickerInput } from "@mantine/dates"; import { useShallowEffect } from "@mantine/hooks"; import { IconPlus, IconTrash } from "@tabler/icons-react"; import { useAtom } from "jotai"; import _ from "lodash"; -import moment from "moment"; -import { useRouter } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; +import { + apiGetDaftarPilihanById, + apiGetOneVotingById, +} from "../_lib/api_voting"; import { Vote_funEditById } from "../fun/edit/fun_edit_by_id"; import { Vote_getListDaftarNamaById } from "../fun/get/get_list_daftar_vote_by_id"; import { gs_vote_hotMenu, gs_vote_status } from "../global_state"; @@ -31,31 +38,54 @@ import { MODEL_VOTING, MODEL_VOTING_DAFTAR_NAMA_VOTE, } from "../model/interface"; -import { clientLogger } from "@/util/clientLogger"; -import Component_V3_Label_TextInput from "@/app_modules/_global/component/new/comp_V3_label_text_input"; -import { Component_V3_TextEditor } from "@/app_modules/_global/component/new/comp_V3_text_editor"; -import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html"; -import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting"; +import { DatePickerInput, DatesRangeValue } from "@mantine/dates"; +import moment from "moment"; +import "moment/locale/id"; -export default function Vote_Edit({ - dataVote, - listDaftarVote, -}: { - dataVote: MODEL_VOTING; - listDaftarVote: MODEL_VOTING_DAFTAR_NAMA_VOTE[]; -}) { - const [data, setData] = useState(dataVote); - const [pilihanNama, setPilihanNama] = useState(listDaftarVote); +export default function Vote_Edit() { + const { id } = useParams(); + const [data, setData] = useState(); + const [daftarPilihan, setDaftarPilihan] = useState< + MODEL_VOTING_DAFTAR_NAMA_VOTE[] | null + >(null); + + useShallowEffect(() => { + onLoadData(); + }, []); + + async function onLoadData() { + try { + const response = await apiGetOneVotingById({ id: id as string }); + if (response) { + const fixData = _.omit(response.data, ["Voting_DaftarNamaVote"]); + setData(fixData as any); + } else { + setData(null); + } + } catch (error) { + console.log(error); + } + } useShallowEffect(() => { onLoadList(); }, []); async function onLoadList() { - const loadList = await Vote_getListDaftarNamaById(data.id); - setPilihanNama(loadList as any); + try { + const response = await apiGetDaftarPilihanById({ id: id as string }); + if (response) { + setDaftarPilihan(response.data); + } else { + setDaftarPilihan(null); + } + } catch (error) { + console.log(error); + } } + if (!data || !daftarPilihan) return ; + return ( <> @@ -113,47 +143,6 @@ export default function Vote_Edit({ /> - {/* -