import type { ColumnDef } from '@tanstack/react-table'; import { format } from 'date-fns'; import { Pencil, Trash2, Upload } from 'lucide-react'; import { AttachmentPreviewDialog } from '@/components/attachment-preview-dialog'; import { RowActions } from '@/components/row-actions'; import { StatusBadge } from '@/components/status-badge'; import type { LetterRequest } from '@/types/letter-request'; import { LetterStatuses, LetterStatusLabels } from '@/types/letter-request'; export type { LetterRequest } from '@/types/letter-request'; const LetterStatusVariants: Record< string, 'default' | 'secondary' | 'destructive' | 'outline' > = { submitted: 'outline', in_process: 'secondary', completed: 'default', rejected: 'destructive', }; const letterStatusOptions = LetterStatuses.map((status) => ({ value: status, label: LetterStatusLabels[status], })); type CreateColumnsParams = { handleEdit: (letterRequest: LetterRequest) => void; handleDeleteClick: (letterRequest: LetterRequest) => void; handleStatusChange: (letterRequest: LetterRequest, status: string) => void; handleUploadClick: (letterRequest: LetterRequest) => void; canUpdate: boolean; canDelete: boolean; canProcess: boolean; }; export function createLetterRequestColumns( params: CreateColumnsParams, ): ColumnDef[] { const { handleEdit, handleDeleteClick, handleStatusChange, handleUploadClick, canUpdate, canDelete, canProcess, } = params; const columns: ColumnDef[] = [ { id: 'requester', header: () => Pemohon, cell: ({ row }) => { const user = row.original.user; const identifier = user?.student ? `${user.student.student_number} · ${user.student.department?.name ?? '-'}` : user?.lecturer ? `${user.lecturer.lecturer_number} · ${user.lecturer.departments.map((d) => d.name).join(', ') || '-'}` : '-'; return (

{user?.profile?.full_name ?? 'N/A'}

{identifier}

); }, }, { accessorKey: 'letter_type', header: () => Jenis Surat, cell: ({ row }) => { const letterRequest = row.original; return (

{letterRequest.letter_type}

{letterRequest.purpose && (

{letterRequest.purpose}

)}
); }, }, { accessorKey: 'status', header: () => Status, meta: { className: 'w-[120px] text-center', headerClassName: 'w-[120px] text-center', }, cell: ({ row }) => (
handleStatusChange(row.original, status) } disabled={!canProcess} />
), }, { accessorKey: 'processor.profile.full_name', header: () => Diproses Oleh, cell: ({ row }) => row.original.processor?.profile?.full_name ?? '-', }, { accessorKey: 'submitted_at', header: () => Diajukan, cell: ({ row }) => { const submittedAt = row.original.submitted_at; return submittedAt ? format(new Date(submittedAt), 'd MMM yyyy, HH:mm') : '-'; }, }, { accessorKey: 'result_name', header: () => Dokumen, cell: ({ row }) => { const letterRequest = row.original; if (!letterRequest.result_url || !letterRequest.result_name) { return -; } return ( ); }, }, ]; if (canUpdate || canDelete || canProcess) { columns.push({ id: 'actions', header: () => Aksi, meta: { className: 'w-[100px] text-center', headerClassName: 'w-[100px] text-center', }, cell: ({ row }) => { const isLocked = row.original.status !== 'submitted'; return ( , show: canProcess && row.original.status === 'in_process', onClick: () => handleUploadClick(row.original), }, { label: 'Edit', icon: , show: canUpdate && !isLocked, onClick: () => handleEdit(row.original), }, { label: 'Hapus', icon: ( ), show: canDelete && !isLocked, onClick: () => handleDeleteClick(row.original), }, ]} /> ); }, }); } return columns; }