import React, { useState, useEffect, useMemo } from 'react'; import { Calendar, Users, BookOpen, Layout, Plus, Trash2, AlertCircle, Printer, CheckCircle, Clock, MapPin, ChevronRight, Menu, X, ShieldCheck, FileText, Search, AlertTriangle } from 'lucide-react'; // --- Constants & Seed Data --- const BRANCHES = [ { id: 'CE', name: 'Civil Engineering', lateral: false }, { id: 'CE-LE', name: 'Civil Engineering - Lateral Entry', lateral: true }, { id: 'PCE', name: 'Petro Chemical Engineering', lateral: false }, { id: 'PT', name: 'Paint Technology', lateral: false }, ]; const SEMESTERS = [ { no: 1, type: 'ODD' }, { no: 2, type: 'EVEN' }, { no: 3, type: 'ODD' }, { no: 4, type: 'EVEN' }, { no: 5, type: 'ODD' }, { no: 6, type: 'EVEN' }, ]; const DAYS = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT']; const TIME_SLOTS = [ { id: 1, label: 'Period 1', time: '10:00 - 11:00' }, { id: 2, label: 'Period 2', time: '11:00 - 12:00' }, { id: 3, label: 'Period 3', time: '12:00 - 13:00' }, { id: 'LUNCH', label: 'Lunch Break', time: '13:00 - 14:00', isBreak: true }, { id: 4, label: 'Period 4', time: '14:00 - 15:00' }, { id: 5, label: 'Period 5', time: '15:00 - 16:00' }, { id: 6, label: 'Period 6', time: '16:00 - 17:00' }, ]; const INITIAL_FACULTY = [ "Atul Kumar Sharma", "Namrata Pal", "Himmani Khandelwal", "Pushpendra Kumar", "Ashwani Kumar Mishra", "Subodh Saini", "Kanchan Kushwaha", "Bhupendra Pal Singh Yadav", "Anuradha Katiyar", "Vibha Verma", "Satyaveer Singh", "Vivek Kumar Singh", "Yatendra Kumar", "Alka Saxena", "Rajkumar Sharma", "Praveen Mishra", "Priya Sharma", "Shalini Rathore", "Radheshyam Sharma", "Nandkishore Saini", "Ambrikesh Mishra", "Lucky", "Vikas Kumar", "Ashok Kumar", "Hemant Kumar Sharma", "Rajkumar Kushwah", "Amit Kumar Sengar" ].map((name, i) => ({ id: i + 1, name, designation: i === 0 ? 'Principal' : (i === 4 ? 'H.O.D' : (i === 14 ? 'Workshop Superintendent' : 'Lecturer')) })); // Expanded Subjects for Phase 2 readiness const INITIAL_SUBJECTS = [ // Sem 1 & 2 (Common-ish) { id: 101, name: 'Mathematics-I', sem: 1, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 102, name: 'Applied Physics-I', sem: 1, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 103, name: 'Applied Chemistry', sem: 1, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 104, name: 'Communication Skills', sem: 1, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 105, name: 'Engineering Graphics', sem: 1, branches: ['CE', 'PCE', 'PT'], type: 'Practical' }, { id: 201, name: 'Mathematics-II', sem: 2, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 202, name: 'Applied Physics-II', sem: 2, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, { id: 203, name: 'Engineering Mechanics', sem: 2, branches: ['CE', 'PCE', 'PT'], type: 'Theory' }, // Sem 3 (Department Specific) { id: 301, name: 'Hydraulics', sem: 3, branches: ['CE', 'CE-LE'], type: 'Theory' }, { id: 302, name: 'Surveying-I', sem: 3, branches: ['CE', 'CE-LE'], type: 'Theory' }, { id: 303, name: 'Concrete Technology', sem: 3, branches: ['CE', 'CE-LE'], type: 'Theory' }, { id: 304, name: 'Chemical Process Calc', sem: 3, branches: ['PCE'], type: 'Theory' }, { id: 305, name: 'Fluid Flow', sem: 3, branches: ['PCE', 'PT'], type: 'Theory' }, { id: 306, name: 'Resins & Polymers', sem: 3, branches: ['PT'], type: 'Theory' }, // Sem 4 { id: 401, name: 'Soil Mechanics', sem: 4, branches: ['CE', 'CE-LE'], type: 'Theory' }, { id: 402, name: 'RCC Design', sem: 4, branches: ['CE', 'CE-LE'], type: 'Theory' }, { id: 403, name: 'Heat Transfer', sem: 4, branches: ['PCE', 'PT'], type: 'Theory' }, { id: 404, name: 'Mass Transfer', sem: 4, branches: ['PCE'], type: 'Theory' }, ]; // --- Main App Component --- export default function App() { const [activeTab, setActiveTab] = useState('dashboard'); const [selectedBranch, setSelectedBranch] = useState(BRANCHES[0]); const [selectedSem, setSelectedSem] = useState(1); const [timetable, setTimetable] = useState([]); const [notifications, setNotifications] = useState([]); // Filtered Subjects for current selection const availableSubjects = useMemo(() => { return INITIAL_SUBJECTS.filter(s => s.sem === selectedSem && s.branches.includes(selectedBranch.id)); }, [selectedSem, selectedBranch]); const addNotification = (msg, type = 'info', details = null) => { const id = Date.now(); setNotifications(prev => [...prev, { id, msg, type, details }]); setTimeout(() => setNotifications(prev => prev.filter(n => n.id !== id)), 6000); }; const handleAddEntry = (day, slotId, subjectId, facultyId, roomId) => { const faculty = INITIAL_FACULTY.find(f => f.id === parseInt(facultyId)); const subject = INITIAL_SUBJECTS.find(s => s.id === parseInt(subjectId)); // Conflict Check 1: Faculty busy in another branch/semester? const facultyConflict = timetable.find(e => e.day === day && e.slotId === slotId && e.facultyId === parseInt(facultyId)); if (facultyConflict) { const conflictBranch = BRANCHES.find(b => b.id === facultyConflict.branchId)?.name; addNotification( `Faculty Conflict!`, 'error', `${faculty?.name} is already assigned to ${conflictBranch} (Sem ${facultyConflict.sem}) in this slot.` ); return; } // Conflict Check 2: Room busy? if (roomId && roomId.trim() !== "") { const roomConflict = timetable.find(e => e.day === day && e.slotId === slotId && e.roomId.toLowerCase() === roomId.toLowerCase()); if (roomConflict) { const conflictBranch = BRANCHES.find(b => b.id === roomConflict.branchId)?.name; addNotification( `Room Conflict!`, 'error', `Room ${roomId} is occupied by ${conflictBranch} (Sem ${roomConflict.sem}).` ); return; } } // Conflict Check 3: Current Branch/Sem already has a class here? const classOverlap = timetable.find(e => e.day === day && e.slotId === slotId && e.branchId === selectedBranch.id && e.sem === selectedSem); if (classOverlap) { addNotification(`Schedule Overlap!`, 'error', `This branch and semester already have a class scheduled for this slot.`); return; } const newEntry = { id: Date.now(), branchId: selectedBranch.id, sem: selectedSem, day, slotId, subjectId: parseInt(subjectId), facultyId: parseInt(facultyId), roomId }; setTimetable(prev => [...prev, newEntry]); addNotification('Entry added successfully', 'success'); }; const removeEntry = (id) => { setTimetable(prev => prev.filter(e => e.id !== id)); }; // Views const Dashboard = () => (
} label="Total Branches" value={BRANCHES.length} color="bg-blue-500" /> } label="Active Faculty" value={INITIAL_FACULTY.length} color="bg-green-500" /> } label="Current Semester" value="Odd (2025-26)" color="bg-purple-500" /> } label="Global Conflicts" value={0} color="bg-orange-500" />

