feat:bulk delete

This commit is contained in:
Rama Priyanto 2025-06-24 19:58:02 +07:00
parent aebf91a442
commit cc45c2dabb
2 changed files with 163 additions and 125 deletions

View File

@ -69,98 +69,98 @@ export default function Login() {
error("Username & Password Wajib Diisi !"); error("Username & Password Wajib Diisi !");
} else { } else {
// login dengan otp // login dengan otp
// loading(); loading();
// const response: any = await emailValidation(data); const response: any = await emailValidation(data);
// if (response?.error) { if (response?.error) {
// console.log("error", response); console.log("error", response);
// if (response?.message?.messages[0]?.includes("failed to send mail")) { if (response?.message?.messages[0]?.includes("failed to send mail")) {
// error("Gagal Mengirim OTP"); error("Gagal Mengirim OTP");
// return false; return false;
// } }
// if (response?.message?.messages[0]?.includes("username")) { if (response?.message?.messages[0]?.includes("username")) {
// error("Username / Password Tidak Sesuai"); error("Username / Password Tidak Sesuai");
// return false; return false;
// } }
// error("Unknown Error"); error("Unknown Error");
// return false; return false;
// } }
// close(); close();
// if (response?.data?.messages[0] === "Continue to setup email") { if (response?.data?.messages[0] === "Continue to setup email") {
// setFirstLogin(true); setFirstLogin(true);
// } else { } else {
// setNeedOtp(true); setNeedOtp(true);
// } }
// login tanpa otp // login tanpa otp
loading(); // loading();
const response = await postSignIn(data); // const response = await postSignIn(data);
if (response?.error) { // if (response?.error) {
error("Username / Password Tidak Sesuai"); // error("Username / Password Tidak Sesuai");
} else { // } else {
const profile = await getProfile(response?.data?.data?.access_token); // const profile = await getProfile(response?.data?.data?.access_token);
const dateTime: any = new Date(); // const dateTime: any = new Date();
const newTime: any = dateTime.getTime() + 10 * 60 * 1000; // const newTime: any = dateTime.getTime() + 10 * 60 * 1000;
Cookies.set("access_token", response?.data?.data?.access_token, { // Cookies.set("access_token", response?.data?.data?.access_token, {
expires: 1, // expires: 1,
}); // });
Cookies.set("refresh_token", response?.data?.data?.refresh_token, { // Cookies.set("refresh_token", response?.data?.data?.refresh_token, {
expires: 1, // expires: 1,
}); // });
Cookies.set("time_refresh", newTime, { // Cookies.set("time_refresh", newTime, {
expires: 1, // expires: 1,
}); // });
Cookies.set("is_first_login", "true", { // Cookies.set("is_first_login", "true", {
secure: true, // secure: true,
sameSite: "strict", // sameSite: "strict",
}); // });
const resActivity = await saveActivity( // const resActivity = await saveActivity(
{ // {
activityTypeId: 1, // activityTypeId: 1,
url: "https://kontenhumas.com/auth", // url: "https://kontenhumas.com/auth",
userId: profile?.data?.data?.id, // userId: profile?.data?.data?.id,
}, // },
accessData?.id_token // accessData?.id_token
); // );
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, { // Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
expires: 1, // expires: 1,
}); // });
Cookies.set("uie", profile?.data?.data?.id, { // Cookies.set("uie", profile?.data?.data?.id, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ufne", profile?.data?.data?.fullname, { // Cookies.set("ufne", profile?.data?.data?.fullname, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ulie", profile?.data?.data?.userLevelGroup, { // Cookies.set("ulie", profile?.data?.data?.userLevelGroup, {
expires: 1, // expires: 1,
}); // });
Cookies.set("username", profile?.data?.data?.username, { // Cookies.set("username", profile?.data?.data?.username, {
expires: 1, // expires: 1,
}); // });
Cookies.set("urie", profile?.data?.data?.userRoleId, { // Cookies.set("urie", profile?.data?.data?.userRoleId, {
expires: 1, // expires: 1,
}); // });
Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, { // Cookies.set("masterPoldaId", profile?.data?.data?.masterPoldaId, {
expires: 1, // expires: 1,
}); // });
Cookies.set("ulne", profile?.data?.data?.userLevelId, { // Cookies.set("ulne", profile?.data?.data?.userLevelId, {
expires: 1, // expires: 1,
}); // });
// Cookies.set("urce", profile?.data?.data?.roleCode, { // // Cookies.set("urce", profile?.data?.data?.roleCode, {
// expires: 1, // // expires: 1,
// }); // // });
Cookies.set("email", profile?.data?.data?.email, { // Cookies.set("email", profile?.data?.data?.email, {
expires: 1, // expires: 1,
}); // });
router.push("/admin/dashboard"); // router.push("/admin/dashboard");
Cookies.set("status", "login", { // Cookies.set("status", "login", {
expires: 1, // expires: 1,
}); // });
close(); // close();
} // }
} }
}; };

View File

