diff --git a/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx b/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx index 866579b5..a7094d30 100644 --- a/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/detail/component/column.tsx @@ -89,7 +89,8 @@ const columns: ColumnDef[] = [ cell: ({ row, table }) => { const original = row.original; - const isValid = original.isValid; + // const isValid = original.isValid; + const isRelevant = original.isRelevant; const link = original.link; const updateRow = (data: Partial) => { @@ -99,10 +100,10 @@ const columns: ColumnDef[] = [ const handleValid = async () => { try { await validateMediaLink(original.id, true); - updateRow({ - isValid: true, + isRelevant: true, }); + table.options.meta?.refetchData?.(); } catch (err: any) { toast.error(err.message); } @@ -113,8 +114,9 @@ const columns: ColumnDef[] = [ await validateMediaLink(original.id, false); updateRow({ - isValid: false, + isRelevant: false, }); + table.options.meta?.refetchData?.(); } catch (err: any) { toast.error(err.message); } @@ -124,24 +126,55 @@ const columns: ColumnDef[] = [ return -; } - if (isValid === true) { + if (isRelevant === true) { return ( ); } return (
- -
diff --git a/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx b/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx index fa0ae7c0..670d9269 100644 --- a/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/detail/component/table.tsx @@ -124,6 +124,9 @@ const NewsDetailTable = () => { ) ); }, + refetchData: () => { + fetchData(); + }, }, state: { sorting, @@ -163,7 +166,7 @@ const NewsDetailTable = () => { pageIndex: 0, pageSize: Number(showData), }); - }, [page, showData]); + }, [page, showData, id]); async function fetchData() { try { diff --git a/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx b/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx index a5aa31cb..bcee9b65 100644 --- a/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx +++ b/app/[locale]/(protected)/admin/media-tracking/results/component/column.tsx @@ -52,32 +52,34 @@ const columns: ColumnDef[] = [ header: "Judul", cell: ({ row }) => {row.getValue("title")}, }, - // { - // accessorKey: "resultTotal", - // header: () =>
Jumlah Amplifikasi
, - // cell: ({ row }) => { - // const value = row.getValue("resultTotal") as number | string | null; + { + accessorKey: "resultTotal", + header: () =>
Total Artikel
, + cell: ({ row }) => { + const value = row.getValue("resultTotal") as number | string | null; - // const finalValue = - // value === null || value === undefined || value === "" - // ? 0 - // : Number(value); + const finalValue = + value === null || value === undefined || value === "" + ? 0 + : Number(value); - // return
{finalValue}
; - // }, - // }, + return
{finalValue}
; + }, + }, { accessorKey: "amplification", header: () =>
Jumlah Amplifikasi
, cell: ({ row }) => { - const totalRaw = row.getValue("amplification") as number | string | null; + const raw = row.getValue("amplification") as string | null; - const total = - totalRaw === null || totalRaw === undefined || totalRaw === "" - ? 0 - : Number(totalRaw); + let total = 0; + let invalidTotal = 0; - const invalidTotal = 0; + if (raw && typeof raw === "string") { + const parts = raw.split("/").map((v) => v.trim()); + total = Number(parts[0]) || 0; + invalidTotal = Number(parts[1]) || 0; + } return (
diff --git a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx index 70c37246..6eaefdc1 100644 --- a/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx +++ b/app/[locale]/(protected)/contributor/agenda-setting/event-modal.tsx @@ -891,7 +891,6 @@ const EventModal = ({ const resCsrf = await getCsrfToken(); const csrfToken = resCsrf?.data?.token; - // console.log("CSRF TOKEN : ", csrfToken); const headers = { "X-XSRF-TOKEN": csrfToken, }; diff --git a/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx b/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx index 7141b761..8f8f9072 100644 --- a/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx +++ b/app/[locale]/(protected)/contributor/task-ta/components/columns.tsx @@ -22,7 +22,7 @@ import withReactContent from "sweetalert2-react-content"; import Swal from "sweetalert2"; import { useTranslations } from "next-intl"; -const useTableColumns = (activeTab: "ta" | "daily" | "special") => { +const useTableColumns = (activeTab: "ta" | "daily" | "special" |"mabes-koor") => { const t = useTranslations("Table"); const columns: ColumnDef[] = [ { diff --git a/app/[locale]/(protected)/contributor/task-ta/components/task-ta-table.tsx b/app/[locale]/(protected)/contributor/task-ta/components/task-ta-table.tsx index 7c91b7cf..590eba20 100644 --- a/app/[locale]/(protected)/contributor/task-ta/components/task-ta-table.tsx +++ b/app/[locale]/(protected)/contributor/task-ta/components/task-ta-table.tsx @@ -2,7 +2,6 @@ import * as React from "react"; import { - ColumnDef, ColumnFiltersState, PaginationState, SortingState, @@ -14,8 +13,8 @@ import { getSortedRowModel, useReactTable, } from "@tanstack/react-table"; -import { Button } from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; import { Table, TableBody, @@ -24,46 +23,47 @@ import { TableHeader, TableRow, } from "@/components/ui/table"; -import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; -import { - ChevronDown, - ChevronLeft, - ChevronRight, - Eye, - MoreVertical, - Search, - SquarePen, - Trash2, - TrendingDown, - TrendingUp, -} from "lucide-react"; -import { cn } from "@/lib/utils"; import { DropdownMenu, DropdownMenuContent, - DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Input } from "@/components/ui/input"; import { InputGroup, InputGroupText } from "@/components/ui/input-group"; -import { paginationBlog } from "@/service/blog/blog"; -import { ticketingPagination } from "@/service/ticketing/ticketing"; -import { Badge } from "@/components/ui/badge"; -import { useRouter, useSearchParams } from "next/navigation"; -import TablePagination from "@/components/table/table-pagination"; -import columns from "./columns"; -import { listTask, listTaskMabesForTa, listTaskTa } from "@/service/task"; import { Label } from "@/components/ui/label"; -import { format } from "date-fns"; -import { useTranslations } from "next-intl"; -import useTableColumns from "./columns"; +import TablePagination from "@/components/table/table-pagination"; -const TaskTaTable = () => { +import { Search, ChevronDown } from "lucide-react"; +import { format } from "date-fns"; +import { useRouter, useSearchParams } from "next/navigation"; +import { useTranslations } from "next-intl"; + +import { getCookiesDecrypt } from "@/lib/utils"; +import { listTask, listTaskTa } from "@/service/task"; + +import useTableColumns from "./columns"; // kamu sudah punya + +type ActiveTab = "ta" | "daily" | "special" | "mabes-koor"; + +const MABES_LEVEL_ID = 216; +const APPROVER_ROLE_ID = 3; + +export default function TaskTaTable() { const router = useRouter(); const searchParams = useSearchParams(); const t = useTranslations("AnalyticsDashboard"); + + // ✅ user identity from cookies + const userLevelId = Number(getCookiesDecrypt("ulie")); + const roleId = Number(getCookiesDecrypt("urie")); + const userId = Number(getCookiesDecrypt("uie")); + + const isMabesApprover = + userLevelId === MABES_LEVEL_ID && roleId === APPROVER_ROLE_ID; + + // table states const [dataTable, setDataTable] = React.useState([]); const [totalData, setTotalData] = React.useState(1); const [sorting, setSorting] = React.useState([]); @@ -73,24 +73,27 @@ const TaskTaTable = () => { const [columnVisibility, setColumnVisibility] = React.useState({}); const [rowSelection, setRowSelection] = React.useState({}); + const [showData, setShowData] = React.useState("10"); const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: Number(showData), }); - const [activeTab, setActiveTab] = React.useState<"ta" | "daily" | "special">( - "ta" + + const [activeTab, setActiveTab] = React.useState( + isMabesApprover ? "mabes-koor" : "ta" ); const [statusFilter, setStatusFilter] = React.useState([]); const [dateFilter, setDateFilter] = React.useState(""); - const [endDate, setEndDate] = React.useState(""); const [filterByCode, setFilterByCode] = React.useState(""); + const [search, setSearch] = React.useState(""); + const [page, setPage] = React.useState(1); const [totalPage, setTotalPage] = React.useState(1); - const [limit, setLimit] = React.useState(10); - const [isSpecificAttention, setIsSpecificAttention] = React.useState(true); - const [search, setSearch] = React.useState(""); + + // ✅ columns based on tab const columns = useTableColumns(activeTab); + const table = useReactTable({ data: dataTable, columns, @@ -114,17 +117,15 @@ const TaskTaTable = () => { React.useEffect(() => { const pageFromUrl = searchParams?.get("page"); - if (pageFromUrl) { - setPage(Number(pageFromUrl)); - } + if (pageFromUrl) setPage(Number(pageFromUrl)); }, [searchParams]); React.useEffect(() => { fetchData(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ page, showData, - isSpecificAttention, search, dateFilter, filterByCode, @@ -138,7 +139,7 @@ const TaskTaTable = () => { : ""; try { - let res; + let res: any; if (activeTab === "ta") { res = await listTaskTa( @@ -150,7 +151,9 @@ const TaskTaTable = () => { "atensi-khusus", statusFilter ); - } else if (activeTab === "daily") { + } + + if (activeTab === "daily") { res = await listTaskTa( page - 1, search, @@ -160,7 +163,9 @@ const TaskTaTable = () => { "tugas-harian", statusFilter ); - } else if (activeTab === "special") { + } + + if (activeTab === "special") { res = await listTask( page - 1, search, @@ -172,19 +177,72 @@ const TaskTaTable = () => { ); } + // ✅ TAB BARU: khusus Mabes Approver + if (activeTab === "mabes-koor") { + // kalau bukan Mabes Approver, jangan fetch + if (!isMabesApprover) { + setDataTable([]); + setTotalData(0); + setTotalPage(0); + return; + } + + // NOTE: backend endpoint harus return tasks mabes -> koorkurator + res = await listTaskTa( + page - 1, + search, + showData, + filterByCode, + formattedStartDate, + "atensi-khusus", + statusFilter + ); + } + let contentData = res?.data?.data?.content || []; - // ⛔ Jika upload belum selesai → sembunyikan task baru + // ⛔ blok task baru kalau upload belum selesai (fitur kamu) const isUploadingTA = localStorage.getItem("TA_UPLOAD_IN_PROGRESS") === "true"; - if (isUploadingTA) { const now = new Date(); - // Filter task yg dibuat < 5 menit terakhir (belum selesai upload) contentData = contentData.filter((item: any) => { const created = new Date(item.createdAt); const diff = now.getTime() - created.getTime(); - return diff > 5 * 60 * 1000; // lebih dari 5 menit + return diff > 5 * 60 * 1000; + }); + } + + // ✅ OPTIONAL SAFETY FILTER (kalau backend belum 100% benar) + // sesuaikan field names sesuai response kamu + // if (activeTab === "mabes-koor") { + // contentData = contentData.filter((item: any) => { + // const createdByLevelName = + // item?.createdByLevelName || item?.createdByLevel?.name; + // const assignedToLevelName = + // item?.assignedToLevelName || item?.assignedToLevel?.name; + + // // minimal filter: + // return ( + // String(createdByLevelName || "") + // .toUpperCase() + // .includes("MABES") && + // String(assignedToLevelName || "") + // .toUpperCase() + // .includes("KOOR") + // ); + // }); + // } + if (activeTab === "mabes-koor") { + contentData = contentData.filter((item: any) => { + const createdByLevel = item?.createdBy?.userLevel?.name || ""; + + const assignedUsers = String(item?.assignedToUsers || ""); + + return ( + /MABES/i.test(createdByLevel) && + assignedUsers.split(",").includes("464") + ); }); } @@ -193,153 +251,50 @@ const TaskTaTable = () => { }); setDataTable(contentData); - setTotalData(res?.data?.data?.totalElements); - setTotalPage(res?.data?.data?.totalPages); + setTotalData(res?.data?.data?.totalElements || 0); + setTotalPage(res?.data?.data?.totalPages || 0); } catch (error) { console.error("Error fetching tasks:", error); + setDataTable([]); + setTotalData(0); + setTotalPage(0); } } - // async function fetchData() { - // const formattedStartDate = dateFilter - // ? format(new Date(dateFilter), "yyyy-MM-dd") - // : ""; - - // try { - // let res; - - // if (activeTab === "ta") { - // res = await listTaskTa( - // page - 1, - // search, - // showData, - // filterByCode, - // formattedStartDate, - // "atensi-khusus", - // statusFilter - // ); - // } else if (activeTab === "daily") { - // res = await listTaskTa( - // page - 1, - // search, - // showData, - // filterByCode, - // formattedStartDate, - // "tugas-harian", - // statusFilter - // ); - // } else if (activeTab === "special") { - // res = await listTask( - // page - 1, - // search, - // showData, - // filterByCode, - // formattedStartDate, - // "atensi-khusus", - // statusFilter - // ); - // } - - // const data = res?.data?.data; - // const contentData = data?.content || []; - - // contentData.forEach((item: any, index: number) => { - // item.no = (page - 1) * Number(showData) + index + 1; - // }); - - // setDataTable(contentData); - // setTotalData(data?.totalElements); - // setTotalPage(data?.totalPages); - // } catch (error) { - // console.error("Error fetching tasks:", error); - // } - // } - - // async function fetchData() { - // const formattedStartDate = dateFilter - // ? format(new Date(dateFilter), "yyyy-MM-dd") - // : ""; - // try { - // const res = isSpecificAttention - // ? await listTaskTa( - // page - 1, - // search, - // showData, - // filterByCode, - // formattedStartDate, - // "atensi-khusus", - // statusFilter - // ) - // : await listTask( - // page - 1, - // search, - // showData, - // filterByCode, - // formattedStartDate, - // "atensi-khusus", - // statusFilter - // ); - - // const data = res?.data?.data; - // const contentData = data?.content; - - // // let contentDataFilter = res?.data?.data?.content || []; - - // // Filter berdasarkan status - // // contentDataFilter = contentDataFilter.filter((item: any) => { - // // const isSelesai = statusFilter.includes(1) ? item.isDone : true; - // // const isAktif = statusFilter.includes(2) ? item.isActive : true; - // // return isSelesai && isAktif; - // // }); - - // contentData.forEach((item: any, index: number) => { - // item.no = (page - 1) * Number(showData) + index + 1; - // }); - - // console.log("contentData : ", contentData); - - // setDataTable(contentData); - // setTotalData(data?.totalElements); - // setTotalPage(data?.totalPages); - // } catch (error) { - // console.error("Error fetching tasks:", error); - // } - // } - const handleSearch = (e: React.ChangeEvent) => { - setFilterByCode(e.target.value); - setSearch(e.target.value); - table.getColumn("judul")?.setFilterValue(e.target.value); + const value = e.target.value; + setFilterByCode(value); + setSearch(value); + table.getColumn("judul")?.setFilterValue(value); }; function handleStatusCheckboxChange(value: number) { setStatusFilter((prev) => - prev.includes(value) - ? prev.filter((status) => status !== value) - : [...prev, value] + prev.includes(value) ? prev.filter((s) => s !== value) : [...prev, value] ); } - // const handleSearchFilterByCode = (e: React.ChangeEvent) => { - // const value = e.target.value; - // console.log("code :", value); - // setFilterByCode(value); - // fetchData(); - // }; - return (
-
-
-
-
+
@@ -424,14 +354,14 @@ const TaskTaTable = () => {
-
+
@@ -461,6 +391,7 @@ const TaskTaTable = () => {
+ + {

Filter

+
{ className="max-w-sm" />
- {/*
- - -
*/} +
{ {t("done", { defaultValue: "Done" })}
+
{
- {/*
- ) => - table.getColumn("status")?.setFilterValue(event.target.value) - } - className="max-w-sm " - /> -
*/}
+ {table.getHeaderGroups().map((headerGroup) => ( @@ -555,6 +470,7 @@ const TaskTaTable = () => { ))} + {table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( @@ -579,6 +495,7 @@ const TaskTaTable = () => { )}
+ { />
); -}; +} -export default TaskTaTable; +// "use client"; + +// import * as React from "react"; +// import { +// ColumnDef, +// ColumnFiltersState, +// PaginationState, +// SortingState, +// VisibilityState, +// flexRender, +// getCoreRowModel, +// getFilteredRowModel, +// getPaginationRowModel, +// getSortedRowModel, +// useReactTable, +// } from "@tanstack/react-table"; +// import { Button } from "@/components/ui/button"; + +// import { +// Table, +// TableBody, +// TableCell, +// TableHead, +// TableHeader, +// TableRow, +// } from "@/components/ui/table"; +// import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +// import { +// ChevronDown, +// ChevronLeft, +// ChevronRight, +// Eye, +// MoreVertical, +// Search, +// SquarePen, +// Trash2, +// TrendingDown, +// TrendingUp, +// } from "lucide-react"; +// import { cn } from "@/lib/utils"; +// import { +// DropdownMenu, +// DropdownMenuContent, +// DropdownMenuItem, +// DropdownMenuRadioGroup, +// DropdownMenuRadioItem, +// DropdownMenuTrigger, +// } from "@/components/ui/dropdown-menu"; +// import { Input } from "@/components/ui/input"; +// import { InputGroup, InputGroupText } from "@/components/ui/input-group"; +// import { paginationBlog } from "@/service/blog/blog"; +// import { ticketingPagination } from "@/service/ticketing/ticketing"; +// import { Badge } from "@/components/ui/badge"; +// import { useRouter, useSearchParams } from "next/navigation"; +// import TablePagination from "@/components/table/table-pagination"; +// import columns from "./columns"; +// import { listTask, listTaskMabesForTa, listTaskTa } from "@/service/task"; +// import { Label } from "@/components/ui/label"; +// import { format } from "date-fns"; +// import { useTranslations } from "next-intl"; +// import useTableColumns from "./columns"; + +// const TaskTaTable = () => { +// const router = useRouter(); +// const searchParams = useSearchParams(); +// const t = useTranslations("AnalyticsDashboard"); +// const [dataTable, setDataTable] = React.useState([]); +// const [totalData, setTotalData] = React.useState(1); +// const [sorting, setSorting] = React.useState([]); +// const [columnFilters, setColumnFilters] = React.useState( +// [] +// ); +// const [columnVisibility, setColumnVisibility] = +// React.useState({}); +// const [rowSelection, setRowSelection] = React.useState({}); +// const [showData, setShowData] = React.useState("10"); +// const [pagination, setPagination] = React.useState({ +// pageIndex: 0, +// pageSize: Number(showData), +// }); +// const [activeTab, setActiveTab] = React.useState<"ta" | "daily" | "special">( +// "ta" +// ); +// const [statusFilter, setStatusFilter] = React.useState([]); +// const [dateFilter, setDateFilter] = React.useState(""); +// const [endDate, setEndDate] = React.useState(""); +// const [filterByCode, setFilterByCode] = React.useState(""); +// const [page, setPage] = React.useState(1); +// const [totalPage, setTotalPage] = React.useState(1); +// const [limit, setLimit] = React.useState(10); +// const [isSpecificAttention, setIsSpecificAttention] = React.useState(true); +// const [search, setSearch] = React.useState(""); +// const columns = useTableColumns(activeTab); +// const table = useReactTable({ +// data: dataTable, +// columns, +// onSortingChange: setSorting, +// onColumnFiltersChange: setColumnFilters, +// getCoreRowModel: getCoreRowModel(), +// getPaginationRowModel: getPaginationRowModel(), +// getSortedRowModel: getSortedRowModel(), +// getFilteredRowModel: getFilteredRowModel(), +// onColumnVisibilityChange: setColumnVisibility, +// onRowSelectionChange: setRowSelection, +// onPaginationChange: setPagination, +// state: { +// sorting, +// columnFilters, +// columnVisibility, +// rowSelection, +// pagination, +// }, +// }); + +// React.useEffect(() => { +// const pageFromUrl = searchParams?.get("page"); +// if (pageFromUrl) { +// setPage(Number(pageFromUrl)); +// } +// }, [searchParams]); + +// React.useEffect(() => { +// fetchData(); +// }, [ +// page, +// showData, +// isSpecificAttention, +// search, +// dateFilter, +// filterByCode, +// statusFilter, +// activeTab, +// ]); + +// async function fetchData() { +// const formattedStartDate = dateFilter +// ? format(new Date(dateFilter), "yyyy-MM-dd") +// : ""; + +// try { +// let res; + +// if (activeTab === "ta") { +// res = await listTaskTa( +// page - 1, +// search, +// showData, +// filterByCode, +// formattedStartDate, +// "atensi-khusus", +// statusFilter +// ); +// } else if (activeTab === "daily") { +// res = await listTaskTa( +// page - 1, +// search, +// showData, +// filterByCode, +// formattedStartDate, +// "tugas-harian", +// statusFilter +// ); +// } else if (activeTab === "special") { +// res = await listTask( +// page - 1, +// search, +// showData, +// filterByCode, +// formattedStartDate, +// "atensi-khusus", +// statusFilter +// ); +// } + +// let contentData = res?.data?.data?.content || []; + +// // ⛔ Jika upload belum selesai → sembunyikan task baru +// const isUploadingTA = +// localStorage.getItem("TA_UPLOAD_IN_PROGRESS") === "true"; + +// if (isUploadingTA) { +// const now = new Date(); +// // Filter task yg dibuat < 5 menit terakhir (belum selesai upload) +// contentData = contentData.filter((item: any) => { +// const created = new Date(item.createdAt); +// const diff = now.getTime() - created.getTime(); +// return diff > 5 * 60 * 1000; // lebih dari 5 menit +// }); +// } + +// contentData.forEach((item: any, index: number) => { +// item.no = (page - 1) * Number(showData) + index + 1; +// }); + +// setDataTable(contentData); +// setTotalData(res?.data?.data?.totalElements); +// setTotalPage(res?.data?.data?.totalPages); +// } catch (error) { +// console.error("Error fetching tasks:", error); +// } +// } + +// // async function fetchData() { +// // const formattedStartDate = dateFilter +// // ? format(new Date(dateFilter), "yyyy-MM-dd") +// // : ""; + +// // try { +// // let res; + +// // if (activeTab === "ta") { +// // res = await listTaskTa( +// // page - 1, +// // search, +// // showData, +// // filterByCode, +// // formattedStartDate, +// // "atensi-khusus", +// // statusFilter +// // ); +// // } else if (activeTab === "daily") { +// // res = await listTaskTa( +// // page - 1, +// // search, +// // showData, +// // filterByCode, +// // formattedStartDate, +// // "tugas-harian", +// // statusFilter +// // ); +// // } else if (activeTab === "special") { +// // res = await listTask( +// // page - 1, +// // search, +// // showData, +// // filterByCode, +// // formattedStartDate, +// // "atensi-khusus", +// // statusFilter +// // ); +// // } + +// // const data = res?.data?.data; +// // const contentData = data?.content || []; + +// // contentData.forEach((item: any, index: number) => { +// // item.no = (page - 1) * Number(showData) + index + 1; +// // }); + +// // setDataTable(contentData); +// // setTotalData(data?.totalElements); +// // setTotalPage(data?.totalPages); +// // } catch (error) { +// // console.error("Error fetching tasks:", error); +// // } +// // } + +// // async function fetchData() { +// // const formattedStartDate = dateFilter +// // ? format(new Date(dateFilter), "yyyy-MM-dd") +// // : ""; +// // try { +// // const res = isSpecificAttention +// // ? await listTaskTa( +// // page - 1, +// // search, +// // showData, +// // filterByCode, +// // formattedStartDate, +// // "atensi-khusus", +// // statusFilter +// // ) +// // : await listTask( +// // page - 1, +// // search, +// // showData, +// // filterByCode, +// // formattedStartDate, +// // "atensi-khusus", +// // statusFilter +// // ); + +// // const data = res?.data?.data; +// // const contentData = data?.content; + +// // // let contentDataFilter = res?.data?.data?.content || []; + +// // // Filter berdasarkan status +// // // contentDataFilter = contentDataFilter.filter((item: any) => { +// // // const isSelesai = statusFilter.includes(1) ? item.isDone : true; +// // // const isAktif = statusFilter.includes(2) ? item.isActive : true; +// // // return isSelesai && isAktif; +// // // }); + +// // contentData.forEach((item: any, index: number) => { +// // item.no = (page - 1) * Number(showData) + index + 1; +// // }); + +// // console.log("contentData : ", contentData); + +// // setDataTable(contentData); +// // setTotalData(data?.totalElements); +// // setTotalPage(data?.totalPages); +// // } catch (error) { +// // console.error("Error fetching tasks:", error); +// // } +// // } + +// const handleSearch = (e: React.ChangeEvent) => { +// setFilterByCode(e.target.value); +// setSearch(e.target.value); +// table.getColumn("judul")?.setFilterValue(e.target.value); +// }; + +// function handleStatusCheckboxChange(value: number) { +// setStatusFilter((prev) => +// prev.includes(value) +// ? prev.filter((status) => status !== value) +// : [...prev, value] +// ); +// } + +// // const handleSearchFilterByCode = (e: React.ChangeEvent) => { +// // const value = e.target.value; +// // console.log("code :", value); +// // setFilterByCode(value); +// // fetchData(); +// // }; + +// return ( +//
+//
+//
+//
+//
+// +//
+//
+//
+//
+//
+//
+// +// +// +// +// +// +//
+ +//
+//
+//
+// +// +// +// +// +// +// +// 1 - 10 Data +// +// +// 1 - 50 Data +// +// +// 1 - 100 Data +// +// +// 1 - 250 Data +// +// +// +// +//
+// +// +// +// +// +//
+//

Filter

+//
+//
+// +// setDateFilter(e.target.value)} +// className="max-w-sm" +// /> +//
+// {/*
+// +// +//
*/} +// +//
+// handleStatusCheckboxChange(1)} +// /> +// +//
+//
+// handleStatusCheckboxChange(2)} +// /> +// +//
+//
+//
+//
+//
+// {/*
+// ) => +// table.getColumn("status")?.setFilterValue(event.target.value) +// } +// className="max-w-sm " +// /> +//
*/} +//
+// +// +// {table.getHeaderGroups().map((headerGroup) => ( +// +// {headerGroup.headers.map((header) => ( +// +// {header.isPlaceholder +// ? null +// : flexRender( +// header.column.columnDef.header, +// header.getContext() +// )} +// +// ))} +// +// ))} +// +// +// {table.getRowModel().rows?.length ? ( +// table.getRowModel().rows.map((row) => ( +// +// {row.getVisibleCells().map((cell) => ( +// +// {flexRender(cell.column.columnDef.cell, cell.getContext())} +// +// ))} +// +// )) +// ) : ( +// +// +// No results. +// +// +// )} +// +//
+// +//
+// ); +// }; + +// export default TaskTaTable; diff --git a/components/form/schedule/live-report-detail-form.tsx b/components/form/schedule/live-report-detail-form.tsx index 0013db48..c1e6ee02 100644 --- a/components/form/schedule/live-report-detail-form.tsx +++ b/components/form/schedule/live-report-detail-form.tsx @@ -75,6 +75,7 @@ interface Detail { youtubeUrl: string; needApprovalFrom: number; uploadedById: number; + statusId?: number; } export default function FormDetailLiveReport() { @@ -176,21 +177,68 @@ export default function FormDetailLiveReport() { statusId: Number(status), message: description, isPublish: status === "2", - placements: schedulePlacements?.filter((val) => val != "all")?.join(","), + placements: schedulePlacements?.filter((val) => val !== "all")?.join(","), }; loading(); const response = await postApprovalSchedule(data); close(); setModalOpen(false); + if (response?.error) { - error(response?.message); - return false; + error(response?.message || "Gagal menyimpan data"); + return; } - initState(); - return false; + + // ✅ update UI lokal (optimistic) + setDetail((prev) => + prev + ? { + ...prev, + statusId: Number(status), + } + : prev, + ); + + Swal.fire({ + icon: "success", + title: "Berhasil", + text: + status === "2" + ? "Jadwal berhasil disetujui" + : status === "3" + ? "Jadwal dikembalikan untuk revisi" + : "Jadwal berhasil ditolak", + confirmButtonText: "OK", + }).then((result) => { + if (result.isConfirmed) { + router.push("/contributor/schedule/live-report"); + } + }); } + // async function save() { + // const data = { + // scheduleId: Number(id), + // statusId: Number(status), + // message: description, + // isPublish: status === "2", + // placements: schedulePlacements?.filter((val) => val != "all")?.join(","), + // }; + + // loading(); + // const response = await postApprovalSchedule(data); + // close(); + // setModalOpen(false); + + // if (response?.error) { + // error(response?.message); + // return false; + // } + // initState(); + // return false; + // } + const [schedulePlacements, setSchedulePlacements] = useState([]); const setupPlacement = (placement: string, checked: boolean) => { @@ -224,6 +272,15 @@ export default function FormDetailLiveReport() { setSchedulePlacements(temp); }; + const isCreator = Number(detail?.uploadedById) === Number(userId); + + const isApprover = + Number(detail?.needApprovalFrom) === Number(userLevelId) && + Number(userLevelNumber) < 2; + + const isAlreadyProcessed = + detail?.statusId === 2 || detail?.statusId === 3 || detail?.statusId === 4; + return (
@@ -284,7 +341,7 @@ export default function FormDetailLiveReport() { variant={"outline"} className={cn( "w-[280px] lg:w-[250px] justify-start text-left font-normal px-0 md:px-0 lg:px-4", - !date && "text-muted-foreground" + !date && "text-muted-foreground", )} > @@ -494,7 +551,38 @@ export default function FormDetailLiveReport() { - {Number(detail?.needApprovalFrom) == Number(userLevelId) && + {(isApprover || isCreator) && !isAlreadyProcessed && ( +
+ + + + + +
+ )} + + {/* {Number(detail?.needApprovalFrom) == Number(userLevelId) && Number(userLevelNumber) < 2 ? ( Number(detail?.uploadedById) == Number(userId) ? ( "" @@ -527,13 +615,15 @@ export default function FormDetailLiveReport() { ) ) : ( "" - )} + )} */}
- {t("leave-comment", { defaultValue: "Leave Comment" })} + + {t("leave-comment", { defaultValue: "Leave Comment" })} +

@@ -544,15 +634,15 @@ export default function FormDetailLiveReport() { status === "2" ? "text-primary" : status === "3" - ? "text-warning" - : "text-destructive" + ? "text-warning" + : "text-destructive" } > {status === "2" ? "Disetujui" : status === "3" - ? "Revisi" - : "Ditolak"} + ? "Revisi" + : "Ditolak"}

{status === "2" && ( diff --git a/components/form/task-ta/task-ta-form.tsx b/components/form/task-ta/task-ta-form.tsx index 2c0c217a..ddd701f5 100644 --- a/components/form/task-ta/task-ta-form.tsx +++ b/components/form/task-ta/task-ta-form.tsx @@ -43,7 +43,7 @@ import { getCsrfToken } from "@/service/auth"; import { loading } from "@/lib/swal"; import { useTranslations } from "next-intl"; import dynamic from "next/dynamic"; -import { cn } from "@/lib/utils"; +import { cn, getCookiesDecrypt } from "@/lib/utils"; import { Popover, PopoverContent, @@ -181,6 +181,33 @@ export default function FormTaskTa() { mode: "all", }); + const [profile, setProfile] = useState(null); + const userLevelId = Number(getCookiesDecrypt("ulie")); + const roleId = Number(getCookiesDecrypt("urie")); + const userId = Number(getCookiesDecrypt("uie")); + + const MABES_LEVEL_ID = 216; // userLevelId Mabes Polri + const APPROVER_ROLE_ID = 3; // roleId Approver + const isMabes = userLevelId === MABES_LEVEL_ID; + const isApprover = roleId === APPROVER_ROLE_ID; + + const isMabesApprover = + userLevelId === MABES_LEVEL_ID && roleId === APPROVER_ROLE_ID; + + const shouldHideExpert = isMabes && isApprover; + + useEffect(() => { + async function fetchUserLevel() { + try { + const res = await getUserLevelForAssignments(); + setProfile(res?.data?.data); + } catch (e) { + console.error("Failed fetch user level", e); + } + } + fetchUserLevel(); + }, []); + useEffect(() => { getDataAdditional(); }, []); @@ -352,55 +379,124 @@ export default function FormTaskTa() { // // }); // }; + // const save = async (data: TaskSchema) => { + // const cleanedLinks = links + // .map((link) => link.trim()) + // .filter((link) => link.startsWith("http")); + + // const requestData = { + // ...data, + // // assignedToUsers: handleExpertChange(), + // assignedToUsers: isMabesApprover ? "464" : handleExpertChange(), + // assignmentType: taskType, + // assignmentTypeId: type, + // expertCompetencies: Array.from(selectedCompetencies).join(","), + // attachmentUrl: cleanedLinks, + // }; + + // console.log("FINAL ASSIGNED TO:", { + // isMabesApprover, + // assignedToUsers: isMabesApprover + // ? String(roleId) + // : handleExpertChange(), + // }); + + // const response = await createTaskTa(requestData); + // const id = String(response?.data?.data.id); + + // // Set block table TA + // localStorage.setItem("TA_UPLOAD_IN_PROGRESS", "true"); + + // loading(); // SHOW SWAL LOADING + + // // Kumpulkan semua upload + // const allUploads: Promise[] = []; + + // imageFiles.forEach((item, idx) => + // allUploads.push(uploadResumableFile(idx, id, item, "1", "0")) + // ); + + // videoFiles.forEach((item, idx) => + // allUploads.push(uploadResumableFile(idx, id, item, "2", "0")) + // ); + + // textFiles.forEach((item, idx) => + // allUploads.push(uploadResumableFile(idx, id, item, "3", "0")) + // ); + + // audioFiles.forEach((item, idx) => + // allUploads.push(uploadResumableFile(idx, id, item, "4", "0")) + // ); + + // // Tunggu upload selesai + // await Promise.all(allUploads); + + // // Hapus flag + // localStorage.removeItem("TA_UPLOAD_IN_PROGRESS"); + + // // Close loading + redirect + // successSubmit("/in/contributor/task-ta"); + // }; + const save = async (data: TaskSchema) => { - const cleanedLinks = links - .map((link) => link.trim()) - .filter((link) => link.startsWith("http")); + try { + loading(); - const requestData = { - ...data, - assignedToUsers: handleExpertChange(), - assignmentType: taskType, - assignmentTypeId: type, - expertCompetencies: Array.from(selectedCompetencies).join(","), - attachmentUrl: cleanedLinks, - }; + const cleanedLinks = links + .map((link) => link.trim()) + .filter((link) => link.startsWith("http")); - const response = await createTaskTa(requestData); - const id = String(response?.data?.data.id); + const requestData = { + ...data, + // assignedToUsers: isMabesApprover ? "464" : handleExpertChange(), + assignedToUsers: isMabesApprover ? "464" : handleExpertChange(), + assignmentType: taskType, + assignmentTypeId: type, + expertCompetencies: Array.from(selectedCompetencies).join(","), + attachmentUrl: cleanedLinks, + }; - // Set block table TA - localStorage.setItem("TA_UPLOAD_IN_PROGRESS", "true"); + const response = await createTaskTa(requestData); - loading(); // SHOW SWAL LOADING + if (!response?.data?.data?.id) { + throw new Error("Gagal membuat task"); + } - // Kumpulkan semua upload - const allUploads: Promise[] = []; + const assignmentId = String(response.data.data.id); - imageFiles.forEach((item, idx) => - allUploads.push(uploadResumableFile(idx, id, item, "1", "0")) - ); + const uploads: Promise[] = []; - videoFiles.forEach((item, idx) => - allUploads.push(uploadResumableFile(idx, id, item, "2", "0")) - ); + imageFiles.forEach((file, i) => + uploads.push(uploadResumableFile(i, assignmentId, file, "1", "0")) + ); - textFiles.forEach((item, idx) => - allUploads.push(uploadResumableFile(idx, id, item, "3", "0")) - ); + videoFiles.forEach((file, i) => + uploads.push(uploadResumableFile(i, assignmentId, file, "2", "0")) + ); - audioFiles.forEach((item, idx) => - allUploads.push(uploadResumableFile(idx, id, item, "4", "0")) - ); + textFiles.forEach((file, i) => + uploads.push(uploadResumableFile(i, assignmentId, file, "3", "0")) + ); - // Tunggu upload selesai - await Promise.all(allUploads); + audioFiles.forEach((file, i) => + uploads.push(uploadResumableFile(i, assignmentId, file, "4", "0")) + ); - // Hapus flag - localStorage.removeItem("TA_UPLOAD_IN_PROGRESS"); + await Promise.all(uploads); - // Close loading + redirect - successSubmit("/in/contributor/task-ta"); + successSubmit("/in/contributor/task-ta"); + } catch (err: any) { + console.error("SUBMIT ERROR:", err); + + Swal.fire({ + icon: "error", + title: "Gagal", + text: + err?.response?.data?.message || + err?.message || + "Terjadi kesalahan, data tidak tersimpan", + }); + } }; const onSubmit = (data: TaskSchema) => { @@ -543,46 +639,91 @@ export default function FormTaskTa() { // upload.start(); // } + // function uploadResumableFile( + // idx: number, + // id: string, + // file: any, + // fileTypeId: string, + // duration: string + // ) { + // return new Promise(async (resolve, reject) => { + // const resCsrf = await getCsrfToken(); + // const csrfToken = resCsrf?.data?.token; + + // const upload = new Upload(file, { + // endpoint: `${process.env.NEXT_PUBLIC_API}/assignment-expert/file/upload`, + // headers: { "X-XSRF-TOKEN": csrfToken }, + // retryDelays: [0, 3000, 6000, 12000], + // chunkSize: 20000, + // metadata: { + // assignmentId: id, + // filename: file.name, + // contentType: file.type, + // fileTypeId, + // duration, + // }, + + // onBeforeRequest(req) { + // req.getUnderlyingObject().withCredentials = true; + // }, + + // onError(err) { + // console.error("Upload error:", err); + // reject(err); + // }, + + // onSuccess() { + // console.log("Upload selesai:", file.name); + // resolve(true); + // }, + // }); + + // upload.start(); + // }); + // } + function uploadResumableFile( idx: number, id: string, - file: any, + file: File, fileTypeId: string, duration: string ) { return new Promise(async (resolve, reject) => { - const resCsrf = await getCsrfToken(); - const csrfToken = resCsrf?.data?.token; + try { + const resCsrf = await getCsrfToken(); + const csrfToken = resCsrf?.data?.token; - const upload = new Upload(file, { - endpoint: `${process.env.NEXT_PUBLIC_API}/assignment-expert/file/upload`, - headers: { "X-XSRF-TOKEN": csrfToken }, - retryDelays: [0, 3000, 6000, 12000], - chunkSize: 20000, - metadata: { - assignmentId: id, - filename: file.name, - contentType: file.type, - fileTypeId, - duration, - }, + const upload = new Upload(file, { + endpoint: `${process.env.NEXT_PUBLIC_API}/assignment-expert/file/upload`, + headers: { "X-XSRF-TOKEN": csrfToken }, + retryDelays: [0, 3000, 6000], + chunkSize: 20000, + metadata: { + assignmentId: id, + filename: file.name, + contentType: file.type, + fileTypeId, + duration, + }, - onBeforeRequest(req) { - req.getUnderlyingObject().withCredentials = true; - }, + onBeforeRequest(req) { + req.getUnderlyingObject().withCredentials = true; + }, - onError(err) { - console.error("Upload error:", err); - reject(err); - }, + onError(error) { + reject(error); + }, - onSuccess() { - console.log("Upload selesai:", file.name); - resolve(true); - }, - }); + onSuccess() { + resolve(true); + }, + }); - upload.start(); + upload.start(); + } catch (err) { + reject(err); + } }); } @@ -718,101 +859,109 @@ export default function FormTaskTa() {
-
- -
- {userCompetencies?.map((item: any) => ( -
- handleCompetencyChange(item.id)} - /> - -
- ))} -
-
-
- -
- - - - - - - Daftar Tenaga Ahli - -
- {listExpert?.map((expert: any) => ( -
- -
- ))} + {!isMabesApprover && ( +
+ +
+ {userCompetencies?.map((item: any) => ( +
+ handleCompetencyChange(item.id)} + /> +
- -
-
- {checkedLevels.size > 0 && ( -
- -
- {Array.from(checkedLevels).map((expertId) => { - const expert = listExpert?.find( - (exp: any) => exp.id === expertId - ); - return expert ? ( -
- {expert.fullname} - -
- ) : null; - })} -
+ ))}
- )} -
+
+ )} + {!isMabesApprover && ( +
+ +
+ + + + + + + Daftar Tenaga Ahli + +
+ {listExpert?.map((expert: any) => ( +
+ +
+ ))} +
+
+
+
+ {checkedLevels.size > 0 && ( +
+ +
+ {Array.from(checkedLevels).map((expertId) => { + const expert = listExpert?.find( + (exp: any) => exp.id === expertId + ); + return expert ? ( +
+ {expert.fullname} + +
+ ) : null; + })} +
+
+ )} +
+ )}
handleLinkChange(index, e.target.value) diff --git a/lib/menus.ts b/lib/menus.ts index 3e6edb5c..913d6529 100644 --- a/lib/menus.ts +++ b/lib/menus.ts @@ -168,6 +168,13 @@ export function getMenuList(pathname: string, t: any): Group[] { icon: "heroicons:shopping-cart", children: [], }, + { + href: "/contributor/task-ta", + label: "penugasan TA", + active: pathname.includes("/contributor/task-ta"), + icon: "heroicons:shopping-cart", + children: [], + }, ], }, ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bc89855..194275ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: '@ckeditor/ckeditor5-react': specifier: ^6.2.0 - version: 6.3.0(@ckeditor/ckeditor5-core@46.0.0)(@ckeditor/ckeditor5-editor-multi-root@46.0.0)(@ckeditor/ckeditor5-engine@46.0.0)(@ckeditor/ckeditor5-utils@46.0.0)(@ckeditor/ckeditor5-watchdog@46.0.0)(react@18.3.1) + version: 6.3.0(@ckeditor/ckeditor5-core@47.1.0)(@ckeditor/ckeditor5-editor-multi-root@47.1.0)(@ckeditor/ckeditor5-engine@47.1.0)(@ckeditor/ckeditor5-utils@47.1.0)(@ckeditor/ckeditor5-watchdog@47.1.0)(react@18.3.1) '@dnd-kit/core': specifier: ^6.1.0 version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -223,7 +223,10 @@ importers: version: 8.5.1(embla-carousel@8.5.1) embla-carousel-react: specifier: ^8.1.3 - version: 8.5.1(react@18.3.1) + version: 8.6.0(react@18.3.1) + file-saver: + specifier: ^2.0.5 + version: 2.0.5 framer-motion: specifier: ^11.15.0 version: 11.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -394,7 +397,10 @@ importers: version: 0.9.9(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) wavesurfer.js: specifier: ^7.8.16 - version: 7.8.16 + version: 7.11.0 + xlsx: + specifier: ^0.18.5 + version: 0.18.5 yup: specifier: ^1.6.1 version: 1.6.1 @@ -3061,8 +3067,12 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.3: - resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} ajv@6.12.6: @@ -3336,6 +3346,10 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + chalk@2.3.0: resolution: {integrity: sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==} engines: {node: '>=4'} @@ -3447,8 +3461,12 @@ packages: code-block-writer@12.0.0: resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -3548,6 +3566,11 @@ packages: typescript: optional: true + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + cross-env@7.0.3: resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} @@ -4223,6 +4246,9 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + file-selector@2.1.2: resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} engines: {node: '>= 12'} @@ -4283,8 +4309,16 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - framer-motion@11.15.0: - resolution: {integrity: sha512-MLk8IvZntxOMg7lDBLw2qgTHHv664bYoYmnFTmE0Gm/FW67aOJk0WM3ctMcG+Xhcv+vh5uyyXwxvxhSeJzSe+w==} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + + framer-motion@11.18.2: + resolution: {integrity: sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -6707,8 +6741,12 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - stable-hash@0.0.4: - resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} @@ -7330,10 +7368,22 @@ packages: engines: {node: '>= 8'} hasBin: true + wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -7373,6 +7423,11 @@ packages: utf-8-validate: optional: true + xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + xml-name-validator@5.0.0: resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} engines: {node: '>=18'} @@ -7855,9 +7910,9 @@ snapshots: '@ckeditor/ckeditor5-adapter-ckfinder@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-upload': 46.0.0 - ckeditor5: 46.0.0 + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-upload': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-alignment@41.3.1': dependencies: @@ -7918,15 +7973,13 @@ snapshots: '@ckeditor/ckeditor5-block-quote@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-enter': 46.0.0 - '@ckeditor/ckeditor5-icons': 46.0.0 - '@ckeditor/ckeditor5-typing': 46.0.0 - '@ckeditor/ckeditor5-ui': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - ckeditor5: 46.0.0 - transitivePeerDependencies: - - supports-color + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-enter': 47.1.0 + '@ckeditor/ckeditor5-icons': 47.1.0 + '@ckeditor/ckeditor5-typing': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-bookmark@46.0.0': dependencies: @@ -7991,11 +8044,9 @@ snapshots: '@ckeditor/ckeditor5-cloud-services@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - ckeditor5: 46.0.0 - transitivePeerDependencies: - - supports-color + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-code-block@41.3.1': dependencies: @@ -8062,8 +8113,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-editor-decoupled@46.0.0': dependencies: @@ -8091,18 +8140,36 @@ snapshots: '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-emoji@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-icons': 46.0.0 - '@ckeditor/ckeditor5-mention': 46.0.0 - '@ckeditor/ckeditor5-typing': 46.0.0 - '@ckeditor/ckeditor5-ui': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - ckeditor5: 46.0.0 + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-engine': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 + es-toolkit: 1.39.5 + + '@ckeditor/ckeditor5-editor-multi-root@47.1.0': + dependencies: + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-engine': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 + es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color + + '@ckeditor/ckeditor5-emoji@47.1.0': + dependencies: + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-icons': 47.1.0 + '@ckeditor/ckeditor5-mention': 47.1.0 + '@ckeditor/ckeditor5-typing': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 es-toolkit: 1.39.5 fuzzysort: 3.1.0 transitivePeerDependencies: @@ -8369,18 +8436,16 @@ snapshots: '@ckeditor/ckeditor5-media-embed@46.0.0': dependencies: - '@ckeditor/ckeditor5-clipboard': 46.0.0 - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-engine': 46.0.0 - '@ckeditor/ckeditor5-icons': 46.0.0 - '@ckeditor/ckeditor5-typing': 46.0.0 - '@ckeditor/ckeditor5-ui': 46.0.0 - '@ckeditor/ckeditor5-undo': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - '@ckeditor/ckeditor5-widget': 46.0.0 - ckeditor5: 46.0.0 - transitivePeerDependencies: - - supports-color + '@ckeditor/ckeditor5-clipboard': 47.1.0 + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-engine': 47.1.0 + '@ckeditor/ckeditor5-icons': 47.1.0 + '@ckeditor/ckeditor5-typing': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-undo': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + '@ckeditor/ckeditor5-widget': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-mention@46.0.0': dependencies: @@ -8439,25 +8504,23 @@ snapshots: '@ckeditor/ckeditor5-engine': 46.0.0 ckeditor5: 46.0.0 - '@ckeditor/ckeditor5-react@6.3.0(@ckeditor/ckeditor5-core@46.0.0)(@ckeditor/ckeditor5-editor-multi-root@46.0.0)(@ckeditor/ckeditor5-engine@46.0.0)(@ckeditor/ckeditor5-utils@46.0.0)(@ckeditor/ckeditor5-watchdog@46.0.0)(react@18.3.1)': + '@ckeditor/ckeditor5-react@6.3.0(@ckeditor/ckeditor5-core@47.1.0)(@ckeditor/ckeditor5-editor-multi-root@47.1.0)(@ckeditor/ckeditor5-engine@47.1.0)(@ckeditor/ckeditor5-utils@47.1.0)(@ckeditor/ckeditor5-watchdog@47.1.0)(react@18.3.1)': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-editor-multi-root': 46.0.0 - '@ckeditor/ckeditor5-engine': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - '@ckeditor/ckeditor5-watchdog': 46.0.0 + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-editor-multi-root': 47.1.0 + '@ckeditor/ckeditor5-engine': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + '@ckeditor/ckeditor5-watchdog': 47.1.0 prop-types: 15.8.1 react: 18.3.1 '@ckeditor/ckeditor5-remove-format@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-icons': 46.0.0 - '@ckeditor/ckeditor5-ui': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - ckeditor5: 46.0.0 - transitivePeerDependencies: - - supports-color + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-icons': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-restricted-editing@46.0.0': dependencies: @@ -8499,12 +8562,12 @@ snapshots: '@ckeditor/ckeditor5-source-editing@46.0.0': dependencies: - '@ckeditor/ckeditor5-core': 46.0.0 - '@ckeditor/ckeditor5-icons': 46.0.0 - '@ckeditor/ckeditor5-theme-lark': 46.0.0 - '@ckeditor/ckeditor5-ui': 46.0.0 - '@ckeditor/ckeditor5-utils': 46.0.0 - ckeditor5: 46.0.0 + '@ckeditor/ckeditor5-core': 47.1.0 + '@ckeditor/ckeditor5-icons': 47.1.0 + '@ckeditor/ckeditor5-theme-lark': 47.1.0 + '@ckeditor/ckeditor5-ui': 47.1.0 + '@ckeditor/ckeditor5-utils': 47.1.0 + ckeditor5: 47.1.0 '@ckeditor/ckeditor5-special-characters@46.0.0': dependencies: @@ -8671,8 +8734,6 @@ snapshots: '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0 es-toolkit: 1.39.5 - transitivePeerDependencies: - - supports-color '@csstools/color-helpers@5.0.2': {} @@ -10730,7 +10791,9 @@ snapshots: acorn@8.14.0: {} - agent-base@7.1.3: {} + adler-32@1.3.1: {} + + agent-base@7.1.4: {} ajv@6.12.6: dependencies: @@ -11054,6 +11117,11 @@ snapshots: ccount@2.0.1: {} + cfb@1.2.2: + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + chalk@2.3.0: dependencies: ansi-styles: 3.2.1 @@ -11260,7 +11328,9 @@ snapshots: code-block-writer@12.0.0: {} - collect-v8-coverage@1.0.2: {} + codepage@1.15.0: {} + + collect-v8-coverage@1.0.3: {} color-convert@1.9.3: dependencies: @@ -11353,6 +11423,8 @@ snapshots: optionalDependencies: typescript: 5.7.2 + crc-32@1.2.2: {} + cross-env@7.0.3: dependencies: cross-spawn: 7.0.6 @@ -11884,8 +11956,8 @@ snapshots: '@typescript-eslint/parser': 7.2.0(eslint@8.57.1)(typescript@5.7.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.3(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) @@ -11916,7 +11988,7 @@ snapshots: is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -11931,7 +12003,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.7.2))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@7.2.0(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -12198,6 +12270,8 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-saver@2.0.5: {} + file-selector@2.1.2: dependencies: tslib: 2.8.1 @@ -12253,7 +12327,11 @@ snapshots: dependencies: fetch-blob: 3.2.0 - framer-motion@11.15.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + forwarded@0.2.0: {} + + frac@1.1.2: {} + + framer-motion@11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: motion-dom: 11.14.3 motion-utils: 11.14.3 @@ -15619,7 +15697,15 @@ snapshots: sprintf-js@1.0.3: {} +<<<<<<< HEAD stable-hash@0.0.4: {} +======= + ssf@0.11.2: + dependencies: + frac: 1.1.2 + + stable-hash@0.0.5: {} +>>>>>>> e5e32496aba520aed62e3a73e9e0bcc42eaca928 stack-utils@2.0.6: dependencies: @@ -16398,8 +16484,21 @@ snapshots: dependencies: isexe: 2.0.0 + wmf@1.0.2: {} + word-wrap@1.2.5: {} +<<<<<<< HEAD +======= + word@0.3.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + +>>>>>>> e5e32496aba520aed62e3a73e9e0bcc42eaca928 wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -16423,6 +16522,16 @@ snapshots: ws@8.18.3: {} + xlsx@0.18.5: + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} diff --git a/service/media-tracking/media-tracking.ts b/service/media-tracking/media-tracking.ts index e3874a3b..0841c6b0 100644 --- a/service/media-tracking/media-tracking.ts +++ b/service/media-tracking/media-tracking.ts @@ -2,6 +2,7 @@ import api from "@/src/lib/api"; import { httpGetInterceptor, httpPostInterceptor, + httpPutInterceptor, } from "../http-config/http-interceptor-service"; export async function getMediaTrackingMonitoring(page: number, size: number) { @@ -63,31 +64,41 @@ export async function listDataTracking( ); } - export async function listDataAllNonPagination(search: string) { return await httpGetInterceptor( `media/public/list?enablePage=0&sort=desc&title=${search || ""}` ); } -export const validateMediaLink = async ( - resultId: number, - isRelevant: boolean -) => { - try { - const res = await api.put( - "/media/tracking/monitoring/results/relevant", - { - resultId, - isRelevant, - } - ); +export async function validateMediaLink(resultId: number, isRelevant: boolean) { + const url = "media/tracking/monitoring/results/relevant"; - return res.data; - } catch (error: any) { - throw new Error( - error?.response?.data?.messages?.[0] || - "Gagal memperbarui status relevansi" - ); - } -}; \ No newline at end of file + const payload = { + resultId, + isRelevant, + }; + + return httpPutInterceptor(url, payload); +} + +// export const validateMediaLink = async ( +// resultId: number, +// isRelevant: boolean +// ) => { +// try { +// const res = await api.put( +// "/media/tracking/monitoring/results/relevant", +// { +// resultId, +// isRelevant, +// } +// ); + +// return res.data; +// } catch (error: any) { +// throw new Error( +// error?.response?.data?.messages?.[0] || +// "Gagal memperbarui status relevansi" +// ); +// } +// }; diff --git a/src/types/react-table.d.ts b/src/types/react-table.d.ts index 682a93a0..5e8e7154 100644 --- a/src/types/react-table.d.ts +++ b/src/types/react-table.d.ts @@ -4,5 +4,6 @@ import "@tanstack/react-table"; declare module "@tanstack/react-table" { interface TableMeta { updateData: (rowIndex: number, value: Partial) => void; + refetchData?: () => void; } }