Branch Status

{BRANCHES.map(b => ( ))}
Branch Type Classes
{b.name} {b.lateral ? 'LATERAL' : 'REGULAR'} {timetable.filter(e => e.branchId === b.id).length} slots filled

Conflict Monitor

SYSTEM STABLE

No cross-departmental conflicts detected.

); const TimetableBuilder = () => { const [entryForm, setEntryForm] = useState(null); // Lateral Entry semester logic useEffect(() => { if (selectedBranch.lateral && selectedSem < 3) { setSelectedSem(3); } }, [selectedBranch]); return (
{/* Controls */}
{/* Grid View */}
{DAYS.map(day => ( ))} {TIME_SLOTS.map(slot => ( {DAYS.map(day => { const entry = timetable.find(e => e.day === day && e.slotId === slot.id && e.branchId === selectedBranch.id && e.sem === selectedSem); if (slot.isBreak) return ; return ( ); })} ))}
Time Slot
Schedule
{day}
{slot.label}
{slot.time}
LUNCH {entry ? (
300 ? 'bg-indigo-50 border-indigo-200 text-indigo-900' : 'bg-blue-50 border-blue-200 text-blue-900'}`}>
{INITIAL_SUBJECTS.find(s => s.id === entry.subjectId)?.name}
{INITIAL_FACULTY.find(f => f.id === entry.facultyId)?.name}
{entry.roomId && (
{entry.roomId}
)}
) : ( )}
{/* Add Entry Modal */} {entryForm && (

Schedule Slot

{entryForm.day} • {TIME_SLOTS.find(s => s.id === entryForm.slotId)?.time}

{ e.preventDefault(); const fd = new FormData(e.target); handleAddEntry(entryForm.day, entryForm.slotId, fd.get('subjectId'), fd.get('facultyId'), fd.get('roomId')); setEntryForm(null); }} className="space-y-5">
)}
); }; const FacultyView = () => (
{INITIAL_FACULTY.map(f => (
{f.name.split(' ').map(n => n[0]).join('')}
{f.name}
{f.designation}
))}

Workload Analysis

Detailed breakdown of teaching hours, administrative duties, and laboratory oversight.

Total Hours
24h
Labs
06h
Theory
18h
); return (
{/* Sidebar */} {/* Main Content Area */}
{/* Header */}

{activeTab === 'timetable' ? 'Academic Planner' : activeTab.replace('_', ' ')}

Manage institution-wide scheduling and resources.

System Time
Feb 2026 • Cycle 1
{/* Improved Notification System */}
{notifications.map(n => (
{n.type === 'error' ? : } {n.msg}
{n.details &&

{n.details}

}
))}
{/* Dynamic Views */}
{activeTab === 'dashboard' && } {activeTab === 'timetable' && } {activeTab === 'faculty' && } {activeTab === 'exams' && (

Sessional Hub

Schedule mid-term assessments and final practical exams for the current semester.

)}
{/* Global CSS for Print and Custom UI */}
); } // --- Sub-components --- function NavItem({ icon, label, active, onClick }) { return ( ); } function StatCard({ icon, label, value, color }) { return (
{icon}
{label}
{value}
); }