'use client'; import { useEffect, useState } from 'react'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Button } from "@/components/ui/button"; import { Loader2, BookOpen, ChevronDown } from "lucide-react"; import { Badge } from "@/components/ui/badge"; interface MataKuliahBelumDiambil { nama_mk: string; jenis_mk: string; kode_mk: string; sks: number; semester: number; } interface MahasiswaMKBelumDiambil { nim: string; nama: string; tahun_angkatan: number; sks_total: number; mk_belum_diambil: MataKuliahBelumDiambil[]; } interface TabelMKBelumDiambilProps { selectedYear: string; selectedJenisMK: string; onJenisMKChange: (jenis: string) => void; } export default function TabelMKBelumDiambil({ selectedYear, selectedJenisMK, onJenisMKChange }: TabelMKBelumDiambilProps) { const [mahasiswaData, setMahasiswaData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // State for pagination const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [paginatedData, setPaginatedData] = useState([]); useEffect(() => { const fetchData = async () => { try { setLoading(true); setError(null); let url = '/api/tabeldetail/mk-belum-diambil'; const params = new URLSearchParams(); if (selectedYear && selectedYear !== 'all') { params.append('tahun_angkatan', selectedYear); } if (selectedJenisMK && selectedJenisMK !== 'all') { params.append('jenis_mk', selectedJenisMK); } if (params.toString()) { url += `?${params.toString()}`; } const response = await fetch(url, { cache: 'no-store', }); if (!response.ok) { throw new Error('Failed to fetch mahasiswa MK belum diambil data'); } const data = await response.json(); setMahasiswaData(data); setCurrentPage(1); // Reset ke halaman pertama saat filter berubah } catch (err) { setError(err instanceof Error ? err.message : 'Terjadi kesalahan'); console.error('Error fetching data:', err); } finally { setLoading(false); } }; fetchData(); }, [selectedYear, selectedJenisMK]); // Update paginated data when data or pagination settings change useEffect(() => { paginateData(); }, [mahasiswaData, currentPage, pageSize]); // Paginate data const paginateData = () => { const startIndex = (currentPage - 1) * pageSize; const endIndex = startIndex + pageSize; setPaginatedData(mahasiswaData.slice(startIndex, endIndex)); }; // Get total number of pages const getTotalPages = () => { return Math.ceil(mahasiswaData.length / pageSize); }; // Handle page change const handlePageChange = (page: number) => { setCurrentPage(page); }; // Handle page size change const handlePageSizeChange = (size: string) => { setPageSize(Number(size)); setCurrentPage(1); }; // Get badge color based on jenis_mk const getJenisMKBadgeColor = (jenis: string) => { switch (jenis) { case 'Wajib': return 'bg-blue-500 hover:bg-blue-600'; case 'Pilihan Wajib': return 'bg-green-500 hover:bg-green-600'; case 'Pilihan': return 'bg-amber-500 hover:bg-amber-600'; default: return 'bg-gray-500 hover:bg-gray-600'; } }; // Calculate statistics const stats = { total: mahasiswaData.length, total_mk_belum_diambil: mahasiswaData.reduce((sum, mhs) => sum + mhs.mk_belum_diambil.length, 0), avg_mk_belum_diambil: mahasiswaData.length > 0 ? (mahasiswaData.reduce((sum, mhs) => sum + mhs.mk_belum_diambil.length, 0) / mahasiswaData.length).toFixed(1) : 0, }; // Get jenis MK counts const jenisMKCounts = mahasiswaData.reduce((acc, mhs) => { mhs.mk_belum_diambil.forEach(mk => { acc[mk.jenis_mk] = (acc[mk.jenis_mk] || 0) + 1; }); return acc; }, {} as Record); if (loading) { return (
Memuat data...
); } if (error) { return ( Error: {error} ); } return ( Tabel Mahasiswa - Mata Kuliah Belum Diambil {selectedYear !== 'all' ? `Angkatan ${selectedYear}` : 'Semua Angkatan'} {/* Tampilkan ringkasan statistik */}
Total Mahasiswa
{stats.total}
Total MK Belum Diambil
{stats.total_mk_belum_diambil}
{/* Tampilkan badge jenis MK */} {selectedJenisMK === 'all' && Object.keys(jenisMKCounts).length > 0 && (
{Object.entries(jenisMKCounts) .sort(([a], [b]) => { const order = ['Wajib', 'Pilihan Wajib', 'Pilihan']; return order.indexOf(a) - order.indexOf(b); }) .map(([jenis, count]) => ( {jenis}: {count} MK ))}
)}
{/* Show entries selector and filter */}
Show entries
{/* Filter Jenis MK */}
Filter Jenis MK:
No NIM Nama Mahasiswa Tahun Angkatan SKS Total Jumlah MK Belum Diambil MK Belum Diambil {paginatedData.length === 0 ? ( Tidak ada data yang tersedia ) : ( paginatedData.map((mahasiswa, index) => ( {(currentPage - 1) * pageSize + index + 1} {mahasiswa.nim} {mahasiswa.nama} {mahasiswa.tahun_angkatan} {mahasiswa.sks_total} {mahasiswa.mk_belum_diambil.length} MK {mahasiswa.mk_belum_diambil.length === 0 ? ( Tidak ada MK yang belum diambil ) : ( mahasiswa.mk_belum_diambil.map((mk, mkIndex) => (
{mk.nama_mk} {mk.jenis_mk}
{mk.kode_mk} {mk.sks} SKS Semester {mk.semester}
)) )}
)) )}
{/* Pagination info and controls */} {!loading && !error && mahasiswaData.length > 0 && (
Showing {getDisplayRange().start} to {getDisplayRange().end} of {mahasiswaData.length} entries
handlePageChange(Math.max(1, currentPage - 1))} className={currentPage === 1 ? "pointer-events-none opacity-50" : "cursor-pointer"} /> {renderPaginationItems()} handlePageChange(Math.min(getTotalPages(), currentPage + 1))} className={currentPage === getTotalPages() ? "pointer-events-none opacity-50" : "cursor-pointer"} />
)}
); // Calculate the range of entries being displayed function getDisplayRange() { if (mahasiswaData.length === 0) return { start: 0, end: 0 }; const start = (currentPage - 1) * pageSize + 1; const end = Math.min(currentPage * pageSize, mahasiswaData.length); return { start, end }; } // Generate pagination items function renderPaginationItems() { const totalPages = getTotalPages(); const items = []; // Always show first page items.push( handlePageChange(1)} className="cursor-pointer" > 1 ); // Show ellipsis if needed if (currentPage > 3) { items.push( ); } // Show pages around current page for (let i = Math.max(2, currentPage - 1); i <= Math.min(totalPages - 1, currentPage + 1); i++) { if (i === 1 || i === totalPages) continue; items.push( handlePageChange(i)} className="cursor-pointer" > {i} ); } // Show ellipsis if needed if (currentPage < totalPages - 2) { items.push( ); } // Always show last page if there's more than one page if (totalPages > 1) { items.push( handlePageChange(totalPages)} className="cursor-pointer" > {totalPages} ); } return items; } }