202 lines
6.0 KiB
TypeScript
202 lines
6.0 KiB
TypeScript
import * as React from "react";
|
|
import { ColumnDef } from "@tanstack/react-table";
|
|
import { exportMediaTrackingToExcel } from "@/utils/export-media-tracking";
|
|
import { loading, close } from "@/config/swal";
|
|
import { error } from "@/lib/swal";
|
|
import {
|
|
DownloadIcon,
|
|
Eye,
|
|
MoreVertical,
|
|
SquarePen,
|
|
Trash2,
|
|
} from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuItem,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import {
|
|
formatDateToIndonesian,
|
|
getOnlyDate,
|
|
htmlToString,
|
|
} from "@/utils/globals";
|
|
import { Link, useRouter } from "@/i18n/routing";
|
|
import {
|
|
Accordion,
|
|
AccordionContent,
|
|
AccordionItem,
|
|
AccordionTrigger,
|
|
} from "@/components/ui/accordion";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from "@/components/ui/dialog";
|
|
import { Collapsible, CollapsibleContent } from "@/components/ui/collapsible";
|
|
|
|
const columns: ColumnDef<any>[] = [
|
|
{
|
|
accessorKey: "no",
|
|
header: "No",
|
|
cell: ({ row }) => <span>{row.getValue("no")}</span>,
|
|
},
|
|
|
|
{
|
|
accessorKey: "title",
|
|
header: "Judul",
|
|
cell: ({ row }) => <span>{row.getValue("title")}</span>,
|
|
},
|
|
// {
|
|
// accessorKey: "resultTotal",
|
|
// header: () => <div className="text-center w-full">Jumlah Amplifikasi</div>,
|
|
// cell: ({ row }) => {
|
|
// const value = row.getValue("resultTotal") as number | string | null;
|
|
|
|
// const finalValue =
|
|
// value === null || value === undefined || value === ""
|
|
// ? 0
|
|
// : Number(value);
|
|
|
|
// return <div className="text-center w-full">{finalValue}</div>;
|
|
// },
|
|
// },
|
|
{
|
|
accessorKey: "amplification",
|
|
header: () => <div className="text-center w-full">Jumlah Amplifikasi</div>,
|
|
cell: ({ row }) => {
|
|
const totalRaw = row.getValue("amplification") as number | string | null;
|
|
|
|
const total =
|
|
totalRaw === null || totalRaw === undefined || totalRaw === ""
|
|
? 0
|
|
: Number(totalRaw);
|
|
|
|
const invalidTotal = 0;
|
|
|
|
return (
|
|
<div className="text-center w-full font-medium">
|
|
{total}
|
|
<span className="text-muted-foreground">/{invalidTotal}</span>
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
|
|
// {
|
|
// accessorKey: "status",
|
|
// header: "Status",
|
|
// cell: ({ row }) => <span>{row.getValue("status")}</span>,
|
|
// },
|
|
// {
|
|
// accessorKey: "isProcessing",
|
|
// header: () => <div className="text-center">Status</div>,
|
|
// cell: ({ row }) => {
|
|
// const raw = row.getValue("isProcessing");
|
|
// var status = "Sedang Diproses"
|
|
// if (Boolean(raw) == true) {
|
|
// status = "Selesai Diproses";
|
|
// }
|
|
// return <div className="text-center">{status}</div>;
|
|
// },
|
|
// },
|
|
{
|
|
accessorKey: "isProcessing",
|
|
header: () => <div className="text-center">Status</div>,
|
|
cell: ({ row }) => {
|
|
const raw = Boolean(row.getValue("isProcessing"));
|
|
const statusText = raw ? "Sedang Diproses" : "Sudah Selesai";
|
|
const colorClass = raw
|
|
? "bg-yellow-100 text-yellow-700 border border-yellow-300"
|
|
: "bg-green-100 text-green-700 border border-green-300";
|
|
|
|
return (
|
|
<div className="text-center">
|
|
<span
|
|
className={`px-2 py-1 rounded text-xs font-medium inline-block ${colorClass}`}
|
|
>
|
|
{statusText}
|
|
</span>
|
|
</div>
|
|
);
|
|
},
|
|
},
|
|
|
|
{
|
|
accessorKey: "createdAt",
|
|
header: () => <div className="text-center">Tanggal Penarikan</div>,
|
|
cell: ({ row }) => {
|
|
const raw = row.getValue("createdAt");
|
|
if (!raw || typeof raw !== "string")
|
|
return <div className="text-center">-</div>;
|
|
|
|
const date = new Date(raw);
|
|
if (isNaN(date.getTime())) return <div className="text-center">-</div>;
|
|
|
|
const formatted = date.toLocaleDateString("id-ID", {
|
|
day: "2-digit",
|
|
month: "short",
|
|
year: "numeric",
|
|
});
|
|
|
|
return <div className="text-center">{formatted}</div>;
|
|
},
|
|
},
|
|
{
|
|
id: "actions",
|
|
accessorKey: "action",
|
|
header: "Action",
|
|
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">
|
|
<Link href={`/admin/media-tracking/detail/${row.original.id}`}>
|
|
<DropdownMenuItem className="p-2 border-b cursor-pointer text-default-700 group focus:bg-default focus:text-primary-foreground items-center rounded-none">
|
|
<Eye className="w-4 h-4 me-1.5" />
|
|
View
|
|
{row.original.mediaUpload.fileType.secondaryName &&
|
|
row.original.mediaUpload.fileType.secondaryName.toLowerCase()}
|
|
</DropdownMenuItem>
|
|
</Link>
|
|
<DropdownMenuItem
|
|
className="p-2 border-b cursor-pointer text-default-700 group rounded-none focus:bg-default focus:text-primary-foreground "
|
|
onClick={async () => {
|
|
try {
|
|
loading();
|
|
await exportMediaTrackingToExcel({
|
|
mediaTrackingId: row.original.id,
|
|
});
|
|
close();
|
|
} catch (e: any) {
|
|
close();
|
|
error(e.message || "Gagal export data");
|
|
}
|
|
}}
|
|
>
|
|
<DownloadIcon className="w-4 h-4 me-1.5" />
|
|
<p>Download</p>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
},
|
|
},
|
|
];
|
|
|
|
export default columns;
|