"use client"; import { useEffect, useState } from "react"; import axios from "axios"; import { CalendarDays, MapPin, Clock, ChevronLeft, ChevronRight, Calendar as CalendarIcon } from "lucide-react"; export default function CalendarViewPage() { const [bookings, setBookings] = useState([]); const [rooms, setRooms] = useState([]); const [schedules, setSchedules] = useState([]); // 1. STATE BARU UNTUK JADWAL KULIAH const [loading, setLoading] = useState(true); // --- STATE UNTUK NAVIGASI MINGGU --- const [startDate, setStartDate] = useState(() => { const d = new Date(); d.setHours(0, 0, 0, 0); return d; }); // Generate 7 Hari ke depan berdasarkan startDate const weekDates = Array.from({ length: 7 }).map((_, i) => { const d = new Date(startDate); d.setDate(startDate.getDate() + i); return d; }); // FORMAT RENTANG TANGGAL const firstDay = weekDates[0].toLocaleDateString('id-ID', { day: 'numeric', month: 'short' }); const lastDay = weekDates[6].toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' }); const dateRangeLabel = `${firstDay} - ${lastDay}`; // Fungsi Navigasi const goToPreviousWeek = () => { setStartDate(prev => { const newDate = new Date(prev); newDate.setDate(prev.getDate() - 7); return newDate; }); }; const goToNextWeek = () => { setStartDate(prev => { const newDate = new Date(prev); newDate.setDate(prev.getDate() + 7); return newDate; }); }; const goToToday = () => { const d = new Date(); d.setHours(0, 0, 0, 0); setStartDate(d); }; useEffect(() => { const fetchData = async () => { try { const token = localStorage.getItem("token"); // 2. FETCH DATA SCHEDULES BERSAMAAN DENGAN ROOMS & BOOKINGS const [roomsRes, bookingsRes, schedulesRes] = await Promise.all([ axios.get("http://172.17.110.6:8080/api/rooms", { headers: { Authorization: `Bearer ${token}` } }), axios.get("http://172.17.110.6:8080/api/bookings", { headers: { Authorization: `Bearer ${token}` } }), axios.get("http://172.17.110.6:8080/api/schedules", { headers: { Authorization: `Bearer ${token}` } }) ]); setRooms(roomsRes.data.data || []); setBookings(bookingsRes.data.data || []); setSchedules(schedulesRes.data.data || []); } catch (error) { console.error("Gagal memuat data", error); } finally { setLoading(false); } }; fetchData(); }, []); // Fungsi memfilter booking dinamis const getBookingsForCell = (roomId: number, dateObj: Date) => { return bookings.filter(b => { if (b.room_id !== roomId) return false; const bDate = new Date(b.start_time); return ( bDate.getDate() === dateObj.getDate() && bDate.getMonth() === dateObj.getMonth() && bDate.getFullYear() === dateObj.getFullYear() ); }); }; // 3. FUNGSI BARU: Memfilter jadwal statis berdasarkan hari const getSchedulesForCell = (roomId: number, dateObj: Date) => { const namaHari = ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"]; const hariIni = namaHari[dateObj.getDay()]; return schedules.filter(s => s.room_id === roomId && s.hari === hariIni); }; // Format Jam const formatTime = (isoString: string) => { return new Date(isoString).toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' }); }; if (loading) return
Menyusun matriks jadwal...
; return (
{/* HEADER & NAVIGASI */}

Weekly Calendar View

Pantau kepadatan jadwal ruangan S-CLASS.

{/* Kontrol Navigasi Minggu */}
{/* Pembungkus Tabel */}
{/* HEADER TABEL: Sumbu X (Tanggal) */} {weekDates.map((date, idx) => ( ))} {/* BODY TABEL: Sumbu Y (Ruangan) */} {[...rooms] .sort((a, b) => a.name.localeCompare(b.name)) .map((room) => ( {weekDates.map((date, idx) => { const dailyBookings = getBookingsForCell(room.room_id, date); const dailySchedules = getSchedulesForCell(room.room_id, date); // Ambil jadwal kuliah hari ini return ( ); })} ))}
Ruangan
{date.toLocaleDateString('id-ID', { weekday: 'long' })}
{date.toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric' })}
{room.name}
{room.category}
{(dailyBookings.length > 0 || dailySchedules.length > 0) ? (
{/* 4. RENDER JADWAL KULIAH STATIS (Tampil Paling Atas, Warna Abu-abu) */} {dailySchedules .sort((a, b) => a.jam_mulai.localeCompare(b.jam_mulai)) .map((s, i) => (

[KULIAH] {s.nama_mk}

{s.jam_mulai.substring(0, 5)} - {s.jam_selesai.substring(0, 5)} {s.kode_mk}
)) } {/* 5. RENDER BOOKING DINAMIS MAHASISWA */} {dailyBookings .filter((b) => b.status === "Pending" || b.status === "Approved") .sort((a, b) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime()) .map((b) => (

{b.purpose}

{formatTime(b.start_time)} - {formatTime(b.end_time)} {b.status || 'Pending'}
))}
) : (
-
)}
); }