fix: voting

deskripsi
- fix get user id di ssr menjadi di client
This commit is contained in:
2025-06-02 14:28:36 +08:00
parent 6f686b6abf
commit c057f20963
12 changed files with 305 additions and 209 deletions

View File

@@ -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 }
);
}
}

View File

@@ -1,13 +1,10 @@
import { Vote_DetailDraft } from "@/app_modules/vote"; 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 } }) { export default async function Page() {
const voteId = params.id;
const dataVote = await voting_funGetOneVotingbyId(voteId);
return ( return (
<> <>
<Vote_DetailDraft dataVote={dataVote as any} /> <Vote_DetailDraft />
</> </>
); );
} }

View File

@@ -1,8 +1,14 @@
import { LayoutVote_DetailReject } from "@/app_modules/vote"; import { LayoutVote_DetailReject } from "@/app_modules/vote";
import React from "react"; import React from "react";
export default async function Layout({children}: {children: React.ReactNode}) { export default async function Layout({
return<> children,
<LayoutVote_DetailReject>{children}</LayoutVote_DetailReject> }: {
children: React.ReactNode;
}) {
return (
<>
<LayoutVote_DetailReject>{children}</LayoutVote_DetailReject>
</> </>
);
} }

View File

@@ -1,13 +1,9 @@
import { Vote_DetailReject } from "@/app_modules/vote"; 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 ( return (
<> <>
<Vote_DetailReject dataVote={dataVote as any} /> <Vote_DetailReject />
</> </>
); );
} }

View File

@@ -1,13 +1,9 @@
import { Vote_DetailReview } from "@/app_modules/vote"; 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 ( return (
<> <>
<Vote_DetailReview dataVote={dataVote as any} /> <Vote_DetailReview />
</> </>
); );
} }

View File

@@ -1,20 +1,9 @@
import { Vote_Edit } from "@/app_modules/vote"; 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 ( return (
<> <>
<Vote_Edit <Vote_Edit />
dataVote={data as any}
listDaftarVote={listDaftarVote as any}
/>
</> </>
); );
} }

View File

@@ -74,3 +74,40 @@ export const apiGetKontributorById = async ({
const respone = await fetch(`/api/voting/kontributor?id=${id}&page=${page}`); const respone = await fetch(`/api/voting/kontributor?id=${id}&page=${page}`);
return await respone.json().catch(() => null); 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
}
};

View File

@@ -12,7 +12,8 @@ import { IconCircle } from "@tabler/icons-react";
import { MODEL_VOTING } from "../../model/interface"; import { MODEL_VOTING } from "../../model/interface";
import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet"; import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet";
import { Comp_SetInnerHTML } from "@/app_modules/_global/component/new/comp_set_inner_html"; 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 export default function ComponentVote_DetailDataSebelumPublish
({ ({
data, data,
@@ -39,7 +40,7 @@ export default function ComponentVote_DetailDataSebelumPublish
</Center> </Center>
<Comp_SetInnerHTML props={data?.deskripsi} /> <Comp_SetInnerHTML props={data?.deskripsi} />
<Stack spacing={0} align="center"> <Stack spacing={"xs"} align="center">
<Center> <Center>
<Text fz={10} fw={"bold"}> <Text fz={10} fw={"bold"}>
Batas Voting Batas Voting
@@ -57,15 +58,11 @@ export default function ComponentVote_DetailDataSebelumPublish
> >
<Group> <Group>
<Text> <Text>
{data?.awalVote.toLocaleDateString(["id-ID"], { {moment(data?.awalVote).format("DD MMM YYYY")}
dateStyle: "medium",
})}
</Text> </Text>
<Text>-</Text> <Text>-</Text>
<Text> <Text>
{data?.akhirVote.toLocaleDateString(["id-ID"], { {moment(data?.akhirVote).format("DD MMM YYYY")}
dateStyle: "medium",
})}
</Text> </Text>
</Group> </Group>
</Badge> </Badge>

View File

@@ -1,49 +1,58 @@
"use client"; "use client";
import { RouterVote } from "@/lib/router_hipmi/router_vote"; import {
import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet"; AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information"; import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal"; 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 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 { IRealtimeData } from "@/lib/global_state";
import { WibuRealtime } from "wibu-pkg"; import { RouterVote } from "@/lib/router_hipmi/router_vote";
import { useShallowEffect } from "@mantine/hooks";
import { voting_funGetOneVotingbyId } from "../../fun/get/fun_get_one_by_id";
import _ from "lodash";
import { clientLogger } from "@/util/clientLogger"; 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({ export default function Vote_DetailDraft() {
dataVote, const { id } = useParams();
}: { const [data, setData] = useState<MODEL_VOTING | null>();
dataVote: MODEL_VOTING;
}) {
const [data, setData] = useState(dataVote);
useShallowEffect(() => { useShallowEffect(() => {
onLoadData(setData); onLoadData();
}, [setData]); }, []);
async function onLoadData(setData: any) { async function onLoadData() {
const loadData = await voting_funGetOneVotingbyId(dataVote.id); try {
setData(loadData); const response = await apiGetOneVotingById({ id: id as string });
if (response) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
console.log(error);
}
} }
if (!data) return <CustomSkeleton height={400} />;
return ( return (
<> <>
<Stack spacing={"xl"}> <Stack spacing={"xl"}>
{dataVote?.catatan && ( {data?.catatan && (
<ComponentGlobal_BoxInformation isReport informasi={data?.catatan} /> <ComponentGlobal_BoxInformation isReport informasi={data?.catatan} />
)} )}
<ComponentVote_DetailDataSebelumPublish data={data} /> <ComponentVote_DetailDataSebelumPublish data={data} />
@@ -72,39 +81,45 @@ function ButtonAction({
if (cekHari < 0) if (cekHari < 0)
return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat"); return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat");
const res = await Vote_funEditStatusByStatusId(voteId, "2"); setIsLoading(true);
if (res.status === 200) { try {
const dataNotifikasi: IRealtimeData = { const res = await Vote_funEditStatusByStatusId(voteId, "2");
appId: res.data?.id as any, if (res.status === 200) {
status: res.data?.Voting_Status?.name as any, const dataNotifikasi: IRealtimeData = {
userId: res.data?.authorId as any, appId: res.data?.id as any,
pesan: res.data?.title as any, status: res.data?.Voting_Status?.name as any,
kategoriApp: "VOTING", userId: res.data?.authorId as any,
title: "Mengajukan review", pesan: res.data?.title as any,
}; kategoriApp: "VOTING",
title: "Mengajukan review",
};
const notif = await notifikasiToAdmin_funCreate({ const notif = await notifikasiToAdmin_funCreate({
data: dataNotifikasi as any, data: dataNotifikasi as any,
});
if (notif.status === 201) {
WibuRealtime.setData({
type: "notification",
pushNotificationTo: "ADMIN",
}); });
WibuRealtime.setData({ if (notif.status === 201) {
type: "trigger", WibuRealtime.setData({
pushNotificationTo: "ADMIN", type: "notification",
dataMessage: dataNotifikasi, pushNotificationTo: "ADMIN",
}); });
ComponentGlobal_NotifikasiBerhasil("Berhasil Ajukan Review", 2000); WibuRealtime.setData({
setIsLoading(true); type: "trigger",
router.replace(RouterVote.status({ id: "2" })); pushNotificationTo: "ADMIN",
dataMessage: dataNotifikasi,
});
ComponentGlobal_NotifikasiBerhasil("Berhasil Ajukan Review", 2000);
router.replace(RouterVote.status({ id: "2" }));
}
} else {
setIsLoading(false);
ComponentGlobal_NotifikasiGagal(res.message);
} }
} else { } catch (error) {
ComponentGlobal_NotifikasiGagal(res.message); setIsLoading(false);
clientLogger.error("Error update status vote", error);
} }
} }
@@ -117,7 +132,7 @@ function ButtonAction({
ComponentGlobal_NotifikasiBerhasil("Berhasil Hapus Vote", 2000); ComponentGlobal_NotifikasiBerhasil("Berhasil Hapus Vote", 2000);
router.replace(RouterVote.status({ id: "3" })); router.replace(RouterVote.status({ id: "3" }));
} else { } else {
setIsLoading(false); setIsLoading(false);
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
} catch (error) { } catch (error) {
@@ -163,7 +178,8 @@ function ButtonAction({
onClick={() => { onClick={() => {
setOpenModal1(false); setOpenModal1(false);
}} }}
style={{ backgroundColor: AccentColor.blue}} c={AccentColor.white} style={{ backgroundColor: AccentColor.blue }}
c={AccentColor.white}
> >
Batal Batal
</Button> </Button>
@@ -177,7 +193,7 @@ function ButtonAction({
onUpdate(); onUpdate();
}} }}
c={MainColor.darkblue} c={MainColor.darkblue}
style={{ backgroundColor: AccentColor.yellow }} style={{ backgroundColor: AccentColor.yellow }}
> >
Ajukan Ajukan
</Button> </Button>
@@ -191,7 +207,8 @@ function ButtonAction({
close={() => setOpenModal2(false)} close={() => setOpenModal2(false)}
buttonKiri={ buttonKiri={
<Button <Button
style={{ backgroundColor: AccentColor.blue}} c={AccentColor.white} style={{ backgroundColor: AccentColor.blue }}
c={AccentColor.white}
radius={"xl"} radius={"xl"}
onClick={() => { onClick={() => {
setOpenModal2(false); setOpenModal2(false);

View File

@@ -1,35 +1,52 @@
"use client"; "use client";
import { AccentColor, MainColor } from "@/app_modules/_global/color";
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information"; import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal"; import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { RouterVote } from "@/lib/router_hipmi/router_vote";
import { clientLogger } from "@/util/clientLogger";
import { Button, SimpleGrid, Stack } from "@mantine/core"; import { Button, SimpleGrid, Stack } from "@mantine/core";
import { useAtom } from "jotai"; import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { apiGetOneVotingById } from "../../_lib/api_voting";
import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish"; import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish";
import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id"; import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id";
import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id"; import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id";
import { gs_vote_status } from "../../global_state";
import { MODEL_VOTING } from "../../model/interface"; import { MODEL_VOTING } from "../../model/interface";
import { RouterVote } from "@/lib/router_hipmi/router_vote";
import { AccentColor, MainColor } from "@/app_modules/_global/color";
import { clientLogger } from "@/util/clientLogger";
export default function Vote_DetailReject({ export default function Vote_DetailReject() {
dataVote, const { id } = useParams();
}: { const [data, setData] = useState<MODEL_VOTING | null>();
dataVote: MODEL_VOTING;
}) { useShallowEffect(() => {
const [data, setData] = useState(dataVote); onLoadData();
}, []);
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 <CustomSkeleton height={400} />;
return ( return (
<> <>
<Stack spacing={"xl"}> <Stack spacing={"xl"}>
<ComponentGlobal_BoxInformation isReport informasi={data?.catatan} /> <ComponentGlobal_BoxInformation isReport informasi={data?.catatan} />
<ComponentVote_DetailDataSebelumPublish data={data as any} /> <ComponentVote_DetailDataSebelumPublish data={data as any} />
<ButtonAction voteId={data.id} /> <ButtonAction voteId={id as string} />
</Stack> </Stack>
</> </>
); );

View File

@@ -1,35 +1,53 @@
"use client"; "use client";
import { IRealtimeData } from "@/lib/global_state"; import { AccentColor, MainColor } from "@/app_modules/_global/color";
import { RouterVote } from "@/lib/router_hipmi/router_vote"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal"; 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 notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
import { IRealtimeData } from "@/lib/global_state";
import { RouterVote } from "@/lib/router_hipmi/router_vote";
import { Button, Stack } from "@mantine/core"; import { Button, Stack } from "@mantine/core";
import { useRouter } from "next/navigation"; import { useShallowEffect } from "@mantine/hooks";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { WibuRealtime } from "wibu-pkg"; import { WibuRealtime } from "wibu-pkg";
import { apiGetOneVotingById } from "../../_lib/api_voting";
import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish"; import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish";
import { voting_checkStatus } from "../../fun";
import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id"; import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id";
import { MODEL_VOTING } from "../../model/interface"; import { MODEL_VOTING } from "../../model/interface";
import { voting_checkStatus } from "../../fun";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
import { AccentColor, MainColor } from "@/app_modules/_global/color";
export default function Vote_DetailReview({ export default function Vote_DetailReview() {
dataVote, const { id } = useParams();
}: { const [data, setData] = useState<MODEL_VOTING | null>();
dataVote: MODEL_VOTING;
}) { useShallowEffect(() => {
onLoadData();
}, []);
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 <CustomSkeleton height={400} />;
return ( return (
<> <>
<Stack spacing={"xl"}> <Stack spacing={"xl"}>
<ComponentVote_DetailDataSebelumPublish data={dataVote as any} /> <ComponentVote_DetailDataSebelumPublish data={data} />
<ButtonAction <ButtonAction voteId={id as string} statusId={data.voting_StatusId} />
voteId={dataVote.id}
statusId={dataVote.voting_StatusId}
/>
</Stack> </Stack>
</> </>
); );
@@ -50,6 +68,7 @@ function ButtonAction({
const check = await voting_checkStatus({ id: voteId }); const check = await voting_checkStatus({ id: voteId });
if (check) { if (check) {
setIsLoading(true);
const res = await Vote_funEditStatusByStatusId(voteId, "3"); const res = await Vote_funEditStatusByStatusId(voteId, "3");
if (res.status === 200) { if (res.status === 200) {
const dataNotifikasi: IRealtimeData = { const dataNotifikasi: IRealtimeData = {
@@ -79,11 +98,12 @@ function ButtonAction({
} }
ComponentGlobal_NotifikasiBerhasil("Berhasil Batalkan Review", 2000); ComponentGlobal_NotifikasiBerhasil("Berhasil Batalkan Review", 2000);
router.replace(RouterVote.status({ id: "3" })); router.replace(RouterVote.status({ id: "3" }));
setIsLoading(true);
} else { } else {
setIsLoading(false);
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
} else { } else {
setIsLoading(false);
ComponentGlobal_NotifikasiPeringatan("Voting telah direview admin"); ComponentGlobal_NotifikasiPeringatan("Voting telah direview admin");
} }
} }
@@ -105,7 +125,12 @@ function ButtonAction({
opened={openModal} opened={openModal}
close={() => setOpenModal(false)} close={() => setOpenModal(false)}
buttonKiri={ buttonKiri={
<Button style={{ backgroundColor: AccentColor.blue}} c={AccentColor.white} radius={"xl"} onClick={() => setOpenModal(false)}> <Button
style={{ backgroundColor: AccentColor.blue }}
c={AccentColor.white}
radius={"xl"}
onClick={() => setOpenModal(false)}
>
Batal Batal
</Button> </Button>
} }

View File

@@ -3,8 +3,14 @@
import { MainColor } from "@/app_modules/_global/color/color_pallet"; import { MainColor } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input"; import ComponentGlobal_ErrorInput from "@/app_modules/_global/component/error_input";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; 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_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { clientLogger } from "@/util/clientLogger";
import { import {
ActionIcon, ActionIcon,
Box, Box,
@@ -14,16 +20,17 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Textarea,
} from "@mantine/core"; } from "@mantine/core";
import { DatePickerInput } from "@mantine/dates";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { IconPlus, IconTrash } from "@tabler/icons-react"; import { IconPlus, IconTrash } from "@tabler/icons-react";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import _ from "lodash"; import _ from "lodash";
import moment from "moment"; import { useParams, useRouter } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import {
apiGetDaftarPilihanById,
apiGetOneVotingById,
} from "../_lib/api_voting";
import { Vote_funEditById } from "../fun/edit/fun_edit_by_id"; import { Vote_funEditById } from "../fun/edit/fun_edit_by_id";
import { Vote_getListDaftarNamaById } from "../fun/get/get_list_daftar_vote_by_id"; import { Vote_getListDaftarNamaById } from "../fun/get/get_list_daftar_vote_by_id";
import { gs_vote_hotMenu, gs_vote_status } from "../global_state"; import { gs_vote_hotMenu, gs_vote_status } from "../global_state";
@@ -31,31 +38,54 @@ import {
MODEL_VOTING, MODEL_VOTING,
MODEL_VOTING_DAFTAR_NAMA_VOTE, MODEL_VOTING_DAFTAR_NAMA_VOTE,
} from "../model/interface"; } from "../model/interface";
import { clientLogger } from "@/util/clientLogger"; import { DatePickerInput, DatesRangeValue } from "@mantine/dates";
import Component_V3_Label_TextInput from "@/app_modules/_global/component/new/comp_V3_label_text_input"; import moment from "moment";
import { Component_V3_TextEditor } from "@/app_modules/_global/component/new/comp_V3_text_editor"; import "moment/locale/id";
import { funReplaceHtml } from "@/app_modules/_global/fun/fun_replace_html";
import { maxInputLength } from "@/app_modules/_global/lib/maximal_setting";
export default function Vote_Edit({ export default function Vote_Edit() {
dataVote, const { id } = useParams();
listDaftarVote, const [data, setData] = useState<MODEL_VOTING | null>();
}: { const [daftarPilihan, setDaftarPilihan] = useState<
dataVote: MODEL_VOTING; MODEL_VOTING_DAFTAR_NAMA_VOTE[] | null
listDaftarVote: MODEL_VOTING_DAFTAR_NAMA_VOTE[]; >(null);
}) {
const [data, setData] = useState(dataVote); useShallowEffect(() => {
const [pilihanNama, setPilihanNama] = useState(listDaftarVote); 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(() => { useShallowEffect(() => {
onLoadList(); onLoadList();
}, []); }, []);
async function onLoadList() { async function onLoadList() {
const loadList = await Vote_getListDaftarNamaById(data.id); try {
setPilihanNama(loadList as any); 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 <CustomSkeleton height={400} />;
return ( return (
<> <>
<Stack px={"sm"} c={"white"} mb={"xl"}> <Stack px={"sm"} c={"white"} mb={"xl"}>
@@ -113,47 +143,6 @@ export default function Vote_Edit({
/> />
</Stack> </Stack>
{/* <Stack spacing={5}>
<Textarea
styles={{
label: {
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
},
}}
label="Deskripsi"
autosize
minRows={2}
maxRows={5}
withAsterisk
placeholder="Deskripsi"
value={data.deskripsi}
maxLength={300}
error={
data.deskripsi === "" ? (
<ComponentGlobal_ErrorInput text="Masukan deskripsi" />
) : (
""
)
}
onChange={(val) => {
setData({
...data,
deskripsi: val.target.value,
});
}}
/>
<ComponentGlobal_InputCountDown
lengthInput={data.deskripsi.length}
maxInput={300}
/>
</Stack> */}
<DatePickerInput <DatePickerInput
styles={{ styles={{
label: { label: {
@@ -174,7 +163,6 @@ export default function Vote_Edit({
excludeDate={(date) => { excludeDate={(date) => {
return moment(date).diff(Date.now(), "days") < 0; return moment(date).diff(Date.now(), "days") < 0;
}} }}
value={[data.awalVote, data.akhirVote]}
error={ error={
data.awalVote === null || data.akhirVote === null ? ( data.awalVote === null || data.akhirVote === null ? (
<ComponentGlobal_ErrorInput text="Invalid Date" /> <ComponentGlobal_ErrorInput text="Invalid Date" />
@@ -182,11 +170,17 @@ export default function Vote_Edit({
"" ""
) )
} }
onChange={(val: any) => { value={[
data.awalVote ? moment(data.awalVote).toDate() : null,
data.akhirVote ? moment(data.akhirVote).toDate() : null,
]}
onChange={(val) => {
if (!val || val.length < 2) return;
setData({ setData({
...data, ...data,
awalVote: val[0], awalVote: val[0] as Date,
akhirVote: val[1], akhirVote: val[1] as Date,
}); });
}} }}
/> />
@@ -200,7 +194,7 @@ export default function Vote_Edit({
<Stack> <Stack>
<Stack> <Stack>
{pilihanNama.map((e, index) => ( {daftarPilihan.map((e, index) => (
<Group key={index} position="apart" align="center"> <Group key={index} position="apart" align="center">
<Box w={"85%"}> <Box w={"85%"}>
<TextInput <TextInput
@@ -228,9 +222,9 @@ export default function Vote_Edit({
) )
} }
onChange={(v) => { onChange={(v) => {
const cloneData = _.clone(pilihanNama); const cloneData = _.clone(daftarPilihan);
cloneData[index].value = v.currentTarget.value; cloneData[index].value = v.currentTarget.value;
setPilihanNama([...pilihanNama]); setDaftarPilihan([...cloneData]);
}} }}
/> />
</Box> </Box>
@@ -238,17 +232,17 @@ export default function Vote_Edit({
mt={"lg"} mt={"lg"}
variant="transparent" variant="transparent"
radius={"xl"} radius={"xl"}
disabled={pilihanNama.length < 3 ? true : false} disabled={daftarPilihan.length < 3 ? true : false}
onClick={() => { onClick={() => {
pilihanNama.splice(index, 1); daftarPilihan.splice(index, 1);
setPilihanNama([...pilihanNama]); setDaftarPilihan([...daftarPilihan]);
}} }}
> >
<IconTrash <IconTrash
style={{ style={{
transition: "0.5s", transition: "0.5s",
}} }}
color={pilihanNama.length < 3 ? "gray" : "red"} color={daftarPilihan.length < 3 ? "gray" : "red"}
/> />
</ActionIcon> </ActionIcon>
</Group> </Group>
@@ -257,11 +251,11 @@ export default function Vote_Edit({
<Group position="center"> <Group position="center">
<Button <Button
disabled={pilihanNama.length >= 4 ? true : false} disabled={daftarPilihan.length >= 4 ? true : false}
radius={"xl"} radius={"xl"}
leftIcon={<IconPlus size={15} />} leftIcon={<IconPlus size={15} />}
onClick={() => { onClick={() => {
setPilihanNama([...(pilihanNama as any), { value: "" }]); setDaftarPilihan([...(daftarPilihan as any), { value: "" }]);
}} }}
compact compact
bg={MainColor.yellow} bg={MainColor.yellow}
@@ -274,9 +268,7 @@ export default function Vote_Edit({
</Stack> </Stack>
</Stack> </Stack>
<ButtonAction data={data} listVoting={pilihanNama} /> <ButtonAction data={data} listVoting={daftarPilihan as any} />
{/* <pre>{JSON.stringify(listDaftarVote, null, 2)}</pre> */}
</Stack> </Stack>
</> </>
); );