mediahub-fe/app/[locale]/(protected)/content/audio-visual/table-video/index.tsx

387 lines
11 KiB
TypeScript

"use client";
import * as React from "react";
import {
ColumnDef,
ColumnFiltersState,
PaginationState,
SortingState,
VisibilityState,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
} from "@tanstack/react-table";
import { Input } from "@/components/ui/input";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { data } from "./data";
import TablePagination from "./table-pagination";
import { Button } from "@/components/ui/button";
import { format } from "date-fns";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
ChevronLeft,
ChevronRight,
Eye,
MoreVertical,
Trash2,
} from "lucide-react";
import { title } from "process";
import { getCookiesDecrypt } from "@/lib/utils";
import { listDataImage, listDataVideo } from "@/service/content/content";
export type CompanyData = {
no: number;
title: string;
categoryName: string;
createdAt: string;
creatorGroup: string;
publishedOn: string;
isPublish: any;
isPublishOnPolda: any;
isDone: string;
};
export const columns: ColumnDef<CompanyData>[] = [
{
accessorKey: "no",
header: "No",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("no")}
</h4>
</div>
</div>
),
},
{
accessorKey: "title",
header: "Judul",
cell: ({ row }) => (
<div className="flex items-center gap-5">
<div className="flex-1 text-start">
<h4 className="text-sm font-medium text-default-600 whitespace-nowrap mb-1">
{row.getValue("title")}
</h4>
</div>
</div>
),
},
{
accessorKey: "categoryName",
header: "Kategori",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("categoryName")}</span>
),
},
{
accessorKey: "createdAt",
header: "Tanggal Unggah",
cell: ({ row }) => {
const createdAt = row.getValue("createdAt") as
| string
| number
| undefined;
const formattedDate =
createdAt && !isNaN(new Date(createdAt).getTime())
? format(new Date(createdAt), "dd-MM-yyyy HH:mm:ss")
: "-";
return <span className="whitespace-nowrap">{formattedDate}</span>;
},
},
{
accessorKey: "creatorGroup",
header: "Sumber ",
cell: ({ row }) => (
<span className="whitespace-nowrap">{row.getValue("creatorGroup")}</span>
),
},
{
accessorKey: "publishedOn",
header: "Penempatan File",
cell: ({ row }) => {
const isPublish = row.original.isPublish;
const isPublishOnPolda = row.original.isPublishOnPolda;
let displayText = "-";
if (isPublish && !isPublishOnPolda) {
displayText = "Mabes";
} else if (isPublish && isPublishOnPolda) {
displayText = "Mabes & Polda";
} else if (!isPublish && isPublishOnPolda) {
displayText = "Polda";
}
return (
<div className="text-center whitespace-nowrap" title={displayText}>
{displayText}
</div>
);
},
},
{
accessorKey: "isDone",
header: "Status",
cell: ({ row }) => {
const isDone = row.getValue<boolean>("isDone");
return (
<div>
<Button
size="sm"
color="success"
variant="outline"
className={` btn btn-sm ${
isDone ? "btn-outline-success" : "btn-outline-primary"
} pill-btn ml-1`}
>
{isDone ? "Selesai" : "Aktif"}
</Button>
</div>
);
},
},
{
id: "actions",
accessorKey: "action",
header: "Actions",
enableHiding: false,
cell: ({ row }) => {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
className="bg-transparent ring-offset-transparent hover:bg-transparent hover:ring-0 hover:ring-transparent"
>
<span className="sr-only">Open menu</span>
<MoreVertical className="h-4 w-4 text-default-800" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="p-0" align="end">
<a href="/en/task/detail/[id]">
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
<Eye className="w-4 h-4 me-1.5" />
View
</DropdownMenuItem>
</a>
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
<Trash2 className="w-4 h-4 me-1.5" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
const TableVideo = () => {
const [videoTable, setVideoTable] = React.useState<CompanyData[]>([]);
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const [pagination, setPagination] = React.useState<PaginationState>({
pageIndex: 0, // Halaman pertama
pageSize: 10, // Jumlah baris per halaman
});
const [page, setPage] = React.useState(1); // Halaman aktif
const [totalPage, setTotalPage] = React.useState(1); // Total halaman
const [limit, setLimit] = React.useState(6); // Jumlah baris per halaman
const [search, setSearch] = React.useState(title);
const userId = getCookiesDecrypt("uie");
const userLevelId = getCookiesDecrypt("ulie");
const [categories, setCategories] = React.useState();
const [categoryFilter, setCategoryFilter] = React.useState([]);
const [statusFilter, setStatusFilter] = React.useState([]);
const [startDateString, setStartDateString] = React.useState("");
const [endDateString, setEndDateString] = React.useState("");
const [filterByCreator, setFilterByCreator] = React.useState("");
const [filterBySource, setFilterBySource] = React.useState("");
const roleId = getCookiesDecrypt("urie");
const table = useReactTable({
data: videoTable,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
React.useEffect(() => {
initState();
}, [page, limit]);
async function initState() {
try {
const isForSelf = Number(roleId) == 4;
const res = await listDataVideo(
limit,
page,
isForSelf,
!isForSelf,
categoryFilter?.sort().join(","),
statusFilter?.sort().join(",").includes("1")
? "1,2"
: statusFilter?.sort().join(","),
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
filterByCreator,
filterBySource,
startDateString,
endDateString
);
const data = res.data.data.content.map((item: any, index: number) => ({
no: (page - 1) * limit + index + 1,
title: item.title,
categoryName: item.categoryName,
creatorGroup: item.creatorGroup,
assignmentType: item.assignmentType?.name || "-",
createdAt: item.createdAt,
isDone: item.isDone,
publishedOn: item.publishedOn,
isPublish: item.isPublish,
isPublishOnPolda: item.isPublishOnPolda,
}));
setVideoTable(data);
setTotalPage(res.data.totalPages);
} catch (error) {
console.error("Error fetching tasks:", error);
}
}
return (
<div className="w-full">
<div className="flex items-center py-4 px-5">
<div className="flex-none">
<Input
placeholder="Filter Status..."
value={
(table.getColumn("status")?.getFilterValue() as string) ?? ""
}
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
table.getColumn("status")?.setFilterValue(event.target.value)
}
className="max-w-sm "
/>
</div>
</div>
<Table className="overflow-hidden">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id} className="bg-default-200">
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
className="h-[75px]"
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
<div className="flex items-center justify-center py-4 gap-2 flex-none">
<Button
variant="outline"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
className="w-8 h-8"
>
<ChevronLeft className="w-4 h-4" />
</Button>
{table.getPageOptions().map((page, pageIndex) => (
<Button
key={`basic-data-table-${pageIndex}`}
onClick={() => table.setPageIndex(pageIndex)}
size="icon"
className="w-8 h-8"
variant={
table.getState().pagination.pageIndex === pageIndex
? "default"
: "outline"
}
>
{page + 1}
</Button>
))}
<Button
variant="outline"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
className="w-8 h-8"
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
</div>
);
};
export default TableVideo;