From 86682ce7c307389d16958cfed3273ea7fc6b772c Mon Sep 17 00:00:00 2001 From: "[Valentino Heman Budiarto]" <[hemanvalentino@gmail.com]> Date: Mon, 22 Jun 2026 16:50:24 +0700 Subject: [PATCH] jadwal --- frontend/app/admin/schedules/page.tsx | 241 +++++++++++++++++++++++--- 1 file changed, 220 insertions(+), 21 deletions(-) diff --git a/frontend/app/admin/schedules/page.tsx b/frontend/app/admin/schedules/page.tsx index 8ff986e..4e8f01d 100644 --- a/frontend/app/admin/schedules/page.tsx +++ b/frontend/app/admin/schedules/page.tsx @@ -2,12 +2,26 @@ import { useEffect, useState } from "react"; import axios from "axios"; -import { CalendarDays, Plus, Trash2, Clock, MapPin, LayoutList, Calendar } from "lucide-react"; +import { CalendarDays, Plus, Trash2, Clock, MapPin, LayoutList, Calendar, Edit, X, Save } from "lucide-react"; export default function SchedulesPage() { const [schedules, setSchedules] = useState([]); const [loading, setLoading] = useState(true); - const [viewMode, setViewMode] = useState<"table" | "calendar">("table"); // State untuk pindah mode + const [viewMode, setViewMode] = useState<"table" | "calendar">("table"); + + // STATE UNTUK MODAL FORM (TAMBAH & EDIT) + const [isModalOpen, setIsModalOpen] = useState(false); + const [isSaving, setIsSaving] = useState(false); + const [formData, setFormData] = useState({ + schedule_id: null as number | null, + kode_mk: "", + nama_mk: "", + room_id: 1, // Default Kelas D101 + hari: "Senin", + jam_mulai: "", + jam_selesai: "", + jumlah_sks: 2, + }); const hariUrutan = ["Senin", "Selasa", "Rabu", "Kamis", "Jumat"]; const listJam = ["07:00", "08:00", "09:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00"]; @@ -31,7 +45,92 @@ export default function SchedulesPage() { } }; - // Helper untuk mengecek apakah ada matkul di hari dan jam tertentu (Untuk Mode Kalender) + // ========================================================================= + // FUNGSI CRUD (TAMBAH, EDIT, HAPUS) + // ========================================================================= + + // 1. Buka Modal untuk Tambah Baru + const handleAddClick = () => { + setFormData({ + schedule_id: null, + kode_mk: "", + nama_mk: "", + room_id: 1, + hari: "Senin", + jam_mulai: "07:00", + jam_selesai: "08:40", + jumlah_sks: 2, + }); + setIsModalOpen(true); + }; + + // 2. Buka Modal untuk Edit Data Lama + const handleEditClick = (sched: any) => { + setFormData({ + schedule_id: sched.schedule_id, + kode_mk: sched.kode_mk, + nama_mk: sched.nama_mk, + room_id: sched.room_id, + hari: sched.hari, + jam_mulai: sched.jam_mulai.substring(0, 5), // Potong detik jika ada (07:00:00 -> 07:00) + jam_selesai: sched.jam_selesai.substring(0, 5), + jumlah_sks: sched.jumlah_sks || 2, + }); + setIsModalOpen(true); + }; + + // 3. Simpan Data (Create atau Update ke Backend) + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setIsSaving(true); + try { + const token = localStorage.getItem("token"); + const headers = { Authorization: `Bearer ${token}` }; + + // Format ulang jam agar aman (tambahkan detik 00) + const payload = { + ...formData, + jam_mulai: formData.jam_mulai.length === 5 ? `${formData.jam_mulai}:00` : formData.jam_mulai, + jam_selesai: formData.jam_selesai.length === 5 ? `${formData.jam_selesai}:00` : formData.jam_selesai, + jumlah_sks: Number(formData.jumlah_sks) + }; + + if (formData.schedule_id) { + // UPDATE (PUT) + await axios.put(`http://172.17.172.17:8080/api/schedules/${formData.schedule_id}`, payload, { headers }); + alert("Jadwal berhasil diperbarui!"); + } else { + // CREATE BARU (POST) + await axios.post("http://172.17.172.17:8080/api/schedules", payload, { headers }); + alert("Jadwal baru berhasil ditambahkan!"); + } + + setIsModalOpen(false); + fetchSchedules(); // Refresh data di tabel + } catch (err: any) { + console.error("Gagal menyimpan jadwal:", err); + alert("Gagal menyimpan data: " + (err.response?.data?.error || err.message)); + } finally { + setIsSaving(false); + } + }; + + // 4. Hapus Data (Delete) + const handleDelete = async (id: number, namaMK: string) => { + if (!window.confirm(`Apakah Anda yakin ingin menghapus jadwal mata kuliah ${namaMK}?`)) return; + + try { + const token = localStorage.getItem("token"); + await axios.delete(`http://172.17.172.17:8080/api/schedules/${id}`, { + headers: { Authorization: `Bearer ${token}` } + }); + alert("Jadwal berhasil dihapus!"); + fetchSchedules(); + } catch (err: any) { + alert("Gagal menghapus jadwal."); + } + }; + const getMatkulDiSlot = (hari: string, jam: string) => { return schedules.find((s) => { if (s.hari !== hari) return false; @@ -59,6 +158,14 @@ export default function SchedulesPage() {
+ {/* Tombol Tambah Jadwal */} + + {/* Toggle View Mode */}
-
@@ -88,8 +194,8 @@ export default function SchedulesPage() { Kode MK Mata Kuliah Ruangan - Hari - Waktu + Hari & Waktu + SKS Aksi @@ -97,24 +203,38 @@ export default function SchedulesPage() { {schedules.length > 0 ? ( schedules.map((sched) => ( - {sched.kode_mk} - {sched.nama_mk} - - Kelas D101 - - - {sched.hari} + {sched.kode_mk} + {sched.nama_mk} + + Kelas D101 -
- +
{sched.hari}
+
+ {sched.jam_mulai.substring(0, 5)} - {sched.jam_selesai.substring(0, 5)}
- - + + {sched.jumlah_sks} + + +
+ + +
)) @@ -149,7 +269,11 @@ export default function SchedulesPage() { return (
{mtk ? ( -
+
handleEditClick(mtk)} + className="bg-blue-50 border-l-4 border-blue-600 p-2 rounded text-left shadow-xs h-full flex flex-col justify-between cursor-pointer hover:bg-blue-100 transition-colors" + title="Klik untuk Edit" + > {mtk.nama_mk} {mtk.kode_mk}
@@ -166,7 +290,82 @@ export default function SchedulesPage() {
)} - + + {/* ==================================== MODAL FORM CRUD ==================================== */} + {isModalOpen && ( +
+
+
+

+ {formData.schedule_id ? "Edit Jadwal Kuliah" : "Tambah Jadwal Kuliah Baru"} +

+ +
+ +
+
+
+ + setFormData({...formData, kode_mk: e.target.value.toUpperCase()})} + className="w-full border border-gray-300 rounded-lg p-2.5 text-sm focus:ring-2 focus:ring-blue-500 outline-none uppercase" + placeholder="Contoh: EE153" + /> +
+
+ + setFormData({...formData, jumlah_sks: Number(e.target.value)})} + className="w-full border border-gray-300 rounded-lg p-2.5 text-sm focus:ring-2 focus:ring-blue-500 outline-none" + /> +
+
+ +
+ + setFormData({...formData, nama_mk: e.target.value})} + className="w-full border border-gray-300 rounded-lg p-2.5 text-sm focus:ring-2 focus:ring-blue-500 outline-none" + placeholder="Contoh: Elektronika dan Sistem Digital" + /> +
+ +
+ + +
+ +
+
+ + setFormData({...formData, jam_mulai: e.target.value})} + className="w-full border border-gray-300 rounded-lg p-2.5 text-sm focus:ring-2 focus:ring-blue-500 outline-none" + /> +
+
+ + setFormData({...formData, jam_selesai: e.target.value})} + className="w-full border border-gray-300 rounded-lg p-2.5 text-sm focus:ring-2 focus:ring-blue-500 outline-none" + /> +
+
+ +
+ + +
+
+
+
+ )} +
); } \ No newline at end of file