import React, { useState, useMemo } from 'react'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell, Legend } from 'recharts'; import { DashboardStats, JournalEntry, ClassJournalEntry } from '../types'; import { Calendar as CalendarIcon, Users, Book, TrendingUp, ChevronLeft, ChevronRight, GraduationCap, Briefcase, BarChart2, Filter, X, Clock } from 'lucide-react'; interface DashboardProps { stats: DashboardStats; teacherEntries: JournalEntry[]; classEntries: ClassJournalEntry[]; } const Dashboard: React.FC = ({ stats, teacherEntries, classEntries }) => { // Use "today" as default selected date if it has entries, otherwise null or today const [currentDate, setCurrentDate] = useState(new Date()); const [selectedDate, setSelectedDate] = useState(new Date()); // Default to today const months = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"]; const getCalendarDays = () => { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); const firstDay = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); const days = []; for (let i = 0; i < firstDay; i++) days.push(null); for (let i = 1; i <= daysInMonth; i++) days.push(i); return days; }; const changeMonth = (offset: number) => { setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + offset, 1)); }; const hasEntryOnDate = (day: number) => { const year = currentDate.getFullYear(); const month = currentDate.getMonth() + 1; const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`; return teacherEntries.some(e => e.date === dateStr) || classEntries.some(e => e.date === dateStr); }; const isSelectedDay = (day: number) => { if (!selectedDate) return false; return ( selectedDate.getDate() === day && selectedDate.getMonth() === currentDate.getMonth() && selectedDate.getFullYear() === currentDate.getFullYear() ); }; const handleDayClick = (day: number) => { if (!day) return; const newDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), day); setSelectedDate(newDate); }; // 1. "Kehadiran Guru per hari" Dashboard Logic const dailyStats = useMemo(() => { const targetDate = selectedDate || new Date(); const dateStr = targetDate.toISOString().split('T')[0]; // Count teachers present in class entries for this date const presentTeachers = new Set( classEntries .filter(ce => ce.date === dateStr && (ce.teacherPresence === 'Hadir' || ce.teacherPresence === 'Tugas')) .map(ce => ce.teacherName) ).size; // Latest activities for this day (from both teacher and class journals) const dailyActivities = [ ...teacherEntries.filter(te => te.date === dateStr).map(te => ({ ...te, type: 'teacher' })), ...classEntries.filter(ce => ce.date === dateStr).map(ce => ({ ...ce, type: 'class' })) ].sort((a, b) => new Date(b.id.split('-')[1]).getTime() - new Date(a.id.split('-')[1]).getTime()); // Class performance for this specific day const classPerfMap: Record = {}; classEntries.filter(ce => ce.date === dateStr).forEach(ce => { if (!classPerfMap[ce.className]) classPerfMap[ce.className] = { present: 0, absent: 0 }; classPerfMap[ce.className].present += Number(ce.studentsPresent) || 0; classPerfMap[ce.className].absent += Number(ce.studentsAbsent) || 0; }); const dailyClassPerformance = Object.keys(classPerfMap).map(name => ({ name, present: classPerfMap[name].present, absent: classPerfMap[name].absent })).sort((a, b) => a.name.localeCompare(b.name)); return { presentTeachers, dailyActivities, dailyClassPerformance, dateStr }; }, [selectedDate, teacherEntries, classEntries]); // Transform Weekly Stats for Chart (Calculated per date trend) const weeklyData = useMemo(() => { const daysMap = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab']; const now = new Date(); const currentWeekData = daysMap.map((day, idx) => { // Find date for this day of current week const diff = idx - now.getDay(); const targetDay = new Date(now); targetDay.setDate(now.getDate() + diff); const targetDateStr = targetDay.toISOString().split('T')[0]; const count = classEntries.filter(ce => ce.date === targetDateStr && (ce.teacherPresence === 'Hadir' || ce.teacherPresence === 'Tugas') ).length; return { day, count }; }); return currentWeekData; }, [classEntries]); return (
{/* Header Stats Cards */}

Total Jurnal Guru

{stats.totalEntries}

Kehadiran Guru (Harian)

{dailyStats.presentTeachers}

Tgl: {dailyStats.dateStr}

Hari Aktif (Sistem)

{stats.weeklyActivity.filter(w => w.count > 0).length}

{/* Left Column: Charts */}
{/* Teacher Activity Chart based on Class Journal */}

Grafik Kehadiran Guru Mengajar

Jumlah kehadiran guru berdasarkan entri sekretaris minggu ini

{weeklyData.map((entry, index) => ( ))}
{/* Class Performance Chart for Selected Date */}

Grafik Statistik Per Kelas ({dailyStats.dateStr})

Perbandingan kehadiran siswa per kelas pada tanggal yang dipilih

{dailyStats.dailyClassPerformance.length > 0 ? (
) : (
Tidak ada data kehadiran kelas untuk tanggal ini
)}
{/* Right Column: Calendar & Filtered Activity List */}
{/* Calendar Widget */}

Kalender

{months[currentDate.getMonth()]} {currentDate.getFullYear()}
{['M', 'S', 'S', 'R', 'K', 'J', 'S'].map((d, i) => ( {d} ))}
{getCalendarDays().map((day, idx) => { const isSelected = day ? isSelectedDay(day) : false; const hasEntry = day ? hasEntryOnDate(day) : false; return (
day && handleDayClick(day)} className={`aspect-square flex flex-col items-center justify-center rounded-lg text-xs transition-all cursor-pointer ${isSelected ? 'bg-school-900 text-white shadow-md' : 'hover:bg-blue-50'} ${hasEntry && !isSelected ? 'text-school-900 font-bold border border-blue-100 bg-blue-50/50' : ''} ${!day ? 'opacity-0 cursor-default' : ''} `} > {day} {hasEntry && (
)}
); })}
{/* New Requirement: Daily Activity List */}

Aktivitas Terbaru

Filter: {dailyStats.dateStr}

{dailyStats.dailyActivities.length === 0 ? (

Tidak ada aktivitas pada tanggal ini

) : ( dailyStats.dailyActivities.map((entry: any) => (
{entry.className.split(' ')[0]}

{entry.subject}

{entry.teacherName}

{entry.type === 'teacher' ? 'Jurnal Guru' : 'Jurnal Kelas'} • {entry.startTime}

)) )}
{selectedDate && ( )}
{/* Detail Table */}

Detail Aktivitas Jurnal ({dailyStats.dateStr})

{dailyStats.dailyActivities.length === 0 ? ( ) : ( dailyStats.dailyActivities.map((entry: any) => ( )) )}
Tipe Guru Kelas Materi/Catatan Status/Siswa
Tidak ada aktivitas.
{entry.type === 'teacher' ? 'Guru' : 'Kelas'} {entry.teacherName} {entry.className} {entry.type === 'teacher' ? entry.topic : entry.notes || '-'} {entry.type === 'teacher' ? (
{entry.studentsPresent} / {entry.studentsAbsent}
) : ( {entry.teacherPresence} )}
); }; export default Dashboard;