108 lines
4.0 KiB
TypeScript
108 lines
4.0 KiB
TypeScript
import { usePermission } from '@/hooks/use-permission';
|
|
import type { ColumnDef } from '@tanstack/react-table';
|
|
import { Pencil, Trash2, ImagePlus } from 'lucide-react';
|
|
import { DataTableColumnHeader } from '@/components/data-table-column-header';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
|
import { formatDate, formatCurrency } from '@/lib/formatters';
|
|
import type { Expense } from '@/types';
|
|
|
|
interface ColumnProps {
|
|
onEdit: (expense: Expense) => void;
|
|
onDelete: (expense: Expense) => void;
|
|
onPreviewImage: (url: string) => void;
|
|
}
|
|
|
|
|
|
export const getColumns = ({ onEdit, onDelete, onPreviewImage }: ColumnProps): ColumnDef<Expense>[] => [
|
|
{
|
|
accessorKey: "user.name",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Pegawai" />
|
|
),
|
|
cell: ({ row }) => (
|
|
<span className="text-sm">{row.original.user?.name || '-'}</span>
|
|
),
|
|
meta: { title: "Pegawai" },
|
|
},
|
|
{
|
|
accessorKey: "proof_url",
|
|
header: "Bukti",
|
|
cell: ({ row }) => {
|
|
const url = row.original.proof_url;
|
|
|
|
return url ? (
|
|
<button onClick={() => onPreviewImage(url)} className="block w-fit">
|
|
<img src={url} alt="Proof" className="h-10 w-10 object-cover rounded-md border hover:opacity-80 transition-opacity" />
|
|
</button>
|
|
) : (
|
|
<div className="h-10 w-10 flex items-center justify-center bg-muted rounded-md border">
|
|
<ImagePlus className="h-4 w-4 text-muted-foreground" />
|
|
</div>
|
|
);
|
|
},
|
|
meta: { title: "Bukti" },
|
|
},
|
|
{
|
|
accessorKey: "name",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Nama" />
|
|
),
|
|
meta: { title: "Nama" },
|
|
},
|
|
{
|
|
accessorKey: "amount",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Nominal" />
|
|
),
|
|
cell: ({ row }) => formatCurrency(row.original.amount),
|
|
meta: { title: "Nominal" },
|
|
},
|
|
{
|
|
accessorKey: "created_at",
|
|
header: ({ column }) => (
|
|
<DataTableColumnHeader column={column} title="Tanggal" />
|
|
),
|
|
cell: ({ row }) => formatDate(row.original.created_at),
|
|
meta: { title: "Tanggal" },
|
|
},
|
|
{
|
|
id: "actions",
|
|
header: "Aksi",
|
|
cell: ({ row }) => {
|
|
const expense = row.original;
|
|
const { hasPermission } = usePermission();
|
|
|
|
return (
|
|
<div className="flex items-center gap-2">
|
|
{hasPermission('Edit:Expense') && (
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button variant="ghost" size="icon" className='text-yellow-600' onClick={() => onEdit(expense)}>
|
|
<Pencil className="size-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<p>Ubah</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)}
|
|
{hasPermission('Delete:Expense') && (
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<Button variant="ghost" size="icon" className='text-red-600' onClick={() => onDelete(expense)}>
|
|
<Trash2 className="size-4" />
|
|
</Button>
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
<p>Hapus</p>
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)}
|
|
</div>
|
|
);
|
|
},
|
|
meta: { title: "Aksi" },
|
|
},
|
|
];
|