@ -28,6 +28,7 @@ import {
Autocomplete, Autocomplete,
AutocompleteItem, AutocompleteItem,
Calendar, Calendar,
Checkbox,
Chip, Chip,
ChipProps, ChipProps,
Dropdown, Dropdown,
@ -50,7 +51,7 @@ import {
TableRow, TableRow,
} from "@heroui/react"; } from "@heroui/react";
import Link from "next/link"; import Link from "next/link";
import { Key, useCallback, useEffect, useState } from "react"; import { Key, useCallback, useEffect, useRef, useState } from "react";
import Datepicker from "react-tailwindcss-datepicker"; import Datepicker from "react-tailwindcss-datepicker";
import Swal from "sweetalert2"; import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content"; import withReactContent from "sweetalert2-react-content";
@ -112,6 +113,8 @@ export default function ArticleTable() {
endDate: null, endDate: null,
}); });
const [selectedArticles, setSelectedArticles] = useState<any>(new Set([]));
const [articleDate, setArticleDate] = useState<{ const [articleDate, setArticleDate] = useState<{
startDate: any; startDate: any;
endDate: any; endDate: any;
@ -283,27 +286,66 @@ export default function ArticleTable() {
} }
}; };
const selectedArticlesRef = useRef(selectedArticles);
const articlesRef = useRef(article);
useEffect(() => {
selectedArticlesRef.current = selectedArticles;
articlesRef.current = article;
}, [selectedArticles, article]);
const doBulkDelete = useCallback(() => {
console.log("issame", Array.from(selectedArticlesRef.current));
const now = Array.from(selectedArticlesRef.current);
if (now.length < 1) {
error("Pilih Article");
return false;
}
const isAll = now.join("") === "all";
MySwal.fire({
title: "Hapus Artikel yang Dipilih?",
icon: "warning",
showCancelButton: true,
cancelButtonColor: "#3085d6",
confirmButtonColor: "#d33",
confirmButtonText: "Hapus",
}).then((result) => {
if (result.isConfirmed) {
if (isAll) {
const temp = [];
for (const element of articlesRef.current) {
temp.push(String(element.id));
}
deleteBulkProcess(temp);
} else {
deleteBulkProcess(now as string[]);
}
}
});
}, []);
const deleteBulkProcess = async (data: string[]) => {
loading();
for (const element of data) {
const resDelete = await deleteArticle(element);
}
close();
success("Berhasil Hapus");
setPage(1);
initState();
};
const renderCell = useCallback( const renderCell = useCallback(
(article: any, columnKey: Key) => { (article: any, columnKey: Key) => {
const cellValue = article[columnKey as keyof any]; const cellValue = article[columnKey as keyof any];
switch (columnKey) { switch (columnKey) {
case "isPublish": case "isPublish":
return ( return <p>{article.isPublish ? "Publish" : "Draft"}</p>;
// <Chip
// className="capitalize "
// color={statusColorMap[article.status]}
// size="lg"
// variant="flat"
// >
// <div className="flex flex-row items-center gap-2 justify-center">
// {article.status}
// </div>
// </Chip>
<p>{article.isPublish ? "Publish" : "Draft"}</p>
);
case "isBanner": case "isBanner":
return <p>{article.isBanner ? "Ya" : "Tidak"}</p>; return <p>{article.isBanner ? "Ya" : "Tidak"}</p>;
case "createdAt": case "createdAt":
return <p>{convertDateFormat(article.createdAt)}</p>; return <p>{convertDateFormat(article.createdAt)}</p>;
case "category": case "category":
@ -393,6 +435,23 @@ export default function ArticleTable() {
</> </>
)} )}
</DropdownItem> </DropdownItem>
<DropdownItem
key="deleteBulk"
onPress={doBulkDelete}
className={roleId && Number(roleId) < 3 ? "" : "hidden"}
>
{roleId && Number(roleId) < 3 && (
<>
{" "}
<DeleteIcon
color="red"
size={18}
className="inline ml-1 mr-2 mb-1"
/>
Bulk Delete
</>
)}
</DropdownItem>
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
</div> </div>
@ -402,7 +461,7 @@ export default function ArticleTable() {
return cellValue; return cellValue;
} }
}, },
[article, page] [article, page, selectedArticles]
); );
let typingTimer: NodeJS.Timeout; let typingTimer: NodeJS.Timeout;
@ -492,30 +551,6 @@ export default function ArticleTable() {
placeholder="Kategori..." placeholder="Kategori..."
name="sub-module" name="sub-module"
options={categories} options={categories}
// styles={{
// control: (base) => ({
// ...base,
// width: "100%",
// overflowX: "auto",
// }),
// valueContainer: (base) => ({
// ...base,
// display: "flex",
// flexWrap: "nowrap",
// overflowX: "auto",
// whiteSpace: "nowrap",
// gap: "4px",
// }),
// multiValue: (base) => ({
// ...base,
// whiteSpace: "nowrap",
// flexShrink: 0,
// }),
// multiValueLabel: (base) => ({
// ...base,
// whiteSpace: "nowrap",
// }),
// }}
/> />
</div> </div>
{roleId && Number(roleId) < 3 && ( {roleId && Number(roleId) < 3 && (
@ -635,6 +670,9 @@ export default function ArticleTable() {
wrapper: wrapper:
"min-h-[50px] bg-transpararent text-black dark:text-white ", "min-h-[50px] bg-transpararent text-black dark:text-white ",
}} }}
selectionMode={roleId && Number(roleId) < 3 ? "multiple" : "none"}
selectedKeys={selectedArticles}
onSelectionChange={setSelectedArticles}
> >
<TableHeader <TableHeader
columns={ columns={