Deskripsi:
- Realtime notifikasi
## No Issue
This commit is contained in:
2024-07-24 10:14:07 +08:00
parent 73c6d58eef
commit 6553f6163f
25 changed files with 510 additions and 289 deletions

View File

@@ -27,6 +27,8 @@ import { Vote_funCreate } from "../fun/create/create_vote";
import { gs_vote_hotMenu, gs_vote_status } from "../global_state";
import { MODEL_VOTING } from "../model/interface";
import { MainColor } from "@/app_modules/_global/color/color_pallet";
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
import mqtt_client from "@/util/mqtt_client";
export default function Vote_Create() {
const router = useRouter();
@@ -254,15 +256,36 @@ async function onSave(
// console.log("berhasil");
await Vote_funCreate(data, listVote).then((res) => {
if (res.status === 201) {
const res = await Vote_funCreate(data, listVote);
if (res.status === 201) {
const dataNotif: any = {
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: "Voting baru",
};
const notif = await notifikasiToAdmin_funCreate({
data: dataNotif as any,
});
if (notif.status === 201) {
mqtt_client.publish(
"ADMIN",
JSON.stringify({
count: 1,
})
);
setHotMenu(2);
setTabsStatus("Review");
router.replace(RouterVote.status);
ComponentGlobal_NotifikasiBerhasil(res.message);
setIsLoading(true);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
}

View File

@@ -1,25 +1,23 @@
"use client";
import { Button, Group, Modal, SimpleGrid, Stack, Title } from "@mantine/core";
import ComponentVote_DetailDataSebelumPublish from "../../component/detail/detail_data_sebelum_publish";
import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { gs_vote_status } from "../../global_state";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { useDisclosure } from "@mantine/hooks";
import { MODEL_VOTING } from "../../model/interface";
import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_id";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { Vote_funDeleteById } from "../../fun/delete/fun_delete_by_id";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import moment from "moment";
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { useState } from "react";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import { 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 { Button, SimpleGrid, Stack } from "@mantine/core";
import { useAtom } from "jotai";
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 { gs_vote_status } from "../../global_state";
import { MODEL_VOTING } from "../../model/interface";
import mqtt_client from "@/util/mqtt_client";
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
export default function Vote_DetailDraft({
dataVote,
@@ -64,16 +62,36 @@ function ButtonAction({
if (cekHari < 0)
return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat");
await Vote_funEditStatusByStatusId(voteId, "2").then((res) => {
if (res.status === 200) {
const res = await Vote_funEditStatusByStatusId(voteId, "2");
if (res.status === 200) {
const dataNotif: any = {
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: dataNotif as any,
});
if (notif.status === 201) {
mqtt_client.publish(
"ADMIN",
JSON.stringify({
count: 1,
})
);
setTabsStatus("Review");
ComponentGlobal_NotifikasiBerhasil("Berhasil Ajukan Review", 2000);
setIsLoading(true);
router.back();
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
}
async function onDelete() {

View File

@@ -1,18 +1,19 @@
"use client";
import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog";
import ComponentGlobal_AuthorNameOnHeader from "@/app_modules/_global/author_name_on_header";
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import notifikasiToUser_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_user";
import {
Avatar,
Badge,
Box,
Button,
Card,
Center,
Divider,
Grid,
Group,
Radio,
Stack,
@@ -25,12 +26,8 @@ import ComponentVote_DaftarKontributorVoter from "../../component/detail/detail_
import ComponentVote_HasilVoting from "../../component/detail/detail_hasil_voting";
import { Vote_funCreateHasil } from "../../fun/create/create_hasil";
import { Vote_getOnebyId } from "../../fun/get/get_one_by_id";
import {
MODEL_VOTE_KONTRIBUTOR,
MODEL_VOTING,
MODEL_VOTING_DAFTAR_NAMA_VOTE,
} from "../../model/interface";
import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet";
import { MODEL_VOTING } from "../../model/interface";
import mqtt_client from "@/util/mqtt_client";
export default function Vote_MainDetail({
dataVote,
@@ -38,12 +35,14 @@ export default function Vote_MainDetail({
isKontributor,
pilihanKontributor,
listKontributor,
userLoginId,
}: {
dataVote: MODEL_VOTING;
hasilVoting: any;
isKontributor: boolean;
pilihanKontributor: string;
listKontributor: any[];
userLoginId: string;
}) {
const [data, setData] = useState(dataVote);
return (
@@ -54,6 +53,7 @@ export default function Vote_MainDetail({
setData={setData}
isKontributor={isKontributor}
pilihanKontributor={pilihanKontributor}
userLoginId={userLoginId}
/>
<ComponentVote_HasilVoting data={data.Voting_DaftarNamaVote} />
<ComponentVote_DaftarKontributorVoter
@@ -69,11 +69,13 @@ function TampilanDataVoting({
setData,
isKontributor,
pilihanKontributor,
userLoginId,
}: {
dataVote?: MODEL_VOTING;
setData: any;
isKontributor: boolean;
pilihanKontributor: any;
userLoginId: string;
}) {
const [votingNameId, setVotingNameId] = useState("");
return (
@@ -182,7 +184,7 @@ function TampilanDataVoting({
{dataVote?.Voting_DaftarNamaVote.map((v) => (
<Box key={v.id}>
<Radio
color="yellow"
color="yellow"
styles={{ label: { color: "white" } }}
label={v.value}
value={v.id}
@@ -200,7 +202,12 @@ function TampilanDataVoting({
<Button
radius={"xl"}
onClick={() =>
onVote(votingNameId, dataVote?.id as any, setData)
onVote(
votingNameId,
dataVote?.id as any,
setData,
userLoginId
)
}
bg={MainColor.yellow}
color="yellow"
@@ -218,141 +225,46 @@ function TampilanDataVoting({
);
}
async function onVote(pilihanVotingId: string, voteId: string, setData: any) {
await Vote_funCreateHasil(pilihanVotingId, voteId).then(async (res) => {
if (res.status === 201) {
await Vote_getOnebyId(voteId).then((val) => {
setData(val);
ComponentGlobal_NotifikasiBerhasil(res.message);
async function onVote(
pilihanVotingId: string,
voteId: string,
setData: any,
userLoginId: string
) {
const res = await Vote_funCreateHasil(pilihanVotingId, voteId);
if (res.status === 201) {
await Vote_getOnebyId(voteId).then((val) => {
setData(val);
ComponentGlobal_NotifikasiBerhasil(res.message);
});
if (userLoginId !== res?.data?.Voting?.authorId) {
const dataNotif = {
appId: res?.data?.Voting?.id,
userId: res?.data?.Voting?.authorId,
pesan: res?.pilihan,
status: "Voting Masuk",
kategoriApp: "VOTING",
title: "User lain telah melakukan voting !",
};
const createNotifikasi = await notifikasiToUser_funCreate({
data: dataNotif as any,
});
} else {
ComponentGlobal_NotifikasiPeringatan(res.message);
if (createNotifikasi.status === 201) {
mqtt_client.publish(
"USER",
JSON.stringify({
userId: dataNotif.userId,
count: 1,
})
);
}
}
});
}
function TampilanHasil({
data,
hasil,
}: {
data: MODEL_VOTING_DAFTAR_NAMA_VOTE[];
hasil: any;
}) {
return (
<>
<Card shadow="lg" withBorder p={30}>
<Card.Section>
<Stack>
<Center>
<Title order={5}>Hasil Voting</Title>
</Center>
{/* <pre>{JSON.stringify(data, null,2)}</pre> */}
<Grid justify="center">
{data.map((e) => (
<Grid.Col key={e.id} span={data.length >= 4 ? 6 : 4}>
<Stack align="center">
<Avatar
radius={100}
size={70}
variant="outline"
color="blue"
>
<Text>
{e.jumlah}
{/* {hasil.filter((i: any) => i.idDaftarNama == "clsijw6ur0002x5loqsq6g4id")} */}
</Text>
</Avatar>
<Text>{e.value}</Text>
</Stack>
</Grid.Col>
))}
</Grid>
</Stack>
</Card.Section>
</Card>
</>
);
}
function TampilanListKontributor({
lisKontributor,
}: {
lisKontributor: MODEL_VOTE_KONTRIBUTOR[];
}) {
return (
<>
<Card shadow="lg" withBorder p={30}>
<Card.Section>
<Stack>
<Center>
<Title order={5}>Daftar Voting</Title>
</Center>
{lisKontributor.map((e, i) => (
<Stack spacing={"xs"} key={i}>
<Grid>
<Grid.Col span={2}>
<Avatar
size={30}
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
radius={"xl"}
bg={"gray.1"}
src={
e
? RouterProfile.api_foto_profile +
e.Author.Profile.imagesId
: "/aset/global/avatar.png"
}
/>
</Grid.Col>
<Grid.Col span={6}>
<Stack justify="center" h={"100%"}>
<Text truncate fz={"sm"} fw={"bold"}>
{e ? e.Author.Profile.name : "Nama author"}
</Text>
</Stack>
</Grid.Col>
<Grid.Col span={4}>
<Badge w={100}>
<Text truncate>{e.Voting_DaftarNamaVote.value}</Text>
</Badge>
</Grid.Col>
</Grid>
<Divider />
</Stack>
))}
{/* {lisKontributor.map((e) => (
<Stack key={e.id}>
<Group position="apart">
<Group>
<Avatar
size={30}
sx={{ borderStyle: "solid", borderWidth: "0.5px" }}
radius={"xl"}
bg={"gray.1"}
src={
e
? RouterProfile.api_foto_profile +
e.Author.Profile.imagesId
: "/aset/global/avatar.png"
}
/>
<Text truncate fz={"sm"} fw={"bold"}>
{e ? e.Author.Profile.name : "Nama author"}
</Text>
</Group>
<Badge>
<Text truncate>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Harum minus libero, ullam ipsum quasi labore iure doloremque sunt et mollitia dolorem laborum quisquam, dolores quis deserunt id. Ipsa, minus temporibus.</Text>
</Badge>
</Group>
<Divider />
</Stack>
))} */}
</Stack>
</Card.Section>
</Card>
{/* <pre>{JSON.stringify(lisKontributor, null, 2)}</pre> */}
</>
);
} else {
ComponentGlobal_NotifikasiPeringatan(res.message);
}
}

View File

@@ -11,6 +11,8 @@ import { Vote_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_
import { gs_vote_status } from "../../global_state";
import { MODEL_VOTING } from "../../model/interface";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import mqtt_client from "@/util/mqtt_client";
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
export default function Vote_DetailReview({
dataVote,
@@ -34,16 +36,36 @@ function ButtonAction({ voteId }: { voteId: string }) {
const [openModal, setOpenModal] = useState(false);
async function onUpdate() {
await Vote_funEditStatusByStatusId(voteId, "3").then((res) => {
if (res.status === 200) {
const res = await Vote_funEditStatusByStatusId(voteId, "3");
if (res.status === 200) {
const dataNotif: any = {
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: "Membatalkan review",
};
const notif = await notifikasiToAdmin_funCreate({
data: dataNotif as any,
});
if (notif.status === 201) {
mqtt_client.publish(
"ADMIN",
JSON.stringify({
count: 1,
})
);
setTabsStatus("Draft");
ComponentGlobal_NotifikasiBerhasil("Berhasil Batalkan Review", 2000);
router.back();
setIsLoading(true);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
}
return (
<>

View File

@@ -16,6 +16,7 @@ export async function Vote_funCreateHasil(
},
select: {
jumlah: true,
value: true,
},
});
@@ -31,16 +32,30 @@ export async function Vote_funCreateHasil(
});
if (!updt) return { status: 400, message: "Gagal Update" };
const create = await prisma.voting_Kontributor.create({
const createKontributor = await prisma.voting_Kontributor.create({
data: {
voting_DaftarNamaVoteId: pilihanVotingId,
votingId: votingId,
authorId: authorId,
},
select: {
Voting: {
select: {
id: true,
title: true,
authorId: true,
},
},
},
});
if (!create) return { status: 400, message: "Gagal Menjadi Kontributor" };
if (!createKontributor)
return { status: 400, message: "Gagal Menjadi Kontributor" };
revalidatePath("/dev/vote/detail/main/");
return { status: 201, message: "Berhasil Voting" };
return {
data: createKontributor,
pilihan: get.value,
status: 201,
message: "Berhasil Voting",
};
}

View File

@@ -16,6 +16,16 @@ export async function Vote_funCreate(req: MODEL_VOTING, listVote: any[]) {
akhirVote: req.akhirVote,
authorId: authorId,
},
select: {
id: true,
title: true,
Voting_Status: {
select: {
name: true,
},
},
authorId: true,
},
});
if (!create) return { status: 400, message: "Gagal Membuat Vote" };
@@ -35,6 +45,7 @@ export async function Vote_funCreate(req: MODEL_VOTING, listVote: any[]) {
revalidatePath("/dev/vote/main/status");
return {
data: create,
status: 201,
message: "Berhasil Membuat Vote",
};

View File

@@ -2,6 +2,7 @@
import prisma from "@/app/lib/prisma";
import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token";
import { data } from "autoprefixer";
import { revalidatePath } from "next/cache";
export async function Vote_funEditStatusByStatusId(
@@ -15,11 +16,22 @@ export async function Vote_funEditStatusByStatusId(
data: {
voting_StatusId: statusId,
},
select: {
id: true,
title: true,
authorId: true,
Voting_Status: {
select: {
name: true,
},
},
},
});
if (!updt) return { status: 400, message: "Gagal Update" };
revalidatePath("/dev/vote/main/status");
return {
data: updt,
status: 200,
message: "Update Berhasil",
};