'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 { Loader2, Trophy } from "lucide-react"; interface MahasiswaTingkatPrestasi { nim: string; nama: string; tahun_angkatan: number; tingkat_prestasi: string; nama_prestasi: string; } interface TabelTingkatPrestasiMahasiswaProps { selectedYear: string; } export default function TabelTingkatPrestasiMahasiswa({ selectedYear }: TabelTingkatPrestasiMahasiswaProps) { 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); const url = selectedYear === 'all' ? '/api/tabeldetail/tingkat-prestasi' : `/api/tabeldetail/tingkat-prestasi?tahun_angkatan=${selectedYear}`; const response = await fetch(url, { cache: 'no-store', }); if (!response.ok) { throw new Error('Failed to fetch mahasiswa tingkat prestasi data'); } const data = await response.json(); setMahasiswaData(data); } catch (err) { setError(err instanceof Error ? err.message : 'Terjadi kesalahan'); console.error('Error fetching data:', err); } finally { setLoading(false); } }; fetchData(); }, [selectedYear]); // 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); // Reset to first page when changing page size }; // Fungsi untuk mendapatkan styling berdasarkan tingkat prestasi const getTingkatPrestasiStyle = (tingkat: string) => { switch (tingkat) { case "Internasional": return "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300"; case "Nasional": return "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300"; case "Provinsi": return "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"; case "Kabupaten": return "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300"; default: return "bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300"; } }; // Hitung statistik berdasarkan tingkat prestasi const tingkatStats = mahasiswaData.reduce((acc, mahasiswa) => { const tingkat = mahasiswa.tingkat_prestasi; acc[tingkat] = (acc[tingkat] || 0) + 1; return acc; }, {} as Record); // Hitung statistik tahun angkatan const tahunAngkatanStats = mahasiswaData.reduce((acc, mahasiswa) => { const tahun = mahasiswa.tahun_angkatan; acc[tahun] = (acc[tahun] || 0) + 1; return acc; }, {} as Record); const stats = { total: mahasiswaData.length, total_tingkat: Object.keys(tingkatStats).length, total_tahun_angkatan: Object.keys(tahunAngkatanStats).length }; if (loading) { return (
Loading...
); } if (error) { return ( Error: {error} ); } return ( Tabel Tingkat Prestasi Mahasiswa {selectedYear !== 'all' ? `Angkatan ${selectedYear}` : 'Semua Angkatan'} {/* Tampilkan ringkasan statistik */}
Total Mahasiswa
{stats.total}
Total Tingkat Prestasi
{stats.total_tingkat}
Total Tahun Angkatan
{stats.total_tahun_angkatan}
{/* Tampilkan ringkasan tingkat prestasi */}
{Object.entries(tingkatStats) .sort(([,a], [,b]) => b - a) // Urutkan berdasarkan jumlah mahasiswa terbanyak .map(([tingkat, count]) => ( {tingkat}: {count} ))}
{/* Show entries selector */}
Show entries
No NIM Nama Mahasiswa Tahun Angkatan Nama Prestasi Tingkat Prestasi {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.nama_prestasi} {mahasiswa.tingkat_prestasi} )) )}
{/* 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; // Skip first and last pages as they're always shown 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; } }