"use client"; import { useState, useEffect } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogClose } from "@/components/ui/dialog"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, } from "@/components/ui/pagination"; import { PlusCircle, Pencil, Trash2, Search, X, Loader2, BookOpen } from "lucide-react"; import UploadFileMataKuliah from "@/components/datatable/upload-file-mata-kuliah"; import { useToast } from "@/components/ui/toast-provider"; // Define the MataKuliah type interface MataKuliah { id_mk: number; kode_mk: string; nama_mk: string; sks: number; semester: number; jenis_mk: 'Wajib' | 'Pilihan Wajib' | 'Pilihan'; id_prasyarat: number | null; nama_prasyarat: string | null; created_at: string; updated_at: string; } export default function DataTableMataKuliah() { const { showSuccess, showError } = useToast(); // State for data const [mataKuliah, setMataKuliah] = useState([]); const [filteredData, setFilteredData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // State for filtering const [searchTerm, setSearchTerm] = useState(""); const [filterSemester, setFilterSemester] = useState(""); const [filterJenisMK, setFilterJenisMK] = useState(""); // State for pagination const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [paginatedData, setPaginatedData] = useState([]); // State for form const [formMode, setFormMode] = useState<"add" | "edit">("add"); const [formData, setFormData] = useState>({}); const [isSubmitting, setIsSubmitting] = useState(false); const [isDialogOpen, setIsDialogOpen] = useState(false); // State for delete confirmation const [deleteId, setDeleteId] = useState(null); const [isDeleting, setIsDeleting] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); // State for prasyarat options const [prasyaratOptions, setPrasyaratOptions] = useState([]); // Fetch data on component mount useEffect(() => { fetchMataKuliah(); }, []); // Filter data when search term or filter changes useEffect(() => { filterData(); }, [searchTerm, filterSemester, filterJenisMK, mataKuliah]); // Update paginated data when filtered data or pagination settings change useEffect(() => { paginateData(); }, [filteredData, currentPage, pageSize]); // Fetch mata kuliah data from API const fetchMataKuliah = async () => { try { setLoading(true); let url = "/api/keloladata/data-mata-kuliah"; // Add filters to URL if they exist const params = new URLSearchParams(); if (searchTerm) { params.append("search", searchTerm); } if (filterSemester && filterSemester !== "all") { params.append("semester", filterSemester); } if (params.toString()) { url += `?${params.toString()}`; } const response = await fetch(url); if (!response.ok) { throw new Error("Failed to fetch data"); } const data = await response.json(); setMataKuliah(data); setFilteredData(data); setPrasyaratOptions(data); // Set options for prasyarat dropdown setError(null); } catch (err) { setError("Error fetching data. Please try again later."); console.error("Error fetching data:", err); } finally { setLoading(false); } }; // Filter data based on search term and filters const filterData = () => { let filtered = [...mataKuliah]; // Filter by search term if (searchTerm) { filtered = filtered.filter( (item) => (item.kode_mk && item.kode_mk.toLowerCase().includes(searchTerm.toLowerCase())) || (item.nama_mk && item.nama_mk.toLowerCase().includes(searchTerm.toLowerCase())) ); } // Filter by semester if (filterSemester && filterSemester !== "all") { filtered = filtered.filter((item) => item.semester === parseInt(filterSemester)); } // Filter by jenis mata kuliah if (filterJenisMK && filterJenisMK !== "all") { filtered = filtered.filter((item) => item.jenis_mk === filterJenisMK); } setFilteredData(filtered); // Reset to first page when filters change setCurrentPage(1); }; // Paginate data const paginateData = () => { const startIndex = (currentPage - 1) * pageSize; const endIndex = startIndex + pageSize; setPaginatedData(filteredData.slice(startIndex, endIndex)); }; // Get total number of pages const getTotalPages = () => { return Math.ceil(filteredData.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 }; // Reset form data const resetForm = () => { setFormData({ jenis_mk: 'Wajib' // Set default value }); }; // Handle form input changes const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value })); }; // Handle select input changes const handleSelectChange = (name: string, value: string) => { setFormData((prev) => ({ ...prev, [name]: value === "none" || value === "" ? null : (name === 'id_prasyarat' ? parseInt(value) : value) })); }; // Open form dialog for adding new mata kuliah const handleAdd = () => { setFormMode("add"); resetForm(); setIsDialogOpen(true); }; // Open form dialog for editing mata kuliah const handleEdit = (data: MataKuliah) => { setFormMode("edit"); setFormData(data); setIsDialogOpen(true); }; // Open delete confirmation dialog const handleDeleteConfirm = (id: number) => { setDeleteId(id); setIsDeleteDialogOpen(true); }; // Submit form for add/edit const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { setIsSubmitting(true); if (formMode === "add") { // Add new mata kuliah const response = await fetch("/api/keloladata/data-mata-kuliah", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(formData), }); const responseData = await response.json(); if (!response.ok) { showError("Gagal!", responseData.message || "Failed to add mata kuliah"); throw new Error(responseData.message || "Failed to add mata kuliah"); } showSuccess("Berhasil!", "Mata kuliah berhasil ditambahkan"); } else { // Edit existing mata kuliah const response = await fetch(`/api/keloladata/data-mata-kuliah?id=${formData.id_mk}`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(formData), }); const responseData = await response.json(); if (!response.ok) { showError("Gagal!", responseData.message || "Failed to update mata kuliah"); throw new Error(responseData.message || "Failed to update mata kuliah"); } showSuccess("Berhasil!", "Mata kuliah berhasil diperbarui"); } // Refresh data after successful operation await fetchMataKuliah(); setIsDialogOpen(false); resetForm(); } catch (err) { console.error("Error submitting form:", err); } finally { setIsSubmitting(false); } }; // Delete mata kuliah const handleDelete = async () => { if (!deleteId) return; try { setIsDeleting(true); const response = await fetch(`/api/keloladata/data-mata-kuliah?id=${deleteId}`, { method: "DELETE", }); const responseData = await response.json(); if (!response.ok) { showError("Gagal!", responseData.message || "Failed to delete mata kuliah"); throw new Error(responseData.message || "Failed to delete mata kuliah"); } // Refresh data after successful deletion await fetchMataKuliah(); setIsDeleteDialogOpen(false); setDeleteId(null); showSuccess("Berhasil!", "Mata kuliah berhasil dihapus"); } catch (err) { console.error("Error deleting mata kuliah:", err); } finally { setIsDeleting(false); } }; // Generate pagination items const 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; }; // Calculate the range of entries being displayed const getDisplayRange = () => { if (filteredData.length === 0) return { start: 0, end: 0 }; const start = (currentPage - 1) * pageSize + 1; const end = Math.min(currentPage * pageSize, filteredData.length); return { start, end }; }; // Get badge color based on semester const getSemesterBadgeColor = (semester: number) => { const colors = [ "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300", "bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300", "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300", "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300", "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300", "bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-300", "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300", "bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300" ]; return colors[(semester - 1) % colors.length] || "bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300"; }; // Get badge color based on jenis mata kuliah const getJenisMKBadgeColor = (jenis: string) => { switch (jenis) { case "Wajib": return "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300"; case "Pilihan Wajib": return "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300"; case "Pilihan": return "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"; default: return "bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300"; } }; return (

Data Mata Kuliah

{/* Filters */}
setSearchTerm(e.target.value)} /> {searchTerm && ( setSearchTerm("")} /> )}
{/* Show entries selector */}
Show entries
{/* Table */} {loading ? (
) : error ? (
{error}
) : (
Kode MK Nama Mata Kuliah SKS Semester Jenis MK Prasyarat Aksi {paginatedData.length === 0 ? ( Tidak ada data yang sesuai dengan filter ) : ( paginatedData.map((mk) => ( {mk.kode_mk} {mk.nama_mk} {mk.sks} Semester {mk.semester} {mk.jenis_mk} {mk.nama_prasyarat || '-'}
)) )}
)} {/* Pagination info and controls */} {!loading && !error && filteredData.length > 0 && (
Showing {getDisplayRange().start} to {getDisplayRange().end} of {filteredData.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"} />
)} {/* Add/Edit Dialog */} {formMode === "add" ? "Tambah Mata Kuliah" : "Edit Mata Kuliah"}
{/* Delete Confirmation Dialog */} Konfirmasi Hapus

Apakah Anda yakin ingin menghapus mata kuliah ini?

Tindakan ini tidak dapat dibatalkan.

); }