siakad-itm/resources/js/pages/admin/academic-classes/course-registrations/columns.tsx
Yoga Pangestu 5710a57992
Some checks failed
tests / ci (pull_request) Has been cancelled
refactor: remove class_name from CourseClass and related components
2026-08-30 13:14:53 +07:00

139 lines
4.8 KiB
TypeScript

import type { ColumnDef } from '@tanstack/react-table';
import { format } from 'date-fns';
import { Pencil, Trash2 } from 'lucide-react';
import { RowActions } from '@/components/row-actions';
import { Badge } from '@/components/ui/badge';
import type {
CourseRegistration,
RegistrationStatus,
} from '@/types/course-registration';
import { RegistrationStatusLabels } from '@/types/course-registration';
export type { CourseRegistration } from '@/types/course-registration';
type CreateColumnsParams = {
handleEdit: (registration: CourseRegistration) => void;
handleDeleteClick: (registration: CourseRegistration) => void;
};
export function createCourseRegistrationColumns(
params: CreateColumnsParams,
): ColumnDef<CourseRegistration>[] {
const { handleEdit, handleDeleteClick } = params;
return [
{
accessorKey: 'student.student_number',
header: () => <span>Mahasiswa</span>,
cell: ({ row }) => {
const student = row.original.student;
return (
<div>
<p className="font-medium">
{student?.user?.profile?.full_name ?? 'N/A'}
</p>
<p className="text-xs text-muted-foreground">
{student?.student_number} &middot;{' '}
{student?.department?.name ?? '-'}
</p>
</div>
);
},
},
{
accessorKey: 'course_class.course.name',
header: () => <span>Kelas Mata Kuliah</span>,
cell: ({ row }) => {
const courseClass = row.original.course_class;
return (
<div>
<p className="font-medium">
{courseClass?.course?.name ?? 'N/A'}
</p>
<p className="text-xs text-muted-foreground">
{courseClass?.course?.code}
</p>
</div>
);
},
},
{
accessorKey: 'academic_term.name',
header: () => <span>Periode</span>,
cell: ({ row }) => row.original.academic_term?.name ?? '-',
},
{
accessorKey: 'status',
header: () => <span className="block text-center">Status</span>,
meta: {
className: 'w-[130px] text-center',
headerClassName: 'w-[130px] text-center',
},
cell: ({ row }) => {
const status = row.getValue(
'status',
) as RegistrationStatus | null;
const variant =
status === 'approved'
? 'default'
: status === 'rejected'
? 'destructive'
: 'outline';
return (
<div className="flex justify-center">
{status ? (
<Badge variant={variant}>
{RegistrationStatusLabels[status]}
</Badge>
) : (
<span className="text-muted-foreground">-</span>
)}
</div>
);
},
},
{
accessorKey: 'approver.user.profile.full_name',
header: () => <span>Disetujui Oleh</span>,
cell: ({ row }) =>
row.original.approver?.user?.profile?.full_name ?? '-',
},
{
accessorKey: 'created_at',
header: () => <span>Diajukan</span>,
cell: ({ row }) =>
format(new Date(row.original.created_at), 'd MMM yyyy, HH:mm'),
},
{
id: 'actions',
header: () => <span className="block text-center">Aksi</span>,
meta: {
className: 'w-[100px] text-center',
headerClassName: 'w-[100px] text-center',
},
cell: ({ row }) => (
<RowActions
actions={[
{
label: 'Edit',
icon: <Pencil className="h-4 w-4" />,
onClick: () => handleEdit(row.original),
},
{
label: 'Hapus',
icon: (
<Trash2 className="h-4 w-4 text-destructive" />
),
onClick: () => handleDeleteClick(row.original),
},
]}
/>
),
},
];
}