QC Voting

- # fix
- Beranda dan mandatori input
## No issuee
This commit is contained in:
2024-05-21 15:24:37 +08:00
parent dbeb740d1f
commit ce35aa8f51
32 changed files with 568 additions and 234 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -4,6 +4,7 @@ import ColabViewChat from "@/app_modules/colab/detail/chat";
import colab_V2getListMessageByRoomId from "@/app_modules/colab/fun/chat/get_message_by_room_id"; import colab_V2getListMessageByRoomId from "@/app_modules/colab/fun/chat/get_message_by_room_id";
import colab_getMessageByRoomId from "@/app_modules/colab/fun/get/room_chat/get_message_by_room_id"; import colab_getMessageByRoomId from "@/app_modules/colab/fun/get/room_chat/get_message_by_room_id";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { user_getOneByUserId } from "@/app_modules/home/fun/get/get_one_user_by_id";
import _ from "lodash"; import _ from "lodash";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
@@ -16,20 +17,23 @@ export default async function Page({ params }: { params: { id: string } }) {
"ProjectCollaboration_AnggotaRoomChat", "ProjectCollaboration_AnggotaRoomChat",
]); ]);
let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 }); let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 });
const dataUserLogin = await user_getOneByUserId(userLoginId);
// console.log(dataUserLogin);
return ( return (
<> <>
<ColabViewChat {/* <ColabViewChat
listMsg={listMsg as any} listMsg={listMsg as any}
dataRoom={dataRoom as any} dataRoom={dataRoom as any}
userLoginId={userLoginId} userLoginId={userLoginId}
/> /> */}
{/* <Colab_GroupChatView <Colab_GroupChatView
userLoginId={userLoginId} userLoginId={userLoginId}
listMsg={listMsg} listMsg={listMsg}
selectRoom={dataRoom as any} selectRoom={dataRoom as any}
/> */} dataUserLogin={dataUserLogin as any}
/>
</> </>
); );
} }

View File

@@ -127,13 +127,13 @@ function DetailRiwayat({ listRiwayat }: { listRiwayat: MODEL_EVENT[] }) {
sx={{ borderStyle: "solid", borderWidth: "0.5px" }} sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
radius={"xl"} radius={"xl"}
src={ src={
RouterProfile.api_foto_profile + e.User.Profile.imagesId RouterProfile.api_foto_profile + e?.User?.Profile?.imagesId
} }
/> />
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Group align="center" h={"100%"}> <Group align="center" h={"100%"}>
<Text>{e.User.Profile.name}</Text> <Text>{e?.User?.Profile?.name}</Text>
</Group> </Group>
</Grid.Col> </Grid.Col>
</Grid> </Grid>

View File

@@ -130,13 +130,13 @@ function TableStatus({ listPublish }: { listPublish: MODEL_EVENT[] }) {
radius={"xl"} radius={"xl"}
src={ src={
RouterProfile.api_foto_profile + RouterProfile.api_foto_profile +
e.User.Profile.imagesId e?.User?.Profile?.imagesId
} }
/> />
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Group align="center" h={"100%"}> <Group align="center" h={"100%"}>
<Text>{e.User.Profile.name}</Text> <Text>{e?.User?.Profile?.name}</Text>
</Group> </Group>
</Grid.Col> </Grid.Col>
</Grid> </Grid>

View File

@@ -69,7 +69,7 @@ function TableStatus({ listReject }: { listReject: MODEL_EVENT[] }) {
const TableRows = data.map((e, i) => ( const TableRows = data.map((e, i) => (
<tr key={i}> <tr key={i}>
<td> <td>
<Box w={200}>{e.Author.Profile.name}</Box> <Box w={200}>{e?.Author?.Profile?.name}</Box>
</td> </td>
<td> <td>
<Box w={200}>{e.title}</Box> <Box w={200}>{e.title}</Box>

View File

@@ -66,7 +66,7 @@ function TableStatus({ listReview }: { listReview: MODEL_EVENT[] }) {
const TableRows = data.map((e, i) => ( const TableRows = data.map((e, i) => (
<tr key={i}> <tr key={i}>
<td>{e.Author.Profile.name}</td> <td>{e?.Author?.Profile?.name}</td>
<td>{e.title}</td> <td>{e.title}</td>
<td>{e.lokasi}</td> <td>{e.lokasi}</td>
<td>{e.EventMaster_TipeAcara.name}</td> <td>{e.EventMaster_TipeAcara.name}</td>

View File

@@ -70,16 +70,16 @@ function TableStatus({ listPublish }: { listPublish: MODEL_VOTING[] }) {
<Center> <Center>
<Button <Button
loading={ loading={
e.id === voteId ? (loading === true ? true : false) : false e?.id === voteId ? (loading === true ? true : false) : false
} }
radius={"xl"} radius={"xl"}
color="green" color="green"
leftIcon={<IconEyeCheck />} leftIcon={<IconEyeCheck />}
onClick={async () => { onClick={async () => {
setVoteId(e.id); setVoteId(e?.id);
setLoading(true); setLoading(true);
await new Promise((r) => setTimeout(r, 500)); await new Promise((r) => setTimeout(r, 500));
onList(e.id, setHasil, setKontributor, setLoading, open); onList(e?.id, setHasil, setKontributor, setLoading, open);
}} }}
> >
Lihat Hasil Lihat Hasil
@@ -87,7 +87,10 @@ function TableStatus({ listPublish }: { listPublish: MODEL_VOTING[] }) {
</Center> </Center>
</td> </td>
<td> <td>
<Center>{e.title}</Center> <Center>{e?.Author?.Profile?.name}</Center>
</td>
<td>
<Center>{e?.title}</Center>
</td> </td>
<td> <td>
<Center> <Center>
@@ -97,27 +100,27 @@ function TableStatus({ listPublish }: { listPublish: MODEL_VOTING[] }) {
maxHeight={50} maxHeight={50}
showLabel="tampilkan" showLabel="tampilkan"
> >
{e.deskripsi} {e?.deskripsi}
</Spoiler> </Spoiler>
</Center> </Center>
</td> </td>
<th> <th>
<Stack> <Stack>
{e.Voting_DaftarNamaVote.map((v) => ( {e?.Voting_DaftarNamaVote.map((v) => (
<Box key={v.id}> <Box key={v?.id}>
<Text>- {v.value}</Text> <Text>- {v?.value}</Text>
</Box> </Box>
))} ))}
</Stack> </Stack>
</th> </th>
<td> <td>
<Center> <Center>
{e.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })} {e?.awalVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
</Center> </Center>
</td> </td>
<td> <td>
<Center> <Center>
{e.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })} {e?.akhirVote.toLocaleDateString("id-ID", { dateStyle: "long" })}
</Center> </Center>
</td> </td>
</tr> </tr>
@@ -131,7 +134,10 @@ function TableStatus({ listPublish }: { listPublish: MODEL_VOTING[] }) {
size={"xl"} size={"xl"}
withCloseButton={false} withCloseButton={false}
> >
<ComponentAdminVote_DetailHasil hasil={hasil} kontributor={kontributor}/> <ComponentAdminVote_DetailHasil
hasil={hasil}
kontributor={kontributor}
/>
</Modal> </Modal>
<Box> <Box>
<Box bg={"green.1"} p={"xs"}> <Box bg={"green.1"} p={"xs"}>
@@ -152,6 +158,9 @@ function TableStatus({ listPublish }: { listPublish: MODEL_VOTING[] }) {
<th> <th>
<Center>Aksi</Center> <Center>Aksi</Center>
</th> </th>
<th>
<Center>Author</Center>
</th>
<th> <th>
<Center>Judul</Center> <Center>Judul</Center>
</th> </th>

View File

@@ -87,6 +87,9 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
</Spoiler> </Spoiler>
</Center> </Center>
</td> </td>
<td>
<Center>{e?.Author?.Profile?.name}</Center>
</td>
<td> <td>
<Center>{e.title}</Center> <Center>{e.title}</Center>
</td> </td>
@@ -184,7 +187,9 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
<th> <th>
<Center>Catatan</Center> <Center>Catatan</Center>
</th> </th>
<th>
<Center>Author</Center>
</th>
<th> <th>
<Center>Judul</Center> <Center>Judul</Center>
</th> </th>

View File

@@ -36,6 +36,7 @@ import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_glob
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { AdminEvent_funEditCatatanById } from "../../fun/edit/fun_edit_status_reject_by_id"; import { AdminEvent_funEditCatatanById } from "../../fun/edit/fun_edit_status_reject_by_id";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import moment from "moment";
export default function AdminVote_TableReview({ export default function AdminVote_TableReview({
listVote, listVote,
@@ -58,9 +59,14 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
const [data, setData] = useState(listData); const [data, setData] = useState(listData);
const [votingId, setVotingId] = useState(""); const [votingId, setVotingId] = useState("");
const [catatan, setCatatan] = useState(""); const [catatan, setCatatan] = useState("");
const [isLoadingPublish, setLoadingPublish] = useState(false);
const [isSaveLoading, setSaveLoading] = useState(false);
const TableRows = data.map((e, i) => ( const TableRows = data.map((e, i) => (
<tr key={i}> <tr key={i}>
<td>
<Center>{e?.Author?.Profile?.name}</Center>
</td>
<td> <td>
<Center>{e.title}</Center> <Center>{e.title}</Center>
</td> </td>
@@ -99,11 +105,23 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
<td> <td>
<Stack align="center"> <Stack align="center">
<Button <Button
loaderPosition="center"
loading={
e?.id === votingId ? (isLoadingPublish ? true : false) : false
}
w={120} w={120}
color={"green"} color={"green"}
leftIcon={<IconEyeShare />} leftIcon={<IconEyeShare />}
radius={"xl"} radius={"xl"}
onClick={() => onPublish(e.id, setData, e.awalVote)} onClick={() =>
onPublish(
e.id,
setData,
e.awalVote,
setLoadingPublish,
setVotingId
)
}
> >
Publish Publish
</Button> </Button>
@@ -146,12 +164,15 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
}} }}
/> />
<Group position="right"> <Group position="right">
<Button radius={"xl"} onClick={() => close()}>
Batal
</Button>
<Button <Button
loaderPosition="center"
loading={isSaveLoading ? true : false}
radius={"xl"} radius={"xl"}
onClick={() => { onClick={() => {
onReject(votingId, setData, catatan, close); onReject(votingId, setData, catatan, close, setSaveLoading);
// console.log("hehe")
}} }}
> >
Simpan Simpan
@@ -178,6 +199,9 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
> >
<thead> <thead>
<tr> <tr>
<th>
<Center>Author</Center>
</th>
<th> <th>
<Center>Judul</Center> <Center>Judul</Center>
</th> </th>
@@ -217,19 +241,26 @@ function TableStatus({ listData }: { listData: MODEL_VOTING[] }) {
); );
} }
async function onPublish(voteId: string, setData: any, awalVote: Date) { async function onPublish(
voteId: string,
setData: any,
awalVote: Date,
setLoadingPublish: any,
setVotingId: any
) {
const hariIni = new Date(); const hariIni = new Date();
if (awalVote < hariIni) const cekHari = moment(awalVote).diff(hariIni, "days");
return ComponentGlobal_NotifikasiPeringatan(
"Tanggal Mulai Votig Lewat, Edit Kembali",
1500
);
if (cekHari < 0)
return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat");
setVotingId(voteId);
await AdminVote_funEditStatusPublishById(voteId).then(async (res) => { await AdminVote_funEditStatusPublishById(voteId).then(async (res) => {
if (res.status === 200) { if (res.status === 200) {
await AdminVote_getListTableByStatusId("2").then((val) => { await AdminVote_getListTableByStatusId("2").then((val) => {
setData(val); setData(val);
ComponentGlobal_NotifikasiBerhasil(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
setLoadingPublish(true);
}); });
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
@@ -241,7 +272,8 @@ async function onReject(
voteId: string, voteId: string,
setData: any, setData: any,
catatan: string, catatan: string,
close: any close: any,
setSaveLoading: any
) { ) {
const data = { const data = {
id: voteId, id: voteId,
@@ -251,6 +283,7 @@ async function onReject(
if (res.status === 200) { if (res.status === 200) {
await AdminVote_getListTableByStatusId("2").then((val) => { await AdminVote_getListTableByStatusId("2").then((val) => {
setData(val); setData(val);
setSaveLoading(true);
ComponentGlobal_NotifikasiBerhasil(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
close(); close();
}); });

View File

@@ -1,8 +1,22 @@
"use client" "use client";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import { MODEL_VOTE_KONTRIBUTOR, MODEL_VOTING_DAFTAR_NAMA_VOTE } from "@/app_modules/vote/model/interface"; import {
import { Paper, Stack, Center, Title, Grid, Card, Avatar, Badge, Divider, Text } from "@mantine/core"; MODEL_VOTE_KONTRIBUTOR,
MODEL_VOTING_DAFTAR_NAMA_VOTE,
} from "@/app_modules/vote/model/interface";
import {
Paper,
Stack,
Center,
Title,
Grid,
Card,
Avatar,
Badge,
Divider,
Text,
} from "@mantine/core";
import _ from "lodash"; import _ from "lodash";
import router from "next/router"; import router from "next/router";
@@ -11,7 +25,7 @@ export default function ComponentAdminVote_DetailHasil({
kontributor, kontributor,
}: { }: {
hasil?: MODEL_VOTING_DAFTAR_NAMA_VOTE[]; hasil?: MODEL_VOTING_DAFTAR_NAMA_VOTE[];
kontributor?: MODEL_VOTE_KONTRIBUTOR[] kontributor?: MODEL_VOTE_KONTRIBUTOR[];
}) { }) {
return ( return (
<> <>
@@ -58,7 +72,7 @@ export default function ComponentAdminVote_DetailHasil({
span={2} span={2}
onClick={() => onClick={() =>
router.push( router.push(
RouterProfile.katalog + e.Author.Profile.id RouterProfile.katalog + e?.Author?.Profile?.id
) )
} }
> >
@@ -73,7 +87,7 @@ export default function ComponentAdminVote_DetailHasil({
src={ src={
e e
? RouterProfile.api_foto_profile + ? RouterProfile.api_foto_profile +
e.Author.Profile.imagesId e?.Author?.Profile?.imagesId
: "/aset/global/avatar.png" : "/aset/global/avatar.png"
} }
/> />
@@ -81,7 +95,7 @@ export default function ComponentAdminVote_DetailHasil({
<Grid.Col span={5}> <Grid.Col span={5}>
<Stack justify="center" h={"100%"}> <Stack justify="center" h={"100%"}>
<Text truncate fz={"sm"} fw={"bold"}> <Text truncate fz={"sm"} fw={"bold"}>
{e ? e.Author.Profile.name : "Nama author"} {e ? e?.Author?.Profile?.name : "Nama author"}
</Text> </Text>
</Stack> </Stack>
</Grid.Col> </Grid.Col>

View File

@@ -23,7 +23,18 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
akhirVote: true, akhirVote: true,
catatan: true, catatan: true,
authorId: true, authorId: true,
Author: true, Author: {
select: {
id: true,
username: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
voting_StatusId: true, voting_StatusId: true,
Voting_DaftarNamaVote: true, Voting_DaftarNamaVote: true,
}, },
@@ -52,7 +63,18 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
akhirVote: true, akhirVote: true,
catatan: true, catatan: true,
authorId: true, authorId: true,
Author: true, Author: {
select: {
id: true,
username: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
voting_StatusId: true, voting_StatusId: true,
Voting_DaftarNamaVote: true, Voting_DaftarNamaVote: true,
}, },
@@ -63,6 +85,9 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
if (statusId === "2") { if (statusId === "2") {
const getData = await prisma.voting.findMany({ const getData = await prisma.voting.findMany({
orderBy: {
updatedAt: "desc",
},
where: { where: {
voting_StatusId: "2", voting_StatusId: "2",
isActive: true, isActive: true,
@@ -78,7 +103,18 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
akhirVote: true, akhirVote: true,
catatan: true, catatan: true,
authorId: true, authorId: true,
Author: true, Author: {
select: {
id: true,
username: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
voting_StatusId: true, voting_StatusId: true,
Voting_DaftarNamaVote: true, Voting_DaftarNamaVote: true,
}, },
@@ -104,7 +140,18 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
akhirVote: true, akhirVote: true,
catatan: true, catatan: true,
authorId: true, authorId: true,
Author: true, Author: {
select: {
id: true,
username: true,
Profile: {
select: {
id: true,
name: true,
},
},
},
},
voting_StatusId: true, voting_StatusId: true,
Voting_DaftarNamaVote: true, Voting_DaftarNamaVote: true,
}, },
@@ -112,6 +159,4 @@ export async function AdminVote_getListTableByStatusId(statusId: string) {
return getData; return getData;
} }
} }

View File

@@ -75,7 +75,7 @@ export default function ColabViewChat({
down: false, down: false,
}); });
const [topik, setTopic] = useState("") const [topik, setTopic] = useState("");
useShallowEffect(() => { useShallowEffect(() => {
evnPesan.on(topik, (msgg) => { evnPesan.on(topik, (msgg) => {
@@ -86,11 +86,8 @@ export default function ColabViewChat({
}); });
}, [data]); }, [data]);
// Kirim pesan // Kirim pesan
async function onSend() { async function onSend() {
// console.log(JSON.stringify(data[0], null, 2)); // console.log(JSON.stringify(data[0], null, 2));
const kiriman = { const kiriman = {
id: "clw8glvt4000j12efrecoubug", id: "clw8glvt4000j12efrecoubug",
@@ -117,7 +114,7 @@ export default function ColabViewChat({
// setData(newData as any); // setData(newData as any);
// setHasMore({ up: true }); // setHasMore({ up: true });
setMsg(""); setMsg("");
// } else { // } else {
// ComponentGlobal_NotifikasiGagal(res.message); // ComponentGlobal_NotifikasiGagal(res.message);
// } // }

View File

@@ -44,15 +44,19 @@ import useInfiniteScroll, {
} from "react-easy-infinite-scroll-hook"; } from "react-easy-infinite-scroll-hook";
import toast from "react-simple-toasts"; import toast from "react-simple-toasts";
import colab_getOneMessageById from "../../fun/get/room_chat/get_one_message_by_id"; import colab_getOneMessageById from "../../fun/get/room_chat/get_one_message_by_id";
import { MODEL_USER } from "@/app_modules/home/model/interface";
import { evnPesan } from "@/util/evn";
export default function Colab_GroupChatView({ export default function Colab_GroupChatView({
userLoginId, userLoginId,
listMsg, listMsg,
selectRoom, selectRoom,
dataUserLogin,
}: { }: {
userLoginId: string; userLoginId: string;
listMsg: any; listMsg: any;
selectRoom: MODEL_COLLABORATION_ROOM_CHAT; selectRoom: MODEL_COLLABORATION_ROOM_CHAT;
dataUserLogin: MODEL_USER;
}) { }) {
const router = useRouter(); const router = useRouter();
const [loadingBack, setLoadingBack] = useState(false); const [loadingBack, setLoadingBack] = useState(false);
@@ -63,6 +67,7 @@ export default function Colab_GroupChatView({
const [totalPage, setTotalPage] = useState(1); const [totalPage, setTotalPage] = useState(1);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [isGet, setIsGet] = useState(true); const [isGet, setIsGet] = useState(true);
const [newMessageId, setIdMessage] = useState("");
const next = async (direction: ScrollDirection) => { const next = async (direction: ScrollDirection) => {
try { try {
@@ -93,28 +98,32 @@ export default function Colab_GroupChatView({
next, next,
rowCount: data.length, rowCount: data.length,
hasMore: { up: isGet }, hasMore: { up: isGet },
scrollThreshold: 0.1, scrollThreshold: 0.5,
}); });
async function onSend() { async function onSend() {
await colab_funCreateMessageByUserId(msg, selectRoom.id).then( await colab_funCreateMessageByUserId(msg, selectRoom.id).then(
async (res) => { async (res) => {
if (res.status === 200) { if (res.status === 200) {
mqtt_client.publish(selectRoom.id, msg); setIdMessage(res.data?.id as any);
setMsg(""); setMsg("");
const kiriman: MODEL_COLLABORATION_MESSAGE = {
await colab_getOneMessageById({ createdAt: new Date(),
messageId: res.data?.id as any, id: newMessageId,
}).then((res) => { isActive: true,
// setNewMessage(res); message: msg,
// console.log(res); isFile: false,
// const d = JSON.parse(JSON.stringify(res)); updatedAt: new Date(),
// setData([...data, ...[d]]); userId: dataUserLogin.id,
User: {
mqtt_client.on("message", (a, b) => { id: dataUserLogin.id,
setData([...data, ...[res]]); Profile: {
}); id: dataUserLogin.Profile?.id as any,
}); name: dataUserLogin.Profile?.name as any,
},
},
};
mqtt_client.publish(selectRoom.id, JSON.stringify(kiriman));
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
@@ -124,32 +133,38 @@ export default function Colab_GroupChatView({
useShallowEffect(() => { useShallowEffect(() => {
mqtt_client.subscribe(selectRoom.id); mqtt_client.subscribe(selectRoom.id);
// mqtt_client.on("message", (topic: any, message: any) => {
// mqtt_client.on("message", (a, b) => { // onList(message.toString());
// // loadDataNew(b.toString());
// // onList(b);
// onList2(newMessage);
// }); // });
}, []);
async function onList2(dt: any) { mqtt_client.on("message", (topic: any, message: any) => {
console.log(dt); let dd = _.clone(data);
setData([...data, ...[dt]]); const a = [...dd, JSON.parse(message)];
} // console.log(dd.length);
setData(a);
// const loadDataNew = (dt: any) => {
// setData([JSON.parse(dt),...data]);
// };
async function onList(b: any) {
await colab_getMessageByRoomId({
roomId: selectRoom?.id,
page: 1,
}).then((val) => {
const d = JSON.parse(JSON.stringify(val[5]));
setData([...data, ...[d]]);
// setTotalPage(totalPage);
}); });
}, [data]);
async function onList(message: any) {
const kiriman: MODEL_COLLABORATION_MESSAGE = {
createdAt: new Date(),
id: newMessageId,
isActive: true,
message: message,
isFile: false,
updatedAt: new Date(),
userId: dataUserLogin.id,
User: {
id: dataUserLogin.id,
Profile: {
id: dataUserLogin.Profile?.id as any,
name: dataUserLogin.Profile?.name as any,
},
},
};
const dataLama = _.clone(data);
setData([...dataLama, { ...kiriman }]);
} }
return ( return (

View File

@@ -42,6 +42,8 @@ export interface MODEL_COLLABORATION_PARTISIPASI {
export interface MODEL_COLLABORATION_ROOM_CHAT { export interface MODEL_COLLABORATION_ROOM_CHAT {
id: string; id: string;
createdAt: Date;
updatedAt: Date;
name: string; name: string;
isActive: true; isActive: true;
Author: MODEL_USER; Author: MODEL_USER;
@@ -79,5 +81,34 @@ export interface MODEL_COLLABORATION_MESSAGE {
userId: string; userId: string;
message: string; message: string;
isFile: boolean; isFile: boolean;
User: MODEL_USER; User: MODEL_USER_FOR_MESSAGE;
}
interface MODEL_USER_FOR_MESSAGE {
id: string;
username?: string;
nomor?: string;
active?: boolean;
createdAt?: Date;
updatedAt?: Date;
masterUserRoleId?: string;
Profile?: MODEL_PROFILE_FOR_MESSAGE;
}
interface MODEL_PROFILE_FOR_MESSAGE{
userId?: string;
User?: MODEL_USER;
id: string;
name: string;
email?: string;
alamat?: string;
jenisKelamin?: string;
active?: string;
createdAt?: Date;
updatedAt?: Date;
// ImageProfile?: MODEL_IMAGES;
// imagesId?: string;
// ImagesBackground?: MODEL_IMAGES;
// imagesBackgroundId?: string;
} }

View File

@@ -35,6 +35,7 @@ import { RouterHome } from "@/app/lib/router_hipmi/router_home";
import { useForm } from "@mantine/form"; import { useForm } from "@mantine/form";
import { useTimeout } from "@mantine/hooks"; import { useTimeout } from "@mantine/hooks";
import { validRegex } from "../../component/regular_expressions"; import { validRegex } from "../../component/regular_expressions";
import ComponentGlobal_ErrorInput from "@/app_modules/component_global/error_input";
export default function CreateProfile({ userId }: { userId: any }) { export default function CreateProfile({ userId }: { userId: any }) {
const [filePP, setFilePP] = useState<File | null>(null); const [filePP, setFilePP] = useState<File | null>(null);
@@ -203,9 +204,11 @@ export default function CreateProfile({ userId }: { userId: any }) {
maxLength={100} maxLength={100}
placeholder="Contoh: User@gmail.com" placeholder="Contoh: User@gmail.com"
error={ error={
value.email.length > 0 && !value.email.match(validRegex) value.email.length > 0 && !value.email.match(validRegex) ? (
? "Invalid email" <ComponentGlobal_ErrorInput text="Invalid Email" />
: "" ) : (
""
)
} }
onChange={(val) => { onChange={(val) => {
setValue({ setValue({

View File

@@ -23,6 +23,9 @@ export default function ComponentVote_HeaderTamplate({
bg?: any; bg?: any;
}) { }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const [isRightLoading, setRightLoading] = useState(false);
return ( return (
<> <>
<Header <Header
@@ -35,8 +38,10 @@ export default function ComponentVote_HeaderTamplate({
<ActionIcon variant="transparent" disabled></ActionIcon> <ActionIcon variant="transparent" disabled></ActionIcon>
) : ( ) : (
<ActionIcon <ActionIcon
loading={isLoading ? true : false}
variant="transparent" variant="transparent"
onClick={() => { onClick={() => {
setIsLoading(true);
if (route === null || route === undefined) { if (route === null || route === undefined) {
return router.back(); return router.back();
} else { } else {
@@ -54,8 +59,13 @@ export default function ComponentVote_HeaderTamplate({
} else { } else {
return ( return (
<ActionIcon <ActionIcon
loading={isRightLoading ? true : false}
variant="transparent" variant="transparent"
onClick={() => router.push(route2)} onClick={() => {
setRightLoading;
true;
router.push(route2);
}}
> >
{icon} {icon}
</ActionIcon> </ActionIcon>

View File

@@ -5,7 +5,7 @@ import { Center } from "@mantine/core";
export default function ComponentVote_IsEmptyData({ text }: { text: string }) { export default function ComponentVote_IsEmptyData({ text }: { text: string }) {
return ( return (
<> <>
<Center h={"50vh"} fz={"sm"} fw={"bold"}> <Center h={"50vh"} fz={"sm"} fw={"bold"} c={"gray"}>
{text} {text}
</Center> </Center>
</> </>

View File

@@ -0,0 +1,22 @@
import { Center, Grid, Group, Paper, Text, Title } from "@mantine/core";
export default function ComponentVote_NotedBox({
informasi,
}: {
informasi: string;
}) {
return (
<>
<Paper bg={"blue.3"} p={10}>
<Group>
<Text fz={10} fs={"italic"}>
<Text span inherit c={"red"}>
Alasan:{" "}
</Text>
{informasi}
</Text>
</Group>
</Paper>
</>
);
}

View File

@@ -29,9 +29,11 @@ import { data } from "autoprefixer";
import { Vote_funCreate } from "../fun/create/create_vote"; import { Vote_funCreate } from "../fun/create/create_vote";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { MODEL_VOTING } from "../model/interface"; import { MODEL_VOTING } from "../model/interface";
import ComponentGlobal_InputCountDown from "@/app_modules/component_global/input_countdown";
export default function Vote_Create() { export default function Vote_Create() {
const router = useRouter(); const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const [hotMenu, setHotMenu] = useAtom(gs_vote_hotMenu); const [hotMenu, setHotMenu] = useAtom(gs_vote_hotMenu);
const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status); const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status);
@@ -47,11 +49,11 @@ export default function Vote_Create() {
const [listVote, setListVote] = useState([ const [listVote, setListVote] = useState([
{ {
name: "Nama Voting", name: "Nama Pilihan",
value: "", value: "",
}, },
{ {
name: "Nama Voting", name: "Nama Pilihan",
value: "", value: "",
}, },
]); ]);
@@ -64,6 +66,7 @@ export default function Vote_Create() {
label="Judul" label="Judul"
withAsterisk withAsterisk
placeholder="Masukan judul" placeholder="Masukan judul"
maxLength={100}
onChange={(val) => { onChange={(val) => {
setData({ setData({
...data, ...data,
@@ -71,20 +74,27 @@ export default function Vote_Create() {
}); });
}} }}
/> />
<Textarea <Stack spacing={5}>
label="Deskripsi" <Textarea
autosize label="Deskripsi"
minRows={2} autosize
maxRows={5} minRows={2}
withAsterisk maxRows={5}
placeholder="Masukan deskripsi" withAsterisk
onChange={(val) => { maxLength={300}
setData({ placeholder="Masukan deskripsi"
...data, onChange={(val) => {
deskripsi: val.target.value, setData({
}); ...data,
}} deskripsi: val.target.value,
/> });
}}
/>
<ComponentGlobal_InputCountDown
maxInput={300}
lengthInput={data.deskripsi.length}
/>
</Stack>
<DatePickerInput <DatePickerInput
label="Jangka Waktu" label="Jangka Waktu"
@@ -108,7 +118,7 @@ export default function Vote_Create() {
<Stack spacing={0}> <Stack spacing={0}>
<Center> <Center>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} fz={"sm"}>
Daftar Voting Daftar Pilihan
</Text> </Text>
</Center> </Center>
@@ -119,6 +129,7 @@ export default function Vote_Create() {
<TextInput <TextInput
label={e.name} label={e.name}
withAsterisk withAsterisk
maxLength={100}
placeholder="Nama pilihan voting" placeholder="Nama pilihan voting"
onChange={(v) => { onChange={(v) => {
const val = _.clone(listVote); const val = _.clone(listVote);
@@ -131,60 +142,55 @@ export default function Vote_Create() {
</Stack> </Stack>
<Group position="center"> <Group position="center">
{listVote.length >= 4 ? ( <Button
"" disabled={listVote.length >= 4 ? true : false}
) : ( compact
<Button w={100}
compact radius={"xl"}
w={100} leftIcon={<IconPlus size={15} />}
radius={"xl"} variant="outline"
leftIcon={<IconPlus size={15} />} onClick={() => {
variant="outline" setListVote([
onClick={() => { ...listVote,
// if (listVote.length >= 4) { name: "Nama Voting", value: "" },
// return ComponentGlobal_NotifikasiPeringatan( ]);
// "Daftar Voting Maksimal 4" }}
// ); >
setListVote([ <Text fz={8}>Tambah List</Text>
...listVote, </Button>
{ name: "Nama Voting", value: "" },
]);
}}
>
<Text fz={8}>Tambah List</Text>
</Button>
)}
{listVote.length <= 2 ? ( <Button
"" disabled={listVote.length <= 2 ? true : false}
) : ( compact
<Button w={100}
compact radius={"xl"}
w={100} leftIcon={<IconMinus size={15} />}
radius={"xl"} variant="outline"
leftIcon={<IconMinus size={15} />} onClick={() => {
variant="outline" setListVote([...listVote.slice(0, -1)]);
onClick={() => { }}
if (listVote.length <= 2) >
return ComponentGlobal_NotifikasiPeringatan( <Text fz={8}>Kurangi List</Text>
"Daftar Voting Minimal 2" </Button>
);
setListVote([...listVote.slice(0, -1)]);
}}
>
<Text fz={8}>Kurangi List</Text>
</Button>
)}
</Group> </Group>
</Stack> </Stack>
</Stack> </Stack>
<Button <Button
// disabled // disabled
loaderPosition="center"
loading={isLoading ? true : false}
mt={"lg"} mt={"lg"}
radius={"xl"} radius={"xl"}
onClick={() => { onClick={() => {
onSave(router, setHotMenu, setTabsStatus, data as any, listVote); onSave(
router,
setHotMenu,
setTabsStatus,
data as any,
listVote,
setIsLoading
);
}} }}
> >
Simpan Simpan
@@ -199,7 +205,8 @@ async function onSave(
setHotMenu: any, setHotMenu: any,
setTabsStatus: any, setTabsStatus: any,
data: MODEL_VOTING, data: MODEL_VOTING,
listVote: any[] listVote: any[],
setIsLoading: any
) { ) {
if (_.values(data).includes("")) if (_.values(data).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
@@ -213,7 +220,9 @@ async function onSave(
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Tanggal"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Tanggal");
if (_.values(listVote.map((e) => e.value)).includes("")) if (_.values(listVote.map((e) => e.value)).includes(""))
return ComponentGlobal_NotifikasiPeringatan("Isi Semua Nama Voting"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Pilihan Voting");
// console.log("berhasil");
await Vote_funCreate(data, listVote).then((res) => { await Vote_funCreate(data, listVote).then((res) => {
if (res.status === 201) { if (res.status === 201) {
@@ -221,6 +230,7 @@ async function onSave(
setTabsStatus("Review"); setTabsStatus("Review");
router.replace(RouterVote.status); router.replace(RouterVote.status);
ComponentGlobal_NotifikasiBerhasil(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
setIsLoading(true);
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }

View File

@@ -12,6 +12,7 @@ import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id"; import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
import moment from "moment";
export default function Vote_DetailDraft({ export default function Vote_DetailDraft({
dataVote, dataVote,
@@ -41,7 +42,10 @@ function ButtonAction({
async function onUpdate() { async function onUpdate() {
const hariIni = new Date(); const hariIni = new Date();
if (awalVote < hariIni) return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat"); const cekHari = moment(awalVote).diff(hariIni, "days");
if (cekHari < 0)
return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat");
await Vote_funEditStatusByStatusId(voteId, "2").then((res) => { await Vote_funEditStatusByStatusId(voteId, "2").then((res) => {
if (res.status === 200) { if (res.status === 200) {

View File

@@ -19,6 +19,7 @@ import { MODEL_VOTING } from "../../model/interface";
import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id"; import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id"; import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id";
import ComponentVote_NotedBox from "../../component/noted_box";
export default function Vote_DetailReject({ export default function Vote_DetailReject({
dataVote, dataVote,
@@ -28,6 +29,7 @@ export default function Vote_DetailReject({
return ( return (
<> <>
<Stack spacing={"xl"}> <Stack spacing={"xl"}>
<ComponentVote_NotedBox informasi={dataVote?.catatan} />
<ComponentVote_DetailDataSebelumPublish data={dataVote as any} /> <ComponentVote_DetailDataSebelumPublish data={dataVote as any} />
<ButtonAction voteId={dataVote.id} /> <ButtonAction voteId={dataVote.id} />
</Stack> </Stack>

View File

@@ -22,6 +22,7 @@ import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detai
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 { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import { useState } from "react";
export default function Vote_DetailReview({ export default function Vote_DetailReview({
dataVote, dataVote,
@@ -40,6 +41,7 @@ export default function Vote_DetailReview({
function ButtonAction({ voteId }: { voteId: string }) { function ButtonAction({ voteId }: { voteId: string }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status); const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status);
async function onUpdate() { async function onUpdate() {
@@ -48,6 +50,7 @@ function ButtonAction({ voteId }: { voteId: string }) {
setTabsStatus("Draft"); setTabsStatus("Draft");
ComponentGlobal_NotifikasiBerhasil("Berhasil Batalkan Review", 2000); ComponentGlobal_NotifikasiBerhasil("Berhasil Batalkan Review", 2000);
router.back(); router.back();
setIsLoading(true);
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
@@ -56,9 +59,11 @@ function ButtonAction({ voteId }: { voteId: string }) {
return ( return (
<> <>
<Button <Button
loaderPosition="center"
loading={isLoading ? true : false}
radius={"xl"} radius={"xl"}
color="red" color="orange"
onClick={() => { onClick={() => {8
onUpdate(); onUpdate();
}} }}
> >

View File

@@ -2,6 +2,7 @@
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/component_global/notif_global/notifikasi_berhasil";
import { import {
ActionIcon,
Box, Box,
Button, Button,
Center, Center,
@@ -15,7 +16,7 @@ import {
} from "@mantine/core"; } from "@mantine/core";
import { DatePickerInput } from "@mantine/dates"; import { DatePickerInput } from "@mantine/dates";
import { useCounter } from "@mantine/hooks"; import { useCounter } from "@mantine/hooks";
import { IconHome, IconPlus } from "@tabler/icons-react"; import { IconHome, IconMinus, IconPlus, IconTrash } from "@tabler/icons-react";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import moment from "moment"; import moment from "moment";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
@@ -27,9 +28,12 @@ import {
MODEL_VOTING, MODEL_VOTING,
MODEL_VOTING_DAFTAR_NAMA_VOTE, MODEL_VOTING_DAFTAR_NAMA_VOTE,
} from "../model/interface"; } from "../model/interface";
import _ from "lodash"; import _, { slice } from "lodash";
import { Vote_funEditById } from "../fun/edit/fun_edit_by_id"; import { Vote_funEditById } from "../fun/edit/fun_edit_by_id";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/component_global/notif_global/notifikasi_gagal";
import ComponentGlobal_InputCountDown from "@/app_modules/component_global/input_countdown";
import ComponentGlobal_ErrorInput from "@/app_modules/component_global/error_input";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/component_global/notif_global/notifikasi_peringatan";
export default function Vote_Edit({ export default function Vote_Edit({
dataVote, dataVote,
@@ -39,7 +43,7 @@ export default function Vote_Edit({
listDaftarVote: MODEL_VOTING_DAFTAR_NAMA_VOTE[]; listDaftarVote: MODEL_VOTING_DAFTAR_NAMA_VOTE[];
}) { }) {
const [data, setData] = useState(dataVote); const [data, setData] = useState(dataVote);
const [listVoting, setListVoting] = useState(listDaftarVote); const [pilihanNama, setPilihanNama] = useState(listDaftarVote);
return ( return (
<> <>
@@ -47,8 +51,16 @@ export default function Vote_Edit({
<TextInput <TextInput
label="Judul" label="Judul"
withAsterisk withAsterisk
placeholder="Masukan judul" placeholder="Judul"
value={data.title} value={data.title}
maxLength={100}
error={
data.title === "" ? (
<ComponentGlobal_ErrorInput text="Masukan judul" />
) : (
""
)
}
onChange={(val) => { onChange={(val) => {
setData({ setData({
...data, ...data,
@@ -56,21 +68,36 @@ export default function Vote_Edit({
}); });
}} }}
/> />
<Textarea
label="Deskripsi" <Stack spacing={5}>
autosize <Textarea
minRows={2} label="Deskripsi"
maxRows={5} autosize
withAsterisk minRows={2}
placeholder="Masukan deskripsi" maxRows={5}
value={data.deskripsi} withAsterisk
onChange={(val) => { placeholder="Deskripsi"
setData({ value={data.deskripsi}
...data, maxLength={300}
deskripsi: val.target.value, 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
label="Jangka Waktu" label="Jangka Waktu"
@@ -82,45 +109,97 @@ export default function Vote_Edit({
return moment(date).diff(Date.now(), "days") < 0; return moment(date).diff(Date.now(), "days") < 0;
}} }}
value={[data.awalVote, data.akhirVote]} value={[data.awalVote, data.akhirVote]}
onChange={(val: any) => error={
data.awalVote === null || data.akhirVote === null ? (
<ComponentGlobal_ErrorInput text="Invalid Date" />
) : (
""
)
}
onChange={(val: any) => {
setData({ setData({
...data, ...data,
awalVote: val[0], awalVote: val[0],
akhirVote: val[1], akhirVote: val[1],
}) });
} }}
/> />
<Stack spacing={0}> <Stack spacing={0}>
<Center> <Center>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} fz={"sm"}>
Daftar Voting Daftar Pilihan
</Text> </Text>
</Center> </Center>
<Stack> <Stack>
<Stack> <Stack>
{listVoting.map((e, index) => ( {pilihanNama.map((e, index) => (
<Box key={index}> <Grid key={index} h="100%" align="center">
<TextInput <Grid.Col span={10}>
label={"Nama Voting"} <Box>
withAsterisk <TextInput
placeholder="Nama pilihan voting" label={"Nama Pilihan"}
value={e.value} withAsterisk
onChange={(v) => { placeholder="Nama pilihan"
const cloneData = _.clone(listVoting); value={e.value}
cloneData[index].value = v.currentTarget.value; maxLength={100}
error={
setListVoting([...listVoting]); e.value === "" ? (
}} <ComponentGlobal_ErrorInput text="Masukan nama pilihan" />
/> ) : (
</Box> ""
)
}
onChange={(v) => {
const cloneData = _.clone(pilihanNama);
cloneData[index].value = v.currentTarget.value;
setPilihanNama([...pilihanNama]);
}}
/>
</Box>
</Grid.Col>
<Grid.Col span={2} mt={"md"}>
<ActionIcon
variant="transparent"
radius={"xl"}
disabled={pilihanNama.length < 3 ? true : false}
onClick={() => {
pilihanNama.splice(index, 1);
setPilihanNama([...pilihanNama]);
}}
>
<IconTrash
style={{
transition: "0.5s",
}}
color={pilihanNama.length < 3 ? "gray" : "red"}
/>
</ActionIcon>
</Grid.Col>
</Grid>
))} ))}
</Stack> </Stack>
<Group position="center">
<Button
disabled={pilihanNama.length >= 4 ? true : false}
compact
w={100}
radius={"xl"}
leftIcon={<IconPlus size={15} />}
variant="outline"
onClick={() => {
setPilihanNama([...(pilihanNama as any), { value: "" }]);
}}
>
<Text fz={8}>Tambah List</Text>
</Button>
</Group>
</Stack> </Stack>
</Stack> </Stack>
<ButtonAction data={data} listVoting={listVoting} /> <ButtonAction data={data} listVoting={pilihanNama} />
{/* <pre>{JSON.stringify(listDaftarVote, null, 2)}</pre> */} {/* <pre>{JSON.stringify(listDaftarVote, null, 2)}</pre> */}
</Stack> </Stack>
@@ -136,16 +215,20 @@ function ButtonAction({
listVoting: MODEL_VOTING_DAFTAR_NAMA_VOTE[]; listVoting: MODEL_VOTING_DAFTAR_NAMA_VOTE[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const [hotMenu, setHotMenu] = useAtom(gs_vote_hotMenu); const [hotMenu, setHotMenu] = useAtom(gs_vote_hotMenu);
const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status); const [tabsStatus, setTabsStatus] = useAtom(gs_vote_status);
async function onUpdate() { async function onUpdate() {
// console.log(listVoting);
await Vote_funEditById(data, listVoting).then((res) => { await Vote_funEditById(data, listVoting).then((res) => {
if (res.status === 200) { if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil("Berhasil Update"); ComponentGlobal_NotifikasiBerhasil("Berhasil Update");
// setHotMenu(1); // setHotMenu(1);
// setTabsStatus("Draft"); // setTabsStatus("Draft");
router.back(); router.back();
setIsLoading(true);
} else { } else {
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiGagal(res.message);
} }
@@ -154,7 +237,14 @@ function ButtonAction({
return ( return (
<> <>
<Button mt={"lg"} radius={"xl"} color="green" onClick={() => onUpdate()}> <Button
loaderPosition="center"
loading={isLoading ? true : false}
mt={"lg"}
radius={"xl"}
color="green"
onClick={() => onUpdate()}
>
Update Update
</Button> </Button>
</> </>

View File

@@ -6,6 +6,7 @@ import {
MODEL_VOTING_DAFTAR_NAMA_VOTE, MODEL_VOTING_DAFTAR_NAMA_VOTE,
} from "../../model/interface"; } from "../../model/interface";
import { revalidatePath } from "next/cache"; import { revalidatePath } from "next/cache";
import _ from "lodash";
export async function Vote_funEditById( export async function Vote_funEditById(
data: MODEL_VOTING, data: MODEL_VOTING,
@@ -22,22 +23,34 @@ export async function Vote_funEditById(
awalVote: data.awalVote, awalVote: data.awalVote,
akhirVote: data.akhirVote, akhirVote: data.akhirVote,
}, },
select: {
Voting_DaftarNamaVote: {
where: {
isActive: true,
},
},
},
}); });
if (!updtVoting) return { status: 400, message: "Gagal Update" }; if (!updtVoting) return { status: 400, message: "Gagal Update" };
for (let e of listVoting) { const delPilihan = await prisma.voting_DaftarNamaVote.deleteMany({
const updtListVoting = await prisma.voting_DaftarNamaVote.updateMany({ where: {
where: { votingId: data.id,
id: e.id, },
}, });
if (!delPilihan) return { status: 400, message: "Gagal Update Pilihan" };
for (let v of listVoting) {
const val = v.value;
const namaPilihan = await prisma.voting_DaftarNamaVote.create({
data: { data: {
value: e.value, value: val,
votingId: data.id,
}, },
}); });
if (!updtListVoting) if (!namaPilihan) return { status: 400, message: "Gagal Membuat List" };
return { status: 400, message: "Gagal Update Daftar Vote" };
} }
revalidatePath("/dev/vote/detail/draft"); revalidatePath("/dev/vote/detail/draft");

View File

@@ -6,6 +6,7 @@ export async function Vote_getListDaftarNamaById(voteId: string) {
const data = await prisma.voting_DaftarNamaVote.findMany({ const data = await prisma.voting_DaftarNamaVote.findMany({
where: { where: {
votingId: voteId, votingId: voteId,
isActive: true,
}, },
}); });

View File

@@ -21,15 +21,17 @@ export async function Vote_getOnebyId(voteId: string) {
voting_StatusId: true, voting_StatusId: true,
Voting_DaftarNamaVote: { Voting_DaftarNamaVote: {
orderBy: { orderBy: {
createdAt: "asc" createdAt: "asc",
} },
where: {
isActive: true,
},
}, },
Author: { Author: {
select: { select: {
Profile: true Profile: true,
} },
} },
}, },
}); });

View File

@@ -19,7 +19,7 @@ import {
Title, Title,
rem, rem,
} from "@mantine/core"; } from "@mantine/core";
import { IconCirclePlus } from "@tabler/icons-react"; import { IconCirclePlus, IconPencilPlus } from "@tabler/icons-react";
import moment from "moment"; import moment from "moment";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import ComponentVote_CardViewPublish from "../component/card_view_publish"; import ComponentVote_CardViewPublish from "../component/card_view_publish";
@@ -27,6 +27,8 @@ import { MODEL_VOTING } from "../model/interface";
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header"; import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/component_global/author_name_on_header";
import _ from "lodash"; import _ from "lodash";
import ComponentVote_IsEmptyData from "../component/is_empty_data"; import ComponentVote_IsEmptyData from "../component/is_empty_data";
import { useState } from "react";
import { useWindowScroll } from "@mantine/hooks";
export default function Vote_Beranda({ export default function Vote_Beranda({
dataVote, dataVote,
@@ -34,25 +36,33 @@ export default function Vote_Beranda({
dataVote: MODEL_VOTING[]; dataVote: MODEL_VOTING[];
}) { }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setIsLoading] = useState(false);
const [scroll, scrollTo] = useWindowScroll();
return ( return (
<> <>
<Affix position={{ bottom: rem(150), right: rem(30) }}> <Affix position={{ bottom: rem(150), right: rem(30) }}>
<ActionIcon <ActionIcon
loading={isLoading ? true : false}
opacity={scroll.y > 0 ? 0.5 : ""}
style={{
transition: "0.5s",
}}
size={"xl"} size={"xl"}
radius={"xl"} radius={"xl"}
variant="transparent" variant="transparent"
bg={"blue"} bg={"blue"}
onClick={() => { onClick={() => {
setIsLoading(true);
router.push(RouterVote.create); router.push(RouterVote.create);
}} }}
> >
<IconCirclePlus color="white" size={40} /> <IconPencilPlus color="white" />
</ActionIcon> </ActionIcon>
</Affix> </Affix>
{_.isEmpty(dataVote) ? ( {_.isEmpty(dataVote) ? (
<ComponentVote_IsEmptyData text="Tidak ada data"/> <ComponentVote_IsEmptyData text="Tidak ada data" />
) : ( ) : (
<Stack> <Stack>
{dataVote.map((e, i) => ( {dataVote.map((e, i) => (

View File

@@ -10,16 +10,16 @@ export default function MqttLoader() {
useEffect(() => { useEffect(() => {
mqtt_client.on("connect", () => { mqtt_client.on("connect", () => {
console.log("connected"); console.log("connected");
mqtt_client.subscribe("pesan"); // mqtt_client.subscribe("pesan");
// fetch("").then((res) => { // fetch("").then((res) => {
// mqtt_client.subscribe("pesan"); // mqtt_client.subscribe("pesan");
// }); // });
}); });
mqtt_client.on("message", (apa: any, itu: any) => { // mqtt_client.on("message", (apa: any, itu: any) => {
console.log(itu) // console.log(itu)
evnPesan.emit("pesan", itu); // evnPesan.emit("pesan", itu);
}); // });
}, []); }, []);
return null; return null;
} }

View File

@@ -53,14 +53,23 @@ const _ = require("lodash");
// randomNumberPerSecond() // randomNumberPerSecond()
function CobaTanggal() { // function CobaTanggal() {
const tgl = "2024-01-25T12:00:24.008Z"; // const tgl = "2024-01-25T12:00:24.008Z";
const i = _.random(0, 100); // const i = _.random(0, 100);
// setInterval(() => console.log("hello" + i), 1000); // // setInterval(() => console.log("hello" + i), 1000);
const waktu = Date.now() // const waktu = Date.now()
const dt = moment(waktu).locale("fr").format() // const dt = moment(waktu).locale("fr").format()
console.log(dt) // console.log(dt)
// }
// CobaTanggal();
function CobaSplice() {
let array = [1, 2, 3, 4, 5];
let indexToRemove = 1;
array.splice(indexToRemove, 1);
console.log(array);
} }
CobaTanggal(); CobaSplice();