siakad-itm/resources/js/pages/student/course-registrations/index.tsx
Yoga Pangestu 6b36d65eb9
Some checks failed
tests / ci (pull_request) Has been cancelled
feat: update search placeholders and remove empty text in data tables
2026-08-30 20:58:19 +07:00

130 lines
5.4 KiB
TypeScript

import { Head, Link } from '@inertiajs/react';
import { XCircle } from 'lucide-react';
import { DataTable } from '@/components/data-table';
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { formatRupiah } from '@/lib/currency';
import { create } from '@/routes/student/course-registrations';
import type { AcademicTerm } from '@/types/academic-term';
import type { RegistrationStatus } from '@/types/course-registration';
import type { SubmissionSummary } from './columns';
import { submissionColumns } from './columns';
type PaymentStatus = {
has_invoice: boolean;
is_paid: boolean;
amount_due: number | null;
paid_total: number | null;
};
type ActiveSubmission = {
status: RegistrationStatus;
rejection_reason: string | null;
};
type Props = {
academicTerm: AcademicTerm | null;
payment: PaymentStatus | null;
canSubmit: boolean;
activeSubmission: ActiveSubmission | null;
submissions: SubmissionSummary[];
};
export default function CourseRegistrationIndex({
academicTerm,
payment,
canSubmit,
activeSubmission,
submissions,
}: Props) {
return (
<>
<Head title="KRS" />
<div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
<PageHeader
title="Kartu Rencana Studi"
description={
academicTerm && (
<p className="mt-1 text-sm text-muted-foreground">
Periode aktif: {academicTerm.name} (
{academicTerm.semester === 'odd'
? 'Ganjil'
: 'Genap'}
)
</p>
)
}
/>
{!academicTerm && (
<Card>
<CardContent className="pt-6 text-sm text-muted-foreground">
Belum ada periode akademik yang aktif. Silakan
hubungi admin.
</CardContent>
</Card>
)}
{academicTerm && payment && !payment.is_paid && (
<Card className="border-destructive/50">
<CardContent className="pt-6 text-sm">
<p className="font-medium text-destructive">
Anda belum bisa mengisi KRS periode ini.
</p>
<p className="mt-1 text-muted-foreground">
{payment.has_invoice
? `Tagihan periode ini belum lunas (terbayar ${formatRupiah(payment.paid_total ?? 0)} dari ${formatRupiah(payment.amount_due ?? 0)}).`
: 'Tagihan untuk periode ini belum diterbitkan. Silakan hubungi staf keuangan.'}
</p>
</CardContent>
</Card>
)}
{academicTerm && payment?.is_paid && canSubmit && (
<Card
className={
activeSubmission?.status === 'rejected'
? 'border-destructive/50'
: undefined
}
>
<CardContent className="flex flex-col gap-3 pt-6 sm:flex-row sm:items-center sm:justify-between">
<div>
{activeSubmission?.status === 'rejected' ? (
<>
<p className="flex items-center gap-2 text-sm font-medium text-destructive">
<XCircle className="h-4 w-4" />
KRS Anda untuk periode ini ditolak
</p>
<p className="mt-1 text-sm text-muted-foreground">
{activeSubmission.rejection_reason ??
'Tidak ada alasan yang diberikan.'}{' '}
Silakan perbaiki dan ajukan kembali.
</p>
</>
) : (
<p className="text-sm text-muted-foreground">
Anda belum mengisi KRS untuk periode
aktif ini.
</p>
)}
</div>
<Button asChild>
<Link href={create.url()}>
{activeSubmission?.status === 'rejected'
? 'Ajukan Ulang KRS'
: 'Isi KRS'}
</Link>
</Button>
</CardContent>
</Card>
)}
<DataTable columns={submissionColumns} data={submissions} />
</div>
</>
);
}