import { Head, router } from '@inertiajs/react'; import { format } from 'date-fns'; import { Plus } from 'lucide-react'; import { useState } from 'react'; import type { PaginationState } from '@/components/data-table'; import { DataTable } from '@/components/data-table'; import { DeleteConfirmDialog } from '@/components/delete-confirm-dialog'; import type { FilterField } from '@/components/filter-dialog'; import { FilterDialog } from '@/components/filter-dialog'; 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 { Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList, useComboboxAnchor, } from '@/components/ui/combobox'; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { usePermissions } from '@/hooks/use-permissions'; import { useServerTable } from '@/hooks/use-server-table'; import { index as academicAdvisingLogIndex, destroy, store, update, } from '@/routes/admin/services/academic-advising-logs'; import type { AcademicAdvisingLog, AcademicAdvisingLogLecturer, AcademicAdvisingLogStudent, } from '@/types/academic-advising-log'; import { createAcademicAdvisingLogColumns } from './columns'; type Props = { logs: { data: AcademicAdvisingLog[]; current_page: number; last_page: number; per_page: number; total: number; }; students: AcademicAdvisingLogStudent[]; lecturers: AcademicAdvisingLogLecturer[]; highlight?: number; filters: { lecturer_id?: string; }; }; function studentLabel(student: AcademicAdvisingLogStudent): string { return `${student.user?.profile?.full_name ?? 'N/A'} - ${student.student_number}`; } function lecturerLabel(lecturer: AcademicAdvisingLogLecturer): string { return `${lecturer.user?.profile?.full_name ?? 'N/A'} - ${lecturer.lecturer_number}`; } export default function AcademicAdvisingLogIndex({ logs, students, lecturers, highlight, filters, }: Props) { const [createOpen, setCreateOpen] = useState(false); const [editing, setEditing] = useState(null); const [deleting, setDeleting] = useState(null); const [viewing, setViewing] = useState(null); const { hasPermission } = usePermissions(); const canCreate = hasPermission('create-academic-advising-logs'); const canUpdate = hasPermission('update-academic-advising-logs'); const canDelete = hasPermission('delete-academic-advising-logs'); const filterFields: FilterField[] = [ { key: 'lecturer_id', label: 'Dosen', options: lecturers.map((lecturer) => ({ value: String(lecturer.id), label: lecturerLabel(lecturer), })), }, ]; const pagination: PaginationState = { current_page: logs.current_page, last_page: logs.last_page, per_page: logs.per_page, total: logs.total, }; const { search, handlePageChange, handlePerPageChange, handleSearchChange, applyFilters, } = useServerTable({ route: () => academicAdvisingLogIndex.url(), pagination, filters, }); function handleDelete() { if (!deleting) { return; } router.delete(destroy(deleting.id), { onSuccess: () => setDeleting(null), }); } const columns = createAcademicAdvisingLogColumns({ handleView: (log) => setViewing(log), handleEdit: (log) => setEditing(log), handleDeleteClick: (log) => setDeleting(log), canUpdate, canDelete, }); return ( <>
Menampilkan log bimbingan dari notifikasi.

) } actions={ canCreate && ( ) } /> { if (!open) { setEditing(null); } }} editing={editing} students={students} lecturers={lecturers} /> { if (!open) { setViewing(null); } }} log={viewing} /> } /> { if (!open) { setDeleting(null); } }} title="Hapus Log Bimbingan" description={(log) => `Apakah Anda yakin ingin menghapus log bimbingan untuk "${log.students.map((s) => s.user?.profile?.full_name ?? 'N/A').join(', ') || 'mahasiswa ini'}"? Tindakan ini tidak dapat dibatalkan.` } onConfirm={handleDelete} />
); } function ViewDetailDialog({ open, onOpenChange, log, }: { open: boolean; onOpenChange: (open: boolean) => void; log: AcademicAdvisingLog | null; }) { return ( Detail Bimbingan Akademik {log && (
Dicatat{' '} {format( new Date(log.created_at), 'd MMM yyyy, HH:mm', )}

{log.lecturer?.user?.profile?.full_name ?? 'N/A'}{' '} · {log.lecturer?.lecturer_number}

{log.students.length === 0 ? (

-

) : (
    {log.students.map((student) => (
  • {student.user?.profile ?.full_name ?? 'N/A'}{' '} · {student.student_number}
  • ))}
)}

{log.topic ?? '-'}

{log.notes ?? '-'}

)}
); } function AdvisingLogFields({ errors, editing, students, lecturers, }: { errors: Record; editing?: AcademicAdvisingLog; students: AcademicAdvisingLogStudent[]; lecturers: AcademicAdvisingLogLecturer[]; }) { const [lecturer, setLecturer] = useState(editing?.lecturer ?? null); const [selectedStudents, setSelectedStudents] = useState< AcademicAdvisingLogStudent[] >(editing?.students ?? []); const studentAnchor = useComboboxAnchor(); const availableStudents = lecturer ? students.filter((s) => lecturer.departments.some( (department) => department.id === s.department?.id, ), ) : []; return ( <>
{ setLecturer(value); setSelectedStudents([]); }} itemToStringLabel={(l) => lecturerLabel(l)} isItemEqualToValue={(a, b) => a.id === b.id} > Dosen tidak ditemukan. {(l: AcademicAdvisingLogLecturer) => ( {lecturerLabel(l)} )}
{selectedStudents.map((s) => ( ))} studentLabel(s)} isItemEqualToValue={(a, b) => a.id === b.id} > {selectedStudents.map((s) => ( {studentLabel(s)} ))} 0 ? '' : lecturer ? 'Pilih mahasiswa' : 'Pilih dosen terlebih dahulu' } /> Mahasiswa tidak ditemukan. {(s: AcademicAdvisingLogStudent) => ( {studentLabel(s)} )}