siakad-itm/resources/js/pages/lecturer/academic-advising-logs/index.tsx

157 lines
5.4 KiB
TypeScript

import { Head } from '@inertiajs/react';
import { Plus } from 'lucide-react';
import { useState } from 'react';
import { DataTable } from '@/components/data-table';
import { DateTimeField } from '@/components/datetime-field';
import { FormDialog } from '@/components/form-dialog';
import InputError from '@/components/input-error';
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';
import { store } from '@/routes/lecturer/academic-advising-logs';
import type { AcademicAdvisingLog } from '@/types/academic-advising-log';
import { advisingLogColumns } from './columns';
type Advisee = {
id: number;
student_number: string;
user: { profile: { full_name: string } | null } | null;
};
type Props = {
logs: AcademicAdvisingLog[];
advisees: Advisee[];
};
function adviseeLabel(advisee: Advisee): string {
return `${advisee.user?.profile?.full_name ?? 'N/A'} - ${advisee.student_number}`;
}
export default function LecturerAcademicAdvisingLogIndex({
logs,
advisees,
}: Props) {
const [createOpen, setCreateOpen] = useState(false);
return (
<>
<Head title="Bimbingan Akademik" />
<div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
<PageHeader
title="Bimbingan Akademik"
actions={
<Button asChild>
<button
type="button"
onClick={() => setCreateOpen(true)}
>
<Plus className="h-4 w-4" />
Tambah Bimbingan
</button>
</Button>
}
/>
<CreateForm
open={createOpen}
onOpenChange={setCreateOpen}
advisees={advisees}
/>
<DataTable
columns={advisingLogColumns}
data={logs}
emptyText="Belum ada log bimbingan akademik."
/>
</div>
</>
);
}
function CreateForm({
open,
onOpenChange,
advisees,
}: {
open: boolean;
onOpenChange: (open: boolean) => void;
advisees: Advisee[];
}) {
return (
<FormDialog
open={open}
onOpenChange={onOpenChange}
title="Tambah Bimbingan Akademik"
action={store()}
resetOnSuccess
onSuccess={() => onOpenChange(false)}
>
{({ errors }) => (
<div className="grid gap-4">
<div className="grid gap-2">
<Label>
Mahasiswa{' '}
<span className="text-destructive">*</span>
</Label>
<Select name="student_id">
<SelectTrigger className="w-full">
<SelectValue placeholder="Pilih mahasiswa bimbingan" />
</SelectTrigger>
<SelectContent>
{advisees.map((advisee) => (
<SelectItem
key={advisee.id}
value={String(advisee.id)}
>
{adviseeLabel(advisee)}
</SelectItem>
))}
</SelectContent>
</Select>
{advisees.length === 0 && (
<p className="text-xs text-muted-foreground">
Anda belum memiliki mahasiswa bimbingan.
</p>
)}
<InputError message={errors.student_id} />
</div>
<div className="grid gap-2">
<Label htmlFor="topic">Topik</Label>
<Input
id="topic"
name="topic"
placeholder="Masukkan topik bimbingan"
/>
<InputError message={errors.topic} />
</div>
<div className="grid gap-2">
<Label htmlFor="notes">Catatan</Label>
<Textarea
id="notes"
name="notes"
placeholder="Masukkan catatan bimbingan"
/>
<InputError message={errors.notes} />
</div>
<DateTimeField
label="Tanggal Sesi"
name="session_date"
placeholder="Pilih tanggal sesi"
error={errors.session_date}
/>
</div>
)}
</FormDialog>
);
}