import { Head, Link, router } from '@inertiajs/react'; import type { ColumnDef } from '@tanstack/react-table'; import { format } from 'date-fns'; import { ArrowLeft, Save } from 'lucide-react'; import { useState } from 'react'; import { DataTable } from '@/components/data-table'; import { PageHeader } from '@/components/page-header'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { usePermissions } from '@/hooks/use-permissions'; import { index as assignmentIndex } from '@/routes/admin/academic-classes/assignments'; import { grade } from '@/routes/admin/academic-classes/assignments/submissions'; import { AssignmentStatusLabels } from '@/types/assignment'; import type { Assignment } from '@/types/assignment'; import type { Submission } from '@/types/submission'; import { SubmissionStatusLabels } from '@/types/submission'; type Props = { assignment: Assignment; submissions: Submission[]; }; function ScoreCell({ assignmentId, submission, canUpdate, }: { assignmentId: number; submission: Submission; canUpdate: boolean; }) { const normalizedScore = submission.score ?? ''; const [value, setValue] = useState(normalizedScore); const [savedScore, setSavedScore] = useState(normalizedScore); const [saving, setSaving] = useState(false); // Sync local state when the score changes externally (e.g. after save). if (normalizedScore !== savedScore) { setSavedScore(normalizedScore); setValue(normalizedScore); } if (!canUpdate) { return
{submission.score ?? '-'}
; } const dirty = value !== normalizedScore; function handleSave() { setSaving(true); router.patch( grade.url([assignmentId, submission.id]), { score: value === '' ? null : value }, { preserveScroll: true, preserveState: true, onFinish: () => setSaving(false), }, ); } return (
setValue(event.target.value)} className="h-8 w-20 text-center" /> {dirty && ( )}
); } export default function SubmissionIndex({ assignment, submissions }: Props) { const { hasPermission } = usePermissions(); const canUpdate = hasPermission('update-assignment-submissions'); const columns: ColumnDef[] = [ { accessorKey: 'student.student_number', header: () => NIM, cell: ({ row }) => row.original.student?.student_number ?? '-', }, { accessorKey: 'student.user.profile.full_name', header: () => Nama Mahasiswa, cell: ({ row }) => row.original.student?.user?.profile?.full_name ?? '-', }, { accessorKey: 'status', header: () => Status, meta: { className: 'w-[160px] text-center', headerClassName: 'w-[160px] text-center', }, cell: ({ row }) => { const status = row.getValue('status') as keyof typeof SubmissionStatusLabels | null; return (
{status ? ( {SubmissionStatusLabels[status]} ) : ( - )}
); }, }, { accessorKey: 'submitted_at', header: () => Waktu Kumpul, cell: ({ row }) => { const submittedAt = row.getValue('submitted_at') as string | null; return submittedAt ? format(new Date(submittedAt), 'd MMM yyyy, HH:mm') : '-'; }, }, { accessorKey: 'score', header: () => Nilai, meta: { className: 'w-[140px] text-center', headerClassName: 'w-[140px] text-center', }, cell: ({ row }) => ( ), }, ]; return ( <>
Kembali } /> {assignment.title} {AssignmentStatusLabels[assignment.status]}

Kelas: {assignment.course_class?.course?.code}{' '} {assignment.course_class?.course?.name}

Batas Waktu:{' '} {format( new Date(assignment.deadline), 'd MMM yyyy, HH:mm', )}

Jumlah Pengumpulan: {submissions.length}

Daftar Pengumpulan

); }