import { useEffect, useState } from 'react'; import { DashboardTab } from './components/DashboardTab'; import { ClassesTab } from './components/ClassesTab'; import { StudentsTab } from './components/StudentsTab'; import { LearningTab } from './components/LearningTab'; import { ExamsTab } from './components/ExamsTab'; import { ExamRoomWorkspace } from './components/ExamRoomWorkspace'; import { SystemTab } from './components/SystemTab'; import { MyAccountTab } from './components/AccountsTab'; import { StudentAffairsTab } from './components/StudentAffairsTab'; import { ApplicationsTab } from './components/ApplicationsTab'; import { ChatWidget } from './components/ChatWidget'; import { StaffChatSocket } from './hooks/useStaffChatSocket'; import { ClassWorkspace } from './components/ClassWorkspace'; import { NavHistoryBar, useRoute } from './components/NavHistoryBar'; import { goBack, navigate, navigateSystem, parseRoute, pushNav, SYSTEM_SECTION_LABELS, TAB_LABELS, type SystemSection, type TabId, } from './navigation'; import { useAuth } from './auth/AuthContext'; const IconDashboard = () => ( ); const IconClass = () => ( ); const IconStudent = () => ( ); const IconLearning = () => ( ); const IconExam = () => ( ); const IconSystem = () => ( ); const IconStudentAffairs = () => ( ); const IconApplications = () => ( ); const IconMenu = () => ( ); const SYSTEM_NAV: { section: SystemSection }[] = [ { section: 'organization' }, { section: 'network' }, { section: 'templates' }, { section: 'seating' }, ]; function App() { const route = useRoute(); const { staff, logout } = useAuth(); const [sidebarOpen, setSidebarOpen] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useState(() => { return localStorage.getItem('sc_sidebar_collapsed') === 'true'; }); const toggleSidebarCollapse = () => { // On mobile (<=900px), just close the sidebar overlay if (window.innerWidth <= 900) { setSidebarOpen(false); return; } // On desktop, toggle collapsed state const nextVal = !sidebarCollapsed; setSidebarCollapsed(nextVal); localStorage.setItem('sc_sidebar_collapsed', String(nextVal)); }; const [myClasses, setMyClasses] = useState<{ id: number; name: string; code: string }[]>(() => { try { const stored = localStorage.getItem('sc_my_classes_details'); return stored ? JSON.parse(stored) : []; } catch { return []; } }); useEffect(() => { const handleUpdate = () => { try { const stored = localStorage.getItem('sc_my_classes_details'); setMyClasses(stored ? JSON.parse(stored) : []); } catch (e) { } }; window.addEventListener('my-classes-updated', handleUpdate); return () => window.removeEventListener('my-classes-updated', handleUpdate); }, []); useEffect(() => { const initial = parseRoute(); if (initial.classId || initial.examId) { return; } const label = initial.tab === 'system' ? `Hệ thống · ${SYSTEM_SECTION_LABELS[initial.systemSection]}` : TAB_LABELS[initial.tab]; pushNav({ kind: 'tab', tab: initial.tab, systemSection: initial.tab === 'system' ? initial.systemSection : undefined, label, }); }, []); useEffect(() => { setSidebarOpen(false); }, [route.tab, route.classId, route.examId, route.systemSection]); const setActiveTab = (tab: string) => { navigate(tab as TabId); setSidebarOpen(false); }; const handleBackFromWorkspace = () => { goBack(route.tab); }; const inWorkspace = Boolean(route.classId || route.examId); const classesActive = route.tab === 'classes'; const learningActive = route.tab === 'learning'; const examsActive = route.tab === 'exams' || route.examId != null; const systemActive = route.tab === 'system' && !inWorkspace; const goSystem = (section: SystemSection) => { navigateSystem(section); setSidebarOpen(false); }; const navBtn = (active: boolean) => `nav-btn${active ? ' active' : ''}`; return ( <> setSidebarOpen(true)} > {sidebarOpen && ( setSidebarOpen(false)} /> )} {route.classId ? ( ( )} /> ) : route.examId ? ( ) : ( <> {route.tab === 'dashboard' && } {route.tab === 'classes' && } {route.tab === 'students' && } {route.tab === 'learning' && } {route.tab === 'exams' && } {route.tab === 'system' && } {route.tab === 'profile' && } {route.tab === 'student-affairs' && } {route.tab === 'applications' && } > )} > ); } export default App;