diff --git a/package.json b/package.json index c1cd1e9b..772a7593 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "hipmi", "version": "0.1.0", "private": true, + "prisma": { + "seed": "npx tsx ./prisma/seed.ts" + }, "scripts": { "dev": "next dev", "build": "next build", diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 00000000..f8b9a701 --- /dev/null +++ b/prisma/seed.ts @@ -0,0 +1,8 @@ +import prisma from "@/app/lib/prisma"; + +(async () => { + console.log("start"); +})().finally(() => { + console.log("success"); + prisma.$disconnect(); +}); diff --git a/src/app/dev/vote/detail/main/[id]/page.tsx b/src/app/dev/vote/detail/main/[id]/page.tsx index cbdfffe3..c85e4ab3 100644 --- a/src/app/dev/vote/detail/main/[id]/page.tsx +++ b/src/app/dev/vote/detail/main/[id]/page.tsx @@ -1,3 +1,4 @@ +import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; import { Vote_MainDetail } from "@/app_modules/vote"; import { Vote_cekKontributorById } from "@/app_modules/vote/fun/get/cek_kontributor_by_id"; import { Vote_getHasilVoteById } from "@/app_modules/vote/fun/get/get_list_hasil_by_id"; @@ -12,7 +13,7 @@ export default async function Page({ params }: { params: { id: string } }) { const isKontributor = await Vote_cekKontributorById(voteId); const pilihanKontributor = await Vote_getOnePilihanVotingByUserId(voteId); const listKontributor = await Vote_getListKontributorById(voteId); - + const userLoginId = await user_getOneUserId(); return ( <> @@ -22,6 +23,7 @@ export default async function Page({ params }: { params: { id: string } }) { isKontributor={isKontributor} pilihanKontributor={pilihanKontributor as any} listKontributor={listKontributor as any} + userLoginId={userLoginId} /> ); diff --git a/src/app_modules/_global/api/generate_api.ts b/src/app_modules/_global/api/generate_api.ts new file mode 100644 index 00000000..c20ddb96 --- /dev/null +++ b/src/app_modules/_global/api/generate_api.ts @@ -0,0 +1,3 @@ +export function generate_api({dev}: {dev: string}) { + +} \ No newline at end of file diff --git a/src/app_modules/admin/layout.tsx b/src/app_modules/admin/layout.tsx index 429adf0c..8f5e261b 100644 --- a/src/app_modules/admin/layout.tsx +++ b/src/app_modules/admin/layout.tsx @@ -51,6 +51,7 @@ import adminNotifikasi_getByUserId from "./notifikasi/fun/get/get_notifikasi_by_ import adminNotifikasi_funUpdateIsReadById from "./notifikasi/fun/update/fun_update_is_read_by_id"; import adminNotifikasi_findRouterJob from "./notifikasi/route_setting/job"; import adminNotifikasi_findRouterForum from "./notifikasi/route_setting/forum"; +import { adminNotifikasi_findRouterVoting } from "./notifikasi/route_setting/voting"; export default function AdminLayout({ children, @@ -297,6 +298,7 @@ export default function AdminLayout({ > {children} + {/* Drawer Mobile View */} setOpened(false)} size={"50%"}> @@ -389,6 +391,7 @@ function DrawerNotifikasi({ }, }} onClick={async () => { + // JOB e?.kategoriApp === "JOB" && adminNotifikasi_findRouterJob({ data: e, @@ -399,6 +402,7 @@ function DrawerNotifikasi({ onToggleNavbar: onToggleNavbar, }); + // FORUM e?.kategoriApp === "FORUM" && adminNotifikasi_findRouterForum({ data: e, @@ -411,6 +415,19 @@ function DrawerNotifikasi({ }, }); + // VOTE + e?.kategoriApp === "VOTING" && + adminNotifikasi_findRouterVoting({ + data: e, + router: router, + onChangeNavbar(val) { + onChangeNavbar(val); + }, + onToggleNavbar(val) { + onToggleNavbar(val); + }, + }); + const updateIsRead = await adminNotifikasi_funUpdateIsReadById({ notifId: e?.id, }); diff --git a/src/app_modules/admin/main_dashboard/main/view.tsx b/src/app_modules/admin/main_dashboard/main/view.tsx index d47cb52d..e4d27390 100644 --- a/src/app_modules/admin/main_dashboard/main/view.tsx +++ b/src/app_modules/admin/main_dashboard/main/view.tsx @@ -1,22 +1,14 @@ "use client"; import { - ActionIcon, - Box, - Center, Divider, Grid, Group, Paper, Stack, Text, - Title, + Title } from "@mantine/core"; -import Admin_Investasi from "../../investasi/main/view"; -import { IconChevronsRight } from "@tabler/icons-react"; -import router from "next/router"; -import * as echarts from 'echarts'; -import EChartsReact from "echarts-for-react"; export default function AdminMain({countUser, countPorto}: {countUser: number, countPorto: number} ) { diff --git a/src/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id.ts b/src/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id.ts index 5f2bfc74..d60b0047 100644 --- a/src/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id.ts +++ b/src/app_modules/admin/notifikasi/fun/get/get_notifikasi_by_user_id.ts @@ -8,10 +8,14 @@ export default async function adminNotifikasi_getByUserId() { const adminId = await user_getOneUserId(); const data = await prisma.notifikasi.findMany({ - - orderBy: { - createdAt: "desc", - }, + orderBy: [ + { + isRead: "asc", + }, + { + createdAt: "desc", + }, + ], where: { adminId: adminId, userRoleId: "2", diff --git a/src/app_modules/admin/notifikasi/route_setting/voting.ts b/src/app_modules/admin/notifikasi/route_setting/voting.ts new file mode 100644 index 00000000..5e8bcc07 --- /dev/null +++ b/src/app_modules/admin/notifikasi/route_setting/voting.ts @@ -0,0 +1,27 @@ +import { RouterAdminVote } from "@/app/lib/router_admin/router_admin_vote"; +import { MODEL_NOTIFIKASI } from "@/app_modules/notifikasi/model/interface"; +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; + +export async function adminNotifikasi_findRouterVoting({ + data, + router, + onChangeNavbar, + onToggleNavbar, +}: { + data: MODEL_NOTIFIKASI; + router: AppRouterInstance; + onChangeNavbar: (val: any) => void; + onToggleNavbar: (val: any) => void; +}) { + const path = RouterAdminVote.table_review; + + if (data.status === "Review") { + router.push(path, { scroll: false }); + onChangeNavbar({ + id: 5, + childId: 53, + }); + } + + onToggleNavbar(true); +} diff --git a/src/app_modules/admin/vote/child/table_review/index.tsx b/src/app_modules/admin/vote/child/table_review/index.tsx index db8463bf..f14023a2 100644 --- a/src/app_modules/admin/vote/child/table_review/index.tsx +++ b/src/app_modules/admin/vote/child/table_review/index.tsx @@ -1,19 +1,13 @@ "use client"; -import { RouterProfile } from "@/app/lib/router_hipmi/router_katalog"; import ComponentAdminGlobal_HeaderTamplate from "@/app_modules/admin/component_global/header_tamplate"; -import { AdminEvent_getListPesertaById } from "@/app_modules/admin/event/fun/get/get_list_peserta_by_id"; import { MODEL_VOTING } from "@/app_modules/vote/model/interface"; import { - Avatar, Box, Button, Center, - Divider, - Grid, Group, Modal, - Paper, ScrollArea, Spoiler, Stack, @@ -23,20 +17,20 @@ import { Title, } from "@mantine/core"; import { useDisclosure } from "@mantine/hooks"; -import { IconBan } from "@tabler/icons-react"; -import { IconEyeShare } from "@tabler/icons-react"; +import { IconBan, IconEyeShare } from "@tabler/icons-react"; import _ from "lodash"; import { useRouter } from "next/navigation"; -import { useState } from "react"; -import { AdminVote_funEditStatusPublishById } from "../../fun/edit/fun_edit_status_publish_by_id"; -import toast from "react-simple-toasts"; -import { AdminVote_getListTableByStatusId } from "../../fun/get/get_list_table_by_status_id"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; -import { AdminEvent_funEditCatatanById } from "../../fun/edit/fun_edit_status_reject_by_id"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import moment from "moment"; +import { useState } from "react"; +import { AdminVote_funEditStatusPublishById } from "../../fun/edit/fun_edit_status_publish_by_id"; +import { AdminEvent_funEditCatatanById } from "../../fun/edit/fun_edit_status_reject_by_id"; +import { AdminVote_getListTableByStatusId } from "../../fun/get/get_list_table_by_status_id"; +import mqtt_client from "@/util/mqtt_client"; +import adminNotifikasi_funCreateToUser from "@/app_modules/admin/notifikasi/fun/create/fun_create_notif_user"; export default function AdminVote_TableReview({ listVote, @@ -255,17 +249,36 @@ async function onPublish( return ComponentGlobal_NotifikasiPeringatan("Tanggal Voting Lewat"); setVotingId(voteId); - await AdminVote_funEditStatusPublishById(voteId).then(async (res) => { - if (res.status === 200) { - await AdminVote_getListTableByStatusId("2").then((val) => { - setData(val); - ComponentGlobal_NotifikasiBerhasil(res.message); - setLoadingPublish(true); - }); - } else { - ComponentGlobal_NotifikasiGagal(res.message); + const res = await AdminVote_funEditStatusPublishById(voteId); + if (res.status === 200) { + const dataNotif = { + appId: res.data?.id, + status: res.data?.Voting_Status?.name as any, + userId: res.data?.authorId as any, + pesan: res.data?.title as any, + kategoriApp: "VOTING", + title: "Voting publish", + }; + + const notif = await adminNotifikasi_funCreateToUser({ + data: dataNotif as any, + }); + + if (notif.status === 201) { + mqtt_client.publish( + "USER", + JSON.stringify({ userId: res?.data?.authorId, count: 1 }) + ); } - }); + + await AdminVote_getListTableByStatusId("2").then((val) => { + setData(val); + ComponentGlobal_NotifikasiBerhasil(res.message); + setLoadingPublish(true); + }); + } else { + ComponentGlobal_NotifikasiGagal(res.message); + } } async function onReject( @@ -279,16 +292,36 @@ async function onReject( id: voteId, catatan: catatan, }; - await AdminEvent_funEditCatatanById(data as any).then(async (res) => { - if (res.status === 200) { - await AdminVote_getListTableByStatusId("2").then((val) => { - setData(val); - setSaveLoading(true); - ComponentGlobal_NotifikasiBerhasil(res.message); - close(); - }); - } else { - ComponentGlobal_NotifikasiGagal(res.message); + + const res = await AdminEvent_funEditCatatanById(data as any); + if (res.status === 200) { + const dataNotif = { + appId: res.data?.id, + status: res.data?.Voting_Status?.name as any, + userId: res.data?.authorId as any, + pesan: res.data?.title as any, + kategoriApp: "VOTING", + title: "Voting anda di tolak !", + }; + + const notif = await adminNotifikasi_funCreateToUser({ + data: dataNotif as any, + }); + + if (notif.status === 201) { + mqtt_client.publish( + "USER", + JSON.stringify({ userId: res?.data?.authorId, count: 1 }) + ); } - }); + + await AdminVote_getListTableByStatusId("2").then((val) => { + setData(val); + setSaveLoading(true); + ComponentGlobal_NotifikasiBerhasil(res.message); + close(); + }); + } else { + ComponentGlobal_NotifikasiGagal(res.message); + } } diff --git a/src/app_modules/admin/vote/fun/edit/fun_edit_status_publish_by_id.ts b/src/app_modules/admin/vote/fun/edit/fun_edit_status_publish_by_id.ts index 1614b610..59c61a14 100644 --- a/src/app_modules/admin/vote/fun/edit/fun_edit_status_publish_by_id.ts +++ b/src/app_modules/admin/vote/fun/edit/fun_edit_status_publish_by_id.ts @@ -4,20 +4,31 @@ import prisma from "@/app/lib/prisma"; import { revalidatePath } from "next/cache"; export async function AdminVote_funEditStatusPublishById(voteId: string) { - - const updt = await prisma.voting.update({ - where: { - id: voteId, + const updt = await prisma.voting.update({ + where: { + id: voteId, + }, + data: { + voting_StatusId: "1", + }, + select: { + id: true, + title: true, + authorId: true, + Voting_Status: { + select: { + name: true, + }, }, - data: { - voting_StatusId: "1", - }, - }); + }, + }); - if (!updt) return { status: 400, message: "Update Gagal" }; - revalidatePath("/dev/admin/vote/main"); - return { - status: 200, - message: "Berhasil Update Status", - }; + if (!updt) return { status: 400, message: "Update Gagal" }; + revalidatePath("/dev/admin/vote/main"); + + return { + data: updt, + status: 200, + message: "Berhasil Update Status", + }; } diff --git a/src/app_modules/admin/vote/fun/edit/fun_edit_status_reject_by_id.ts b/src/app_modules/admin/vote/fun/edit/fun_edit_status_reject_by_id.ts index 5cb8cd46..66800203 100644 --- a/src/app_modules/admin/vote/fun/edit/fun_edit_status_reject_by_id.ts +++ b/src/app_modules/admin/vote/fun/edit/fun_edit_status_reject_by_id.ts @@ -15,11 +15,22 @@ export async function AdminEvent_funEditCatatanById( voting_StatusId: "4", catatan: data.catatan, }, + select: { + id: true, + title: true, + authorId: true, + Voting_Status: { + select: { + name: true, + }, + }, + } }); if (!updt) return { status: 400, message: "Update Gagal" }; revalidatePath("/dev/admin/event/main"); return { + data: updt, status: 200, message: "Berhasil Update Status", }; diff --git a/src/app_modules/colab/create/index.tsx b/src/app_modules/colab/create/index.tsx index 2628621b..58597789 100644 --- a/src/app_modules/colab/create/index.tsx +++ b/src/app_modules/colab/create/index.tsx @@ -23,6 +23,7 @@ import _ from "lodash"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import { MainColor } from "@/app_modules/_global/color/color_pallet"; import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; +import mqtt_client from "@/util/mqtt_client"; export default function Colab_Create({ listIndustri, @@ -184,18 +185,24 @@ function ButtonAction({ value }: { value: any }) { return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); if (value.projectCollaborationMaster_IndustriId === 0) return ComponentGlobal_NotifikasiPeringatan("Pilih Industri"); - // if (value.jumlah_partisipan < 2) - // return ComponentGlobal_NotifikasiPeringatan("Minimal Ada 2 Partisipan"); - await colab_funCreateProyek(value).then((res) => { - if (res.status === 201) { - setLoading(true); - router.back(); - ComponentGlobal_NotifikasiBerhasil(res.message); - } else { - ComponentGlobal_NotifikasiGagal(res.message); - } - }); + const res = await colab_funCreateProyek(value); + if (res.status === 201) { + // const dataNotif: any = { + // appId: res.data?.id as any, + // kategoriApp: "VOTING", + // status: create.data?.MasterStatus?.name as any, + // userId: create.data?.authorId as any, + // pesan: create.data?.title as any, + // title: "Job baru", + // }; + + setLoading(true); + router.back(); + ComponentGlobal_NotifikasiBerhasil(res.message); + } else { + ComponentGlobal_NotifikasiGagal(res.message); + } } // console.log(value); diff --git a/src/app_modules/colab/fun/create/fun_create_proyek.ts b/src/app_modules/colab/fun/create/fun_create_proyek.ts index f09bd685..5a194ed2 100644 --- a/src/app_modules/colab/fun/create/fun_create_proyek.ts +++ b/src/app_modules/colab/fun/create/fun_create_proyek.ts @@ -12,7 +12,7 @@ export default async function colab_funCreateProyek( ) { const AuthorId = await user_getOneUserId(); - const create = await prisma.projectCollaboration.create({ + const data = await prisma.projectCollaboration.create({ data: { title: value.title, lokasi: value.lokasi, @@ -25,7 +25,7 @@ export default async function colab_funCreateProyek( }, }); - if (!create) return { status: 400, message: "Gagal Membuat Proyek" }; + if (!data) return { status: 400, message: "Gagal Membuat Proyek" }; revalidatePath(RouterColab.beranda); - return { status: 201, message: "Berhasil Membuar Proyek" }; + return { data, status: 201, message: "Berhasil Membuar Proyek" }; } diff --git a/src/app_modules/home/component/button_header.tsx b/src/app_modules/home/component/button_header.tsx index b7fe8588..2410796d 100644 --- a/src/app_modules/home/component/button_header.tsx +++ b/src/app_modules/home/component/button_header.tsx @@ -15,6 +15,7 @@ import { IconBell, IconUserSearch } from "@tabler/icons-react"; import { RouterNotifikasi } from "@/app/lib/router_hipmi/router_notifikasi"; import { useShallowEffect } from "@mantine/hooks"; import notifikasi_countUserNotifikasi from "@/app_modules/notifikasi/fun/count/fun_count_by_id"; +import mqtt_client from "@/util/mqtt_client"; export function ComponentHome_ButtonHeaderLeft({ dataUser, @@ -59,17 +60,41 @@ export function ComponentHome_ButtonHeaderRight({ const [count, setCount] = useState(countNotifikasi); const [isLoadingBell, setIsLoadingBell] = useState(false); + // useShallowEffect(() => { + // onLoadNotifkasi({ + // onLoad(val) { + // setCount(val); + // }, + // }); + // }, []); + + // async function onLoadNotifkasi({ onLoad }: { onLoad: (val: any) => void }) { + // const loadNotifikasi = await notifikasi_countUserNotifikasi(); + // onLoad(loadNotifikasi); + // } + useShallowEffect(() => { - onLoadNotifkasi({ + mqtt_client.subscribe("USER"); + + mqtt_client.on("message", (topic: any, message: any) => { + // console.log(topic); + const data = JSON.parse(message.toString()); + + if (data.userId === dataUser.id) { + setCount(count + data.count); + } + }); + + onLoadNotifikasi({ onLoad(val) { setCount(val); }, }); - }, []); + }, [count]); - async function onLoadNotifkasi({ onLoad }: { onLoad: (val: any) => void }) { - const loadNotifikasi = await notifikasi_countUserNotifikasi(); - onLoad(loadNotifikasi); + async function onLoadNotifikasi({ onLoad }: { onLoad: (val: any) => void }) { + const loadNotif = await notifikasi_countUserNotifikasi(); + onLoad(loadNotif); } return ( diff --git a/src/app_modules/notifikasi/component/card_view.tsx b/src/app_modules/notifikasi/component/card_view.tsx index b3c048fe..ff0552fd 100644 --- a/src/app_modules/notifikasi/component/card_view.tsx +++ b/src/app_modules/notifikasi/component/card_view.tsx @@ -12,17 +12,18 @@ import { MainColor, } from "@/app_modules/_global/color/color_pallet"; import notifikasi_getByUserId from "../fun/get/get_notifiaksi_by_id"; +import { redirectVotingPage } from "./path/voting"; export function ComponentNotifiaksi_CardView({ data, onLoadData, activePage, - onSetJob, + onSetMenu, }: { data: MODEL_NOTIFIKASI; onLoadData: (val: any) => void; activePage: number; - onSetJob: (val: any) => void; + onSetMenu: (val: any) => void; }) { const router = useRouter(); return ( @@ -45,7 +46,7 @@ export function ComponentNotifiaksi_CardView({ data: data, router: router, onSetPage(val) { - onSetJob(val); + onSetMenu(val); }, }); @@ -55,6 +56,15 @@ export function ComponentNotifiaksi_CardView({ router: router, }); + data?.kategoriApp === "VOTING" && + redirectVotingPage({ + data: data, + router: router, + onSetPage(val) { + onSetMenu(val); + }, + }); + const updateIsRead = await notifikasi_funUpdateIsReadById({ notifId: data?.id, }); diff --git a/src/app_modules/notifikasi/component/path/voting.ts b/src/app_modules/notifikasi/component/path/voting.ts new file mode 100644 index 00000000..b283034e --- /dev/null +++ b/src/app_modules/notifikasi/component/path/voting.ts @@ -0,0 +1,36 @@ +import { RouterVote } from "@/app/lib/router_hipmi/router_vote"; +import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime"; +import { MODEL_NOTIFIKASI } from "../../model/interface"; + +export function redirectVotingPage({ + data, + router, + onSetPage, +}: { + data: MODEL_NOTIFIKASI; + router: AppRouterInstance; + onSetPage: (val: any) => void; +}) { + const path = RouterVote.status; + + if (data.status === "Publish") { + onSetPage({ + menuId: 2, + status: data.status, + }); + router.push(path, { scroll: false }); + } + // console.log(data) + + if (data.status === "Reject") { + onSetPage({ + menuId: 2, + status: data.status, + }); + router.push(path, { scroll: false }); + } + + if (data.status === "Voting Masuk") { + router.push(RouterVote.main_detail + data.appId, { scroll: false }); + } +} diff --git a/src/app_modules/notifikasi/component/ui_notifiaksi.tsx b/src/app_modules/notifikasi/component/ui_notifiaksi.tsx index 66ea0682..57db3e55 100644 --- a/src/app_modules/notifikasi/component/ui_notifiaksi.tsx +++ b/src/app_modules/notifikasi/component/ui_notifiaksi.tsx @@ -12,6 +12,10 @@ import { useState } from "react"; import notifikasi_getByUserId from "../fun/get/get_notifiaksi_by_id"; import { MODEL_NOTIFIKASI } from "../model/interface"; import { ComponentNotifiaksi_CardView } from "./card_view"; +import { + gs_vote_hotMenu, + gs_vote_status, +} from "@/app_modules/vote/global_state"; export function Notifikasi_UiView({ listNotifikasi, @@ -24,19 +28,21 @@ export function Notifikasi_UiView({ // JOB const [jobMenuId, setJobMenuId] = useAtom(gs_job_hot_menu); const [jobStatus, setJobStatus] = useAtom(gs_job_status); + const [voteMenu, setVoteMenu] = useAtom(gs_vote_hotMenu); + const [voeStatus, setVoteStatus] = useAtom(gs_vote_status); - useShallowEffect(() => { - onLoadData({ - onLoad(val) { - setData(val); - }, - }); - }, []); + useShallowEffect(() => { + onLoadData({ + onLoad(val) { + setData(val); + }, + }); + }, []); - async function onLoadData({ onLoad }: { onLoad: (val: any) => void }) { - const loadData = await notifikasi_getByUserId({ page: 1 }); - onLoad(loadData); - } + async function onLoadData({ onLoad }: { onLoad: (val: any) => void }) { + const loadData = await notifikasi_getByUserId({ page: 1 }); + onLoad(loadData); + } return ( <> @@ -67,9 +73,15 @@ export function Notifikasi_UiView({ data={item} onLoadData={(val) => setData(val)} activePage={activePage} - onSetJob={(val) => { - setJobMenuId(val.menuId); - setJobStatus(val.status); + onSetMenu={(val) => { + if (item?.kategoriApp === "JOB") { + setJobMenuId(val.menuId); + setJobStatus(val.status); + } + if (item?.kategoriApp === "VOTING") { + setVoteMenu(val.menuId); + setVoteStatus(val.status); + } }} /> )} diff --git a/src/app_modules/notifikasi/fun/get/get_notifiaksi_by_id.ts b/src/app_modules/notifikasi/fun/get/get_notifiaksi_by_id.ts index 0d2d4d68..edd947d5 100644 --- a/src/app_modules/notifikasi/fun/get/get_notifiaksi_by_id.ts +++ b/src/app_modules/notifikasi/fun/get/get_notifiaksi_by_id.ts @@ -3,17 +3,24 @@ import prisma from "@/app/lib/prisma"; import { user_getOneUserId } from "@/app_modules/fun_global/get_user_token"; -export default async function notifikasi_getByUserId({page}: {page: number }) { +export default async function notifikasi_getByUserId({ + page, +}: { + page: number; +}) { const userId = await user_getOneUserId(); - const takeData = 10; - const skipData = page * takeData - takeData; + const takeData = 10; + const skipData = page * takeData - takeData; const data = await prisma.notifikasi.findMany({ take: takeData, skip: skipData, - orderBy: { - isRead: "asc" - }, + orderBy: [ + { + isRead: "asc", + }, + { createdAt: "desc" }, + ], where: { userId: userId, userRoleId: "1", diff --git a/src/app_modules/vote/create/index.tsx b/src/app_modules/vote/create/index.tsx index b2909bfd..8991f93b 100644 --- a/src/app_modules/vote/create/index.tsx +++ b/src/app_modules/vote/create/index.tsx @@ -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); + } } diff --git a/src/app_modules/vote/detail/draft/index.tsx b/src/app_modules/vote/detail/draft/index.tsx index ea1fb05e..04b55895 100644 --- a/src/app_modules/vote/detail/draft/index.tsx +++ b/src/app_modules/vote/detail/draft/index.tsx @@ -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() { diff --git a/src/app_modules/vote/detail/main/index.tsx b/src/app_modules/vote/detail/main/index.tsx index 716d51e4..6349bbc4 100644 --- a/src/app_modules/vote/detail/main/index.tsx +++ b/src/app_modules/vote/detail/main/index.tsx @@ -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} /> ( - 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 ( - <> - - - -
- Hasil Voting -
- - {/*
{JSON.stringify(data, null,2)}
*/} - - - {data.map((e) => ( - = 4 ? 6 : 4}> - - - - {e.jumlah} - {/* {hasil.filter((i: any) => i.idDaftarNama == "clsijw6ur0002x5loqsq6g4id")} */} - - - {e.value} - - - ))} - -
-
-
- - ); -} - -function TampilanListKontributor({ - lisKontributor, -}: { - lisKontributor: MODEL_VOTE_KONTRIBUTOR[]; -}) { - return ( - <> - - - -
- Daftar Voting -
- {lisKontributor.map((e, i) => ( - - - - - - - - - {e ? e.Author.Profile.name : "Nama author"} - - - - - - {e.Voting_DaftarNamaVote.value} - - - - - - ))} - {/* {lisKontributor.map((e) => ( - - - - - - {e ? e.Author.Profile.name : "Nama author"} - - - - 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. - - - - - ))} */} -
-
-
- {/*
{JSON.stringify(lisKontributor, null, 2)}
*/} - - ); + + + } else { + ComponentGlobal_NotifikasiPeringatan(res.message); + } } diff --git a/src/app_modules/vote/detail/review/index.tsx b/src/app_modules/vote/detail/review/index.tsx index 7782b291..c6044a40 100644 --- a/src/app_modules/vote/detail/review/index.tsx +++ b/src/app_modules/vote/detail/review/index.tsx @@ -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 ( <> diff --git a/src/app_modules/vote/fun/create/create_hasil.ts b/src/app_modules/vote/fun/create/create_hasil.ts index 98708d5f..1b1e3ab9 100644 --- a/src/app_modules/vote/fun/create/create_hasil.ts +++ b/src/app_modules/vote/fun/create/create_hasil.ts @@ -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", + }; } diff --git a/src/app_modules/vote/fun/create/create_vote.ts b/src/app_modules/vote/fun/create/create_vote.ts index 33f67c1f..dda6597c 100644 --- a/src/app_modules/vote/fun/create/create_vote.ts +++ b/src/app_modules/vote/fun/create/create_vote.ts @@ -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", }; diff --git a/src/app_modules/vote/fun/edit/fun_edit_status_by_id.ts b/src/app_modules/vote/fun/edit/fun_edit_status_by_id.ts index 7d4d937a..cf4e73fc 100644 --- a/src/app_modules/vote/fun/edit/fun_edit_status_by_id.ts +++ b/src/app_modules/vote/fun/edit/fun_edit_status_by_id.ts @@ -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", };