Merge pull request #216 from bipproduction/fix/bug/voting

Fix/bug/voting
This commit is contained in:
Bagasbanuna02
2024-12-27 11:08:28 +08:00
committed by GitHub
38 changed files with 1082 additions and 490 deletions

View File

@@ -2,6 +2,8 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [1.2.35](https://github.com/bipproduction/hipmi/compare/v1.2.34...v1.2.35) (2024-12-27)
## [1.2.34](https://github.com/bipproduction/hipmi/compare/v1.2.33...v1.2.34) (2024-12-24)
## [1.2.33](https://github.com/bipproduction/hipmi/compare/v1.2.32...v1.2.33) (2024-12-22)

View File

@@ -1,6 +1,6 @@
{
"name": "hipmi",
"version": "1.2.34",
"version": "1.2.35",
"private": true,
"prisma": {
"seed": "npx tsx prisma/seed.ts --yes"

View File

@@ -1,5 +1,5 @@
import { prisma } from "@/app/lib";
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
@@ -7,7 +7,7 @@ export const dynamic = "force-dynamic";
export async function GET(request: Request) {
try {
const userLoginId = await newFunGetUserId();
const userLoginId = await funGetUserIdByToken();
const count = await prisma.notifikasi.findMany({
where: {

View File

@@ -1,5 +1,5 @@
import { prisma } from "@/app/lib";
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { ICategoryapp } from "@/app_modules/notifikasi/model/interface";
import backendLogger from "@/util/backendLogger";
import _ from "lodash";
@@ -13,7 +13,7 @@ export async function GET(request: Request) {
const category = searchParams.get("category") as ICategoryapp;
const page = searchParams.get("page");
const userLoginId = await newFunGetUserId();
const userLoginId = await funGetUserIdByToken();
const fixPage = _.toNumber(page);
const takeData = 10;
const skipData = fixPage * takeData - takeData;

View File

@@ -1,4 +1,4 @@
import { jwtVerify } from "jose";
import { decrypt } from "@/app/auth/_lib/decrypt";
import _ from "lodash";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
@@ -20,22 +20,3 @@ export async function GET() {
return NextResponse.json({ status: 200, message: "OK", data: dataUser });
}
async function decrypt({
token,
encodedKey,
}: {
token: string;
encodedKey: string;
}): Promise<Record<string, any> | null> {
try {
const enc = new TextEncoder().encode(encodedKey);
const { payload } = await jwtVerify(token, enc, {
algorithms: ["HS256"],
});
return (payload.user as Record<string, any>) || null;
} catch (error) {
console.error("Gagal verifikasi session", error);
return null;
}
}

View File

@@ -0,0 +1,312 @@
import { prisma } from "@/app/lib";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
try {
let fixData;
const { searchParams } = new URL(request.url);
const search = searchParams.get("search");
const kategori = searchParams.get("kategori");
const status = searchParams.get("status");
const page = searchParams.get("page");
const takeData = 5;
const skipData = Number(page) * 5 - 5;
const userLoginId = await funGetUserIdByToken();
if (userLoginId == null) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data, user id tidak ada",
},
{ status: 500 }
);
}
if (kategori == "beranda" && search != null && search != "") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
updatedAt: "desc",
},
where: {
voting_StatusId: "1",
isArsip: false,
isActive: true,
akhirVote: {
gte: new Date(),
},
title: {
contains: search,
mode: "insensitive",
},
},
select: {
id: true,
title: true,
isActive: true,
createdAt: true,
updatedAt: true,
deskripsi: true,
awalVote: true,
akhirVote: true,
catatan: true,
authorId: true,
voting_StatusId: true,
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
include: {
Voting_Kontributor: {
include: {
Author: true,
},
},
},
},
Author: {
select: {
id: true,
username: true,
nomor: true,
Profile: true,
},
},
},
});
} else if (kategori == "beranda") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
updatedAt: "desc",
},
where: {
voting_StatusId: "1",
isArsip: false,
isActive: true,
akhirVote: {
gte: new Date(),
},
title: {
// contains: search,
mode: "insensitive",
},
},
select: {
id: true,
title: true,
isActive: true,
createdAt: true,
updatedAt: true,
deskripsi: true,
awalVote: true,
akhirVote: true,
catatan: true,
authorId: true,
voting_StatusId: true,
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
include: {
Voting_Kontributor: {
include: {
Author: true,
},
},
},
},
Author: {
select: {
id: true,
username: true,
nomor: true,
Profile: true,
},
},
},
});
} else if (kategori == "status" && status == "1") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
updatedAt: "desc",
},
where: {
voting_StatusId: status,
authorId: userLoginId as string,
isActive: true,
akhirVote: {
gte: new Date(),
},
},
include: {
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
},
},
});
} else if (kategori == "status" && status != "1") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
updatedAt: "desc",
},
where: {
voting_StatusId: status,
authorId: userLoginId as string,
isActive: true,
},
});
} else if (kategori == "kontribusi") {
fixData = await prisma.voting_Kontributor.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "desc",
},
where: {
authorId: userLoginId,
},
select: {
id: true,
Voting: {
select: {
id: true,
title: true,
isActive: true,
awalVote: true,
akhirVote: true,
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
},
Author: {
select: {
Profile: true,
},
},
},
},
Voting_DaftarNamaVote: true,
Author: true,
},
});
} else if (kategori == "riwayat" && status == "1") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "asc",
},
where: {
voting_StatusId: "1",
isActive: true,
akhirVote: {
lte: new Date(),
},
},
select: {
id: true,
title: true,
isActive: true,
createdAt: true,
updatedAt: true,
deskripsi: true,
awalVote: true,
akhirVote: true,
catatan: true,
authorId: true,
voting_StatusId: true,
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
},
Author: {
select: {
id: true,
username: true,
nomor: true,
Profile: true,
},
},
},
});
} else if (kategori == "riwayat" && status == "2") {
fixData = await prisma.voting.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "asc",
},
where: {
voting_StatusId: "1",
authorId: userLoginId as string,
isActive: true,
akhirVote: {
lte: new Date(),
},
},
select: {
id: true,
title: true,
isActive: true,
createdAt: true,
updatedAt: true,
deskripsi: true,
awalVote: true,
akhirVote: true,
catatan: true,
authorId: true,
voting_StatusId: true,
Voting_DaftarNamaVote: {
orderBy: {
createdAt: "asc",
},
},
Author: {
select: {
id: true,
username: true,
nomor: true,
Profile: true,
},
},
},
});
}
return NextResponse.json(
{ success: true, message: "Berhasil mendapatkan data", data: fixData },
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error get voting: ", error);
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,22 @@
import { prisma } from "@/app/lib";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
const data = await prisma.voting_Status.findMany();
return NextResponse.json({
success: true,
message: "Berhasil mendapatkan data",
data: data,
});
} catch (error) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -1,9 +1,9 @@
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Event_Create } from "@/app_modules/event";
import { Event_getMasterTipeAcara } from "@/app_modules/event/fun/master/get_tipe_acara";
export default async function Page() {
const userLoginId = await newFunGetUserId();
const userLoginId = await funGetUserIdByToken();
const listTipeAcara = await Event_getMasterTipeAcara();
return (

View File

@@ -1,10 +1,10 @@
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Event_DetailMain } from "@/app_modules/event";
import { Event_countTotalPesertaById } from "@/app_modules/event/fun/count/count_total_peserta_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let eventId = params.id;
const userLoginId = await newFunGetUserId();
const userLoginId = await funGetUserIdByToken();
const totalPeserta = await Event_countTotalPesertaById(eventId);
return (

View File

@@ -1,4 +1,4 @@
import { newFunGetUserId } from "@/app/lib/new_fun_user_id";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import Ui_Konfirmasi from "@/app_modules/event/_ui/konfirmasi";
export default async function Page({
@@ -7,7 +7,7 @@ export default async function Page({
params: Promise<{ id: string }>;
}) {
const eventId = (await params).id;
const userLoginId = await newFunGetUserId();
const userLoginId = await funGetUserIdByToken();
return (
<>

View File

@@ -1,5 +1,5 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { RealtimeProvider } from "../lib";
import { newFunGetUserId } from "../lib/new_fun_user_id";
import { ServerEnv } from "../lib/server_env";
export default async function Layout({
@@ -8,7 +8,7 @@ export default async function Layout({
children: React.ReactNode;
}) {
const userId = await newFunGetUserId();
const userId = await funGetUserIdByToken();
return (
<>

View File

@@ -1,12 +1,10 @@
import { Vote_Beranda } from "@/app_modules/vote";
import { vote_getAllListPublish } from "@/app_modules/vote/fun/get/get_all_list_publish";
export default async function Page() {
const dataVote = await vote_getAllListPublish({ page: 1 });
return (
<>
<Vote_Beranda dataVote={dataVote as any} />
<Vote_Beranda />
</>
);
}

View File

@@ -1,11 +1,9 @@
import { Vote_Kontribusi } from "@/app_modules/vote";
import { vote_getAllListKontribusiByAuthorId } from "@/app_modules/vote/fun/get/get_list_kontribusi_by_author_id";
export default async function Page() {
const dataKontribusi = await vote_getAllListKontribusiByAuthorId({ page: 1 });
return (
<>
<Vote_Kontribusi dataKontribusi={dataKontribusi as any} />
<Vote_Kontribusi />
</>
);
}

View File

@@ -1,41 +1,9 @@
import { Vote_Riwayat } from "@/app_modules/vote";
import { vote_getAllListRiwayat } from "@/app_modules/vote/fun/get/get_all_list_riwayat";
import { Vote_getAllListRiwayatSaya as vote_getAllListRiwayatSaya } from "@/app_modules/vote/fun/get/get_all_list_riwayat_saya";
export default async function Page({ params }: { params: { id: string } }) {
let statusRiwayatId = params.id;
const listRiwayat = await vote_getAllListRiwayat({ page: 1 });
const listRiwayatSaya = await vote_getAllListRiwayatSaya({ page: 1 });
if (statusRiwayatId == "1") {
return (
<>
<Vote_Riwayat
riwayatId={statusRiwayatId}
listRiwayat={listRiwayat as any}
/>
</>
);
}
if (statusRiwayatId == "2") {
return (
<>
<Vote_Riwayat
riwayatId={statusRiwayatId}
listRiwayatSaya={listRiwayatSaya as any}
/>
</>
);
}
// return (
// <>
// <Vote_Riwayat
// riwayatId={statusRiwayatId}
// listRiwayat={listRiwayat as any}
// listRiwayatSaya={listRiwayatSaya as any}
// />
// </>
// );
return (
<>
<Vote_Riwayat />
</>
);
}

View File

@@ -1,25 +1,9 @@
import { Vote_Status } from "@/app_modules/vote";
import {
vote_funGetAllByStatusId,
voting_getMasterStatus,
} from "@/app_modules/vote/fun";
export default async function Page({ params }: { params: { id: string } }) {
const statusId = params.id;
const listStatus = await voting_getMasterStatus();
const dataVoting = await vote_funGetAllByStatusId({
page: 1,
statusId: statusId,
});
export default async function Page() {
return (
<>
<Vote_Status
statusId={statusId}
dataVoting={dataVoting as any}
listStatus={listStatus as any}
/>
<Vote_Status />
</>
);
}

View File

@@ -1,21 +1,28 @@
"use server"
"use server";
import _ from "lodash";
import { cookies } from "next/headers";
import { decrypt } from "../auth/_lib/decrypt";
import backendLogger from "@/util/backendLogger";
export async function newFunGetUserId() {
const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
try {
const key = process.env.NEXT_PUBLIC_BASE_SESSION_KEY;
const c = cookies().get("hipmi-key");
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
return null;
}
const token = c.value;
const dataUser = await decrypt({
token: token,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
});
return dataUser?.id;
} catch (error) {
backendLogger.log("Gagal mendapatkan user id", error);
return null;
}
const token = c.value;
const dataUser = await decrypt({
token: token,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
});
return dataUser?.id;
}
}

View File

@@ -0,0 +1,51 @@
"use client";
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import {
UIGlobal_LayoutHeaderTamplate,
UIGlobal_LayoutTamplate,
} from "@/app_modules/_global/ui";
import { Center, Grid, Group, Skeleton, Stack } from "@mantine/core";
export default function Voting_ComponentSkeletonViewPuh() {
return (
<>
<UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Detail Publish" />}
>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack spacing={"lg"}>
<Grid align="center">
<Grid.Col span={"content"}>
<Skeleton circle height={40} />
</Grid.Col>
<Grid.Col span={4}>
<Skeleton height={20} w={150} />
</Grid.Col>
</Grid>
<Stack align="center">
<Skeleton height={20} w={150} />
<Skeleton height={20} w={300} />
</Stack>
<Group position="center" spacing={100}>
<Stack align="center">
<Skeleton circle height={70} />
<Skeleton height={20} w={50} />
</Stack>
<Stack align="center">
<Skeleton circle height={70} />
<Skeleton height={20} w={50} />
</Stack>
</Group>
<Stack align="center">
<Skeleton height={15} w={50} /> <Skeleton height={20} w={50} />
</Stack>
</Stack>
</ComponentGlobal_CardStyles>
</UIGlobal_LayoutTamplate>
</>
);
}

View File

@@ -1,56 +1,36 @@
"use server";
import { prisma } from "@/app/lib";
import { ServerEnv } from "@/app/lib/server_env";
import { unsealData } from "iron-session";
import { jwtVerify } from "jose";
import { cookies } from "next/headers";
import { decrypt } from "../../../../app/auth/_lib/decrypt";
export async function funGetUserIdByToken() {
const SESSION_KEY = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!;
// console.log("SESSION_KEY", SESSION_KEY);
const c = cookies().get("hipmi-key");
const c = cookies().get(SESSION_KEY);
const cekUser = await decrypt({
token: c?.value as string,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
});
// console.log("userid" , cekUser?.id)
// const token = JSON.parse(
// await unsealData(c?.value as string, {
// password: process.env.WIBU_PWD as string,
// })
// );
// return token.id;
// const token = c?.value;
// const cekToken = await prisma.userSession.findFirst({
// where: {
// token: token,
// },
// });
// if (cekToken === null) return null
return cekUser?.id;
}
async function decrypt({
token,
encodedKey,
}: {
token: string;
encodedKey: string;
}): Promise<Record<string, any> | null> {
try {
const enc = new TextEncoder().encode(encodedKey);
const { payload } = await jwtVerify(token, enc, {
algorithms: ["HS256"],
});
return (payload.user as Record<string, any>) || null;
} catch (error) {
console.error("Gagal verifikasi session", error);
return null;
}
}
// async function decrypt({
// token,
// encodedKey,
// }: {
// token: string;
// encodedKey: string;
// }): Promise<Record<string, any> | null> {
// try {
// const enc = new TextEncoder().encode(encodedKey);
// const { payload } = await jwtVerify(token, enc, {
// algorithms: ["HS256"],
// });
// return (payload.user as Record<string, any>) || null;
// } catch (error) {
// console.error("Gagal verifikasi session", error);
// return null;
// }
// }

View File

@@ -15,7 +15,7 @@ export default function LayoutMainCrowd({
<UIGlobal_LayoutTamplate
header={
<UIGlobal_LayoutHeaderTamplate
title="Crowd Funding"
title="Crowdfunding"
routerLeft={RouterHome.main_home}
/>
}

View File

@@ -5,8 +5,6 @@ import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import { gs_donasi_hot_menu } from "@/app_modules/donasi/global_state";
import { gs_investas_menu } from "@/app_modules/investasi/g_state";
import { Grid, Image, Paper, Stack, Text, Title } from "@mantine/core";
@@ -21,26 +19,27 @@ export default function MainCrowd() {
const [donasiHotMenu, setDonasiHotMenu] = useAtom(gs_donasi_hot_menu);
const [loadingInv, setLoadingInv] = useState(false);
const [loadingDon, setLoadingDon] = useState(false);
const [isLoading, setLoading] = useState(true);
return (
<>
<Stack>
<Paper>
{/* <AspectRatio ratio={16 / 9}>
<Paper radius={"md"}>
</Paper>
</AspectRatio> */}
<Image
alt="Logo"
src={"/aset/investasi/logo-crowd-panjang-new.png"}
mah={"100%"}
styles={{
image: {
borderRadius: "20px",
},
}}
/>
</Paper>
<Image
height={200}
fit={"cover"}
alt="logo"
src={"/aset/investasi/logo-crowd-panjang-new.png"}
onLoad={() => setLoading(false)}
styles={{
imageWrapper: {
border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px 10px 10px 10px",
},
image: {
borderRadius: "8px 8px 8px 8px",
},
}}
/>
<Stack>
{/* INVESTASI */}

View File

@@ -26,6 +26,7 @@ export default function BodyHome() {
const [dataUser, setDataUser] = useState<any>({});
const [dataJob, setDataJob] = useState<any[]>([]);
const [loadingJob, setLoadingJob] = useState(true);
const [loading, setLoading] = useState(true);
useShallowEffect(() => {
cekUserLogin();
@@ -59,16 +60,35 @@ export default function BodyHome() {
return (
<Box>
<Paper
{/* <Paper
radius={"xl"}
h={150}
mb={"xs"}
style={{
borderRadius: "10px 10px 10px 10px",
border: `2px solid ${AccentColor.blue}`,
position: "relative",
}}
>
<Image radius={"lg"} alt="logo" src={"/aset/home/home-hipmi-new.png"} />
</Paper>
</Paper> */}
<Image
height={140}
fit={"cover"}
alt="logo"
src={"/aset/home/home-hipmi-new.png"}
onLoad={() => setLoading(false)}
styles={{
imageWrapper: {
border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px 10px 10px 10px",
},
image: {
borderRadius: "8px 8px 8px 8px",
},
}}
/>
<Stack my={"sm"}>
<SimpleGrid cols={2} spacing="md">

View File

@@ -0,0 +1,42 @@
/**
* Mengambil daftar semua voting dari API berdasarkan filter yang diberikan.
*
* @param {Object} params - Parameter untuk permintaan data voting.
* @param {"beranda"|"status"} params.kategori - Kategori voting yang diminta, hanya dapat berupa "beranda" atau "status".
* @param {string} params.page - Nomor halaman untuk pagination.
* @param {string|null|undefined} [params.search] - Kata kunci pencarian untuk memfilter voting (opsional).
* @param {"1"|"2"|"3"|"4"|undefined} [params.status] - Status voting, di mana:
* - "1": Publish,
* - "2": Review,
* - "3": Draft,
* - "4": Reject.
* Parameter ini bersifat opsional.
* @returns {Promise<Object|null>} Mengembalikan objek hasil permintaan dalam bentuk JSON jika berhasil,
* atau `null` jika terjadi kesalahan dalam parsing respons.
*
* @example
* // Contoh penggunaan:
* apiGetAllVoting({
* kategori: "beranda",
* page: "1",
* search: "pemilu",
* status: "1",
* }).then(data => console.log(data));
*/
export const apiGetAllVoting = async ({
kategori,
page,
search,
status,
}: {
kategori: "beranda" | "status" | "kontribusi" | "riwayat";
page: string;
search?: string | null;
status?: "1" | "2" | "3" | "4";
}) => {
const respone = await fetch(
`/api/voting/get?kategori=${kategori}&page=${page}&search=${search || ""}&status=${status || ""}`
);
return await respone.json().catch(() => null);
};

View File

@@ -7,17 +7,9 @@ import {
ComponentGlobal_CardStyles,
} from "@/app_modules/_global/component";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import {
Avatar,
Badge,
Box,
Center,
Grid,
Group,
Stack,
Text,
Title
} from "@mantine/core";
import { Avatar, Badge, Box, Center, Grid, Stack, Text } from "@mantine/core";
import moment from "moment";
import "moment/locale/id";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_VOTING } from "../model/interface";
@@ -75,35 +67,23 @@ export default function ComponentVote_CardViewPublish({
backgroundColor: AccentColor.blue,
border: `1px solid ${AccentColor.skyblue}`,
color: "white",
width: "80%",
width: "70%",
},
}}
>
<Group>
<Text>
{data
? data?.awalVote.toLocaleDateString(["id-ID"], {
dateStyle: "medium",
})
: "tgl awal voting"}
</Text>
<Text>-</Text>
<Text>
{data
? data?.akhirVote.toLocaleDateString(["id-ID"], {
dateStyle: "medium",
})
: "tgl akhir voting"}
</Text>
</Group>
<Text>
{data
? moment(data.awalVote).format("ll")
: "tgl awal voting"}{" "}
-{" "}
{data
? moment(data.akhirVote).format("ll")
: "tgl akhir voting"}
</Text>
</Badge>
</Stack>
{data ? (
<Stack>
<Center>
<Title order={5}>Hasil Voting</Title>
</Center>
<Grid justify="center">
{data?.Voting_DaftarNamaVote.map((e) => (
<Grid.Col

View File

@@ -1,12 +1,17 @@
"use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
import {
ComponentGlobal_CardLoadingOverlay,
ComponentGlobal_CardStyles,
} from "@/app_modules/_global/component";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import { Badge, Card, Group, Stack, Text } from "@mantine/core";
import { Badge, Stack, Text } from "@mantine/core";
import moment from "moment";
import "moment/locale/id";
import { useRouter } from "next/navigation";
import { MODEL_VOTING } from "../model/interface";
import { useState } from "react";
import { ComponentGlobal_CardLoadingOverlay, ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import { MODEL_VOTING } from "../model/interface";
export default function ComponentVote_CardViewStatus({
path,
@@ -17,13 +22,13 @@ export default function ComponentVote_CardViewStatus({
}) {
const router = useRouter();
const [visible, setVisible] = useState(false);
return (
<>
<ComponentGlobal_CardStyles
onClickHandler={() => {
if (data?.id === undefined) {
ComponentGlobal_NotifikasiPeringatan("Path tidak ditemukan");
ComponentGlobal_NotifikasiPeringatan("Halaman tidak ditemukan");
} else {
setVisible(true);
router.push((path as string) + data?.id);
@@ -42,23 +47,14 @@ export default function ComponentVote_CardViewStatus({
backgroundColor: AccentColor.blue,
border: `1px solid ${AccentColor.skyblue}`,
color: "white",
width: "80%",
width: "70%",
},
}}
>
<Group>
<Text>
{data?.awalVote.toLocaleDateString(["id-ID"], {
dateStyle: "medium",
})}
</Text>
<Text>-</Text>
<Text>
{data?.akhirVote.toLocaleDateString(["id-ID"], {
dateStyle: "medium",
})}
</Text>
</Group>
<Text>
{data ? moment(data.awalVote).format("ll") : "tgl awal voting"} -{" "}
{data ? moment(data.akhirVote).format("ll") : "tgl akhir voting"}
</Text>
</Badge>
</Stack>
{visible && <ComponentGlobal_CardLoadingOverlay />}

View File

@@ -1,3 +1,9 @@
import { Voting_ComponentLayoutHeaderDetailPublish } from "./detail/comp_layout_header_detail_publish";
import {
Voting_ComponentSkeletonViewPublish,
Voting_ComponentSkeletonViewStatus,
} from "./skeleton_view";
export { Voting_ComponentLayoutHeaderDetailPublish };
export { Voting_ComponentSkeletonViewPublish };
export { Voting_ComponentSkeletonViewStatus };

View File

@@ -0,0 +1,97 @@
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import { Grid, Group, Skeleton, Stack } from "@mantine/core";
export function Voting_ComponentSkeletonViewPublish() {
return (
<>
{Array.from({ length: 2 }).map((e, i) => (
<ComponentGlobal_CardStyles key={i} marginBottom={"0"}>
<Stack spacing={"lg"}>
<Grid align="center">
<Grid.Col span={"content"}>
<Skeleton circle height={40} />
</Grid.Col>
<Grid.Col span={4}>
<Skeleton height={20} w={150} />
</Grid.Col>
</Grid>
<Stack align="center">
<Skeleton height={20} w={150} />
<Skeleton height={20} w={300} />
{/* <Skeleton height={20} w={70} /> */}
</Stack>
<Grid grow>
{Array.from({ length: 2 }).map((e, i) => (
<Grid.Col span={4} key={i}>
<Stack align="center">
<Skeleton circle height={70} />
<Skeleton height={20} w={50} />
</Stack>
</Grid.Col>
))}
</Grid>
</Stack>
</ComponentGlobal_CardStyles>
))}
</>
);
}
export function Voting_ComponentSkeletonViewStatus() {
return (
<>
{Array.from({ length: 2 }).map((e, i) => (
<ComponentGlobal_CardStyles key={i}>
<Stack align="center" spacing="lg">
<Skeleton height={20} w={150} />
<Skeleton height={20} w={300} />
</Stack>
</ComponentGlobal_CardStyles>
))}
</>
);
}
export function Voting_ComponentSkeletonViewKontribusi() {
return (
<>
{Array.from({ length: 2 }).map((e, i) => (
<ComponentGlobal_CardStyles key={i} marginBottom={"0"}>
<Stack spacing={"lg"}>
<Grid align="center">
<Grid.Col span={"content"}>
<Skeleton circle height={40} />
</Grid.Col>
<Grid.Col span={4}>
<Skeleton height={20} w={150} />
</Grid.Col>
</Grid>
<Stack align="center">
<Skeleton height={20} w={150} />
<Skeleton height={20} w={300} />
</Stack>
<Group position="center" spacing={100}>
<Stack align="center">
<Skeleton circle height={70} />
<Skeleton height={20} w={50} />
</Stack>
<Stack align="center">
<Skeleton circle height={70} />
<Skeleton height={20} w={50} />
</Stack>
</Group>
<Stack align="center">
<Skeleton height={15} w={50} /> <Skeleton height={20} w={50} />
</Stack>
</Stack>
</ComponentGlobal_CardStyles>
))}
</>
);
}

View File

@@ -53,3 +53,4 @@ export {
Vote_DetailRiwayatSaya,
LayoutVote_DetailRiwayatSaya,
};

View File

@@ -1,8 +1,11 @@
"use client";
import { gs_votingTiggerBeranda } from "@/app/lib/global_state";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import { AccentColor } from "@/app_modules/_global/color";
import ComponentGlobal_CreateButton from "@/app_modules/_global/component/button_create";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import {
Affix,
Box,
@@ -14,22 +17,17 @@ import {
TextInput,
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useAtom } from "jotai";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllVoting } from "../_lib/api_voting";
import { Voting_ComponentSkeletonViewPublish } from "../component";
import ComponentVote_CardViewPublish from "../component/card_view_publish";
import { vote_getAllListPublish } from "../fun/get/get_all_list_publish";
import { MODEL_VOTING } from "../model/interface";
import { gs_votingTiggerBeranda } from "@/app/lib/global_state";
import { useAtom } from "jotai";
import { AccentColor } from "@/app_modules/_global/color";
export default function Vote_Beranda({
dataVote,
}: {
dataVote: MODEL_VOTING[];
}) {
const [data, setData] = useState(dataVote);
export default function Vote_Beranda() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
// Realtime
@@ -46,32 +44,50 @@ export default function Vote_Beranda({
}, [isTriggerVotingBeranda, setIsShowUpdate]);
useShallowEffect(() => {
onLoad({
newData(val) {
setData(val);
},
});
setIsTriggerVotingBeranda(false);
}, [setData, setIsTriggerVotingBeranda]);
onLoad();
}, []);
async function onLoad({ newData }: { newData: (val: any) => void }) {
const loadData = await vote_getAllListPublish({ page: 1 });
newData(loadData);
async function onLoad() {
try {
const loadData = await apiGetAllVoting({
kategori: "beranda",
page: "1",
});
setData(loadData.data as any);
setIsTriggerVotingBeranda(false);
} catch (error) {
clientLogger.error("Error get data beranda", error);
}
}
async function onSearch(s: string) {
const loadSearch = await vote_getAllListPublish({ page: 1, search: s });
setData(loadSearch as any);
try {
const loadData = await apiGetAllVoting({
kategori: "beranda",
page: "1",
search: s,
});
setData(loadData.data as any);
} catch (error) {
clientLogger.error("Error get data beranda", error);
}
}
async function onLoadData({ onPublish }: { onPublish: (val: any) => void }) {
setIsLoading(true);
const loadData = await vote_getAllListPublish({ page: 1 });
onPublish(loadData);
setIsShowUpdate(false);
setIsTriggerVotingBeranda(false);
setIsLoading(false);
async function onLoadData() {
try {
setIsLoading(true);
const loadData = await apiGetAllVoting({
kategori: "beranda",
page: "1",
});
setData(loadData.data as any);
setIsShowUpdate(false);
setIsTriggerVotingBeranda(false);
} catch (error) {
clientLogger.error("Error get data beranda", error);
} finally {
setIsLoading(false);
}
}
return (
@@ -90,11 +106,7 @@ export default function Vote_Beranda({
radius={"xl"}
opacity={0.8}
onClick={() => {
onLoadData({
onPublish(val) {
setData(val);
},
});
onLoadData();
}}
>
Update beranda
@@ -111,7 +123,9 @@ export default function Vote_Beranda({
<ComponentGlobal_CreateButton path={RouterVote.create} />
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewPublish />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
<Box>
@@ -123,15 +137,16 @@ export default function Vote_Beranda({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await vote_getAllListPublish({
page: activePage + 1,
const loadData = await apiGetAllVoting({
kategori: "beranda",
page: `${activePage + 1}`,
});
setActivePage((val) => val + 1);
return loadData;
return loadData.data;
}}
>
{(item) => (

View File

@@ -1,64 +1,80 @@
"use client";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import { Box, Center, Loader, Stack } from "@mantine/core";
import _ from "lodash";
import ComponentVote_CardViewPublish from "../component/card_view_publish";
import ComponentVote_IsEmptyData from "../component/is_empty_data";
import { MODEL_VOTE_KONTRIBUTOR } from "../model/interface";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { data } from "autoprefixer";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader, Stack } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { vote_getAllListPublish } from "../fun/get/get_all_list_publish";
import { useState } from "react";
import { vote_getAllListKontribusiByAuthorId } from "../fun/get/get_list_kontribusi_by_author_id";
import { apiGetAllVoting } from "../_lib/api_voting";
import ComponentVote_CardViewPublish from "../component/card_view_publish";
import { MODEL_VOTE_KONTRIBUTOR } from "../model/interface";
import { Voting_ComponentSkeletonViewKontribusi } from "../component/skeleton_view";
export default function Vote_Kontribusi({
dataKontribusi,
}: {
dataKontribusi: MODEL_VOTE_KONTRIBUTOR[];
}) {
const [data, setData] = useState(dataKontribusi);
export default function Vote_Kontribusi() {
const [data, setData] = useState<MODEL_VOTE_KONTRIBUTOR[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const loadData = await apiGetAllVoting({
kategori: "kontribusi",
page: "1",
});
setData(loadData.data as any);
} catch (error) {
clientLogger.error("Error get data beranda", error);
}
}
return (
<>
{_.isEmpty(dataKontribusi) ? (
<ComponentGlobal_IsEmptyData />
) : (
<Box >
<ScrollOnly
height="82vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData}
moreData={async () => {
const loadData = await vote_getAllListKontribusiByAuthorId({
page: activePage + 1,
});
<Stack>
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewKontribusi />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
<Box>
<ScrollOnly
height="82vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData as any}
moreData={async () => {
const loadData = await apiGetAllVoting({
kategori: "kontribusi",
page: `${activePage + 1}`,
});
setActivePage((val) => val + 1);
setActivePage((val) => val + 1);
return loadData;
}}
>
{(item) => (
<ComponentVote_CardViewPublish
path={RouterVote.detail_kontribusi}
pilihanSaya={true}
data={item.Voting}
authorName={true}
namaPilihan={item.Voting_DaftarNamaVote.value}
/>
)}
</ScrollOnly>
</Box>
)}
{/* <pre>{JSON.stringify(dataKontribusi, null, 2)}</pre> */}
return loadData.data;
}}
>
{(item) => (
<ComponentVote_CardViewPublish
path={RouterVote.detail_kontribusi}
pilihanSaya={true}
data={item.Voting}
authorName={true}
namaPilihan={item.Voting_DaftarNamaVote.value}
/>
)}
</ScrollOnly>
</Box>
)}
</Stack>
</>
);
}

View File

@@ -1,30 +1,18 @@
"use client";
import { Stack, Tabs } from "@mantine/core";
import { useState } from "react";
import Vote_SemuaRiwayat from "./semua";
import Vote_RiwayatSaya from "./saya";
import { useAtom } from "jotai";
import { gs_vote_riwayat } from "../../global_state";
import { MODEL_VOTING } from "../../model/interface";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { useRouter } from "next/navigation";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import { Stack, Tabs } from "@mantine/core";
import { useParams, useRouter } from "next/navigation";
import Vote_RiwayatSaya from "./saya";
import Vote_SemuaRiwayat from "./semua";
export default function Vote_Riwayat({
riwayatId,
listRiwayat,
listRiwayatSaya,
}: {
riwayatId: string;
listRiwayat?: MODEL_VOTING[];
listRiwayatSaya?: MODEL_VOTING[];
}) {
export default function Vote_Riwayat() {
const router = useRouter();
const [changeStatus, setChangeStatus] = useState(riwayatId);
const params = useParams<{ id: string }>();
const listTabs = [
{
@@ -39,20 +27,15 @@ export default function Vote_Riwayat({
},
];
async function onChangeStatus({ statusId }: { statusId: string }) {
router.push(RouterVote.riwayat({ id: statusId }));
}
return (
<>
<Tabs
mt={1}
variant="pills"
radius={"xl"}
value={changeStatus}
value={params.id}
onTabChange={(val: any) => {
setChangeStatus(val);
onChangeStatus({ statusId: val });
router.replace(RouterVote.riwayat({ id: val }));
}}
styles={{
tabsList: {
@@ -77,9 +60,9 @@ export default function Vote_Riwayat({
style={{
transition: "0.5s",
backgroundColor:
changeStatus === e.id ? MainColor.yellow : "white",
params.id === e.id ? MainColor.yellow : "white",
border:
changeStatus === e.id
params.id === e.id
? `1px solid ${AccentColor.yellow}`
: `1px solid white`,
}}
@@ -89,13 +72,8 @@ export default function Vote_Riwayat({
))}
</Tabs.List>
{riwayatId === "1" && (
<Vote_SemuaRiwayat listRiwayat={listRiwayat as any} />
)}
{riwayatId === "2" && (
<Vote_RiwayatSaya listRiwayatSaya={listRiwayatSaya as any} />
)}
{params.id === "1" && <Vote_SemuaRiwayat />}
{params.id === "2" && <Vote_RiwayatSaya />}
</Stack>
</Tabs>
</>

View File

@@ -1,28 +1,47 @@
"use client";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import { Box, Center, Loader, Stack } from "@mantine/core";
import _ from "lodash";
import { useRouter } from "next/navigation";
import ComponentVote_CardViewPublish from "../../component/card_view_publish";
import ComponentVote_IsEmptyData from "../../component/is_empty_data";
import { MODEL_VOTING } from "../../model/interface";
import { useState } from "react";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { Vote_getAllListRiwayatSaya } from "../../fun/get/get_all_list_riwayat_saya";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import { Voting_ComponentSkeletonViewPublish } from "../../component";
import ComponentVote_CardViewPublish from "../../component/card_view_publish";
import { MODEL_VOTING } from "../../model/interface";
export default function Vote_RiwayatSaya({
listRiwayatSaya,
}: {
listRiwayatSaya: MODEL_VOTING[];
}) {
const [data, setData] = useState(listRiwayatSaya);
export default function Vote_RiwayatSaya() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "riwayat",
page: "1",
status: "2",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewPublish />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
@@ -35,14 +54,17 @@ export default function Vote_RiwayatSaya({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await Vote_getAllListRiwayatSaya({
page: activePage + 1,
const respone = await apiGetAllVoting({
kategori: "riwayat",
page: `${activePage + 1}`,
status: "2",
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (

View File

@@ -2,25 +2,46 @@
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import { Voting_ComponentSkeletonViewPublish } from "../../component";
import ComponentVote_CardViewPublish from "../../component/card_view_publish";
import { vote_getAllListRiwayat } from "../../fun/get/get_all_list_riwayat";
import { MODEL_VOTING } from "../../model/interface";
export default function Vote_SemuaRiwayat({
listRiwayat,
}: {
listRiwayat: MODEL_VOTING[];
}) {
const [data, setData] = useState(listRiwayat);
export default function Vote_SemuaRiwayat() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "riwayat",
page: "1",
status: "1",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewPublish />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
@@ -33,14 +54,17 @@ export default function Vote_SemuaRiwayat({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await vote_getAllListRiwayat({
page: activePage + 1,
const respone = await apiGetAllVoting({
kategori: "riwayat",
page: `${activePage + 1}`,
status: "1",
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (

View File

@@ -1,28 +1,47 @@
"use client";
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import { Box, Center, Loader, Stack } from "@mantine/core";
import _ from "lodash";
import ComponentVote_CardViewStatus from "../../component/card_view_status";
import ComponentVote_IsEmptyData from "../../component/is_empty_data";
import { MODEL_VOTING } from "../../model/interface";
import { useState } from "react";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { vote_getAllReview } from "../../fun/get/status/get_all_review";
import { vote_getAllDraft } from "../../fun/get/status/get_all_draft";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import { Voting_ComponentSkeletonViewStatus } from "../../component";
import ComponentVote_CardViewStatus from "../../component/card_view_status";
import { MODEL_VOTING } from "../../model/interface";
export default function Vote_StatusDraft({
listDraft,
}: {
listDraft: MODEL_VOTING[];
}) {
const [data, setData] = useState(listDraft);
export default function Vote_StatusDraft() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "status",
page: "1",
status: "3",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewStatus />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
@@ -35,20 +54,22 @@ export default function Vote_StatusDraft({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await vote_getAllDraft({
page: activePage + 1,
const respone = await apiGetAllVoting({
kategori: "status",
page: `${activePage + 1}`,
status: "3",
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (
<ComponentVote_CardViewStatus
data={item}
path={RouterVote.detail_draft}
path={RouterVote.detail_review}
/>
)}
</ScrollOnly>

View File

@@ -5,32 +5,34 @@ import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { MODEL_NEW_DEFAULT_MASTER } from "@/app_modules/model_global/interface";
import { Box, Stack, Tabs } from "@mantine/core";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_VOTING } from "../../model/interface";
import { useParams, useRouter } from "next/navigation";
import Vote_StatusDraft from "./draft";
import Vote_StatusPublish from "./publish";
import Vote_StatusReject from "./reject";
import Vote_StatusReview from "./review";
export default function Vote_Status({
statusId,
dataVoting,
listStatus,
}: {
statusId: string;
dataVoting: MODEL_VOTING[];
listStatus: MODEL_NEW_DEFAULT_MASTER[];
}) {
export default function Vote_Status() {
const router = useRouter();
const [changeStatus, setChangeStatus] = useState(statusId);
async function onChangeStatus({ statusId }: { statusId: string }) {
router.replace(RouterVote.status({ id: statusId }));
}
const params = useParams<{ id: string }>();
const status = [
{
id: "1",
name: "Publish",
},
{
id: "2",
name: "Review",
},
{
id: "3",
name: "Draft",
},
{
id: "4",
name: "Reject",
},
];
return (
<>
@@ -38,10 +40,9 @@ export default function Vote_Status({
mt={1}
variant="pills"
radius={"xl"}
value={changeStatus}
value={params.id}
onTabChange={(val: any) => {
setChangeStatus(val);
onChangeStatus({ statusId: val });
router.replace(RouterVote.status({ id: val }));
}}
styles={{
tabsList: {
@@ -57,7 +58,7 @@ export default function Vote_Status({
>
<Stack>
<Tabs.List grow>
{listStatus.map((e) => (
{status.map((e) => (
<Tabs.Tab
w={"20%"}
key={e.id}
@@ -67,9 +68,9 @@ export default function Vote_Status({
style={{
transition: "0.5s",
backgroundColor:
changeStatus === e.id ? MainColor.yellow : "white",
params.id === e.id ? MainColor.yellow : "white",
border:
changeStatus === e.id
params.id === e.id
? `1px solid ${AccentColor.yellow}`
: `1px solid white`,
}}
@@ -80,12 +81,10 @@ export default function Vote_Status({
</Tabs.List>
<Box>
{statusId === "1" && (
<Vote_StatusPublish listPublish={dataVoting} />
)}
{statusId === "2" && <Vote_StatusReview listReview={dataVoting} />}
{statusId === "3" && <Vote_StatusDraft listDraft={dataVoting} />}
{statusId === "4" && <Vote_StatusReject listReject={dataVoting} />}
{params.id === "1" && <Vote_StatusPublish />}
{params.id === "2" && <Vote_StatusReview />}
{params.id === "3" && <Vote_StatusDraft />}
{params.id === "4" && <Vote_StatusReject />}
</Box>
</Stack>
</Tabs>

View File

@@ -2,56 +2,82 @@
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import job_getAllStatusPublish from "@/app_modules/job/fun/get/status/get_list_publish";
import { Center, Loader } from "@mantine/core";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader, Stack } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import ComponentVote_CardViewPublish from "../../component/card_view_publish";
import { MODEL_VOTING } from "../../model/interface";
import { Voting_ComponentSkeletonViewPublish } from "../../component";
export default function Vote_StatusPublish({
listPublish,
}: {
listPublish: MODEL_VOTING[];
}) {
const [data, setData] = useState(listPublish);
export default function Vote_StatusPublish() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "status",
page: "1",
status: "1",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
<ScrollOnly
height="75vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData}
moreData={async () => {
const loadData = await job_getAllStatusPublish({
page: activePage + 1,
});
<Stack>
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewPublish />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
<Box>
<ScrollOnly
height="75vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData as any}
moreData={async () => {
const respone = await apiGetAllVoting({
kategori: "status",
page: `${activePage + 1}`,
status: "1",
});
setActivePage((val) => val + 1);
setActivePage((val) => val + 1);
return loadData;
}}
>
{(item) => (
<ComponentVote_CardViewPublish
data={item}
path={RouterVote.detail_publish}
statusArsip
/>
)}
</ScrollOnly>
)}
return respone.data;
}}
>
{(item) => (
<ComponentVote_CardViewPublish
data={item}
path={RouterVote.detail_publish}
statusArsip
/>
)}
</ScrollOnly>
</Box>
)}
</Stack>
</>
);
}

View File

@@ -2,25 +2,46 @@
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import { Voting_ComponentSkeletonViewStatus } from "../../component";
import ComponentVote_CardViewStatus from "../../component/card_view_status";
import { vote_getAllReject } from "../../fun/get/status/get_all_reject";
import { MODEL_VOTING } from "../../model/interface";
export default function Vote_StatusReject({
listReject,
}: {
listReject: MODEL_VOTING[];
}) {
const [data, setData] = useState(listReject);
export default function Vote_StatusReject() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "status",
page: "1",
status: "4",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewStatus />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
@@ -33,20 +54,22 @@ export default function Vote_StatusReject({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await vote_getAllReject({
page: activePage + 1,
const respone = await apiGetAllVoting({
kategori: "status",
page: `${activePage + 1}`,
status: "4",
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (
<ComponentVote_CardViewStatus
data={item}
path={RouterVote.detail_reject}
path={RouterVote.detail_review}
/>
)}
</ScrollOnly>

View File

@@ -2,29 +2,50 @@
import { RouterVote } from "@/app/lib/router_hipmi/router_vote";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllVoting } from "../../_lib/api_voting";
import ComponentVote_CardViewStatus from "../../component/card_view_status";
import { vote_getAllReview } from "../../fun/get/status/get_all_review";
import { MODEL_VOTING } from "../../model/interface";
import { Voting_ComponentSkeletonViewStatus } from "../../component";
export default function Vote_StatusReview({
listReview,
}: {
listReview: MODEL_VOTING[];
}) {
const [data, setData] = useState(listReview);
export default function Vote_StatusReview() {
const [data, setData] = useState<MODEL_VOTING[] | null>(null);
const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
const respone = await apiGetAllVoting({
kategori: "status",
page: "1",
status: "2",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data review", error);
}
}
return (
<>
{_.isEmpty(data) ? (
{_.isNull(data) ? (
<Voting_ComponentSkeletonViewStatus />
) : _.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData />
) : (
// --- Main component --- //
<Box >
<Box>
<ScrollOnly
height="75vh"
renderLoading={() => (
@@ -33,14 +54,16 @@ export default function Vote_StatusReview({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await vote_getAllReview({
page: activePage + 1,
const respone = await apiGetAllVoting({
kategori: "status",
page: `${activePage + 1}`,
status: "2",
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (

View File

@@ -19,6 +19,7 @@ const middlewareConfig: MiddlewareConfig = {
userPath: "/dev/home",
publicRoutes: [
"/",
"/api/voting/*",
"/api/collaboration/*",
"/api/notifikasi/*",
"/api/logs/*",