fix: correct Material UI icon naming in Header.tsx and update timetable components

- Fix icon naming: remove 'Icon' suffix from MUI icon components in Header.tsx
  (AccessTime, Close, Person, School, Schedule, Class, Book, Settings, Student, Login, Logout)
- Update timetable components to use UserContext instead of ProfileContext
- Fix timetableService naming collision and circular reference
- Update various components for consistency
This commit is contained in:
Agent Zero 2026-02-26 07:28:47 +00:00
parent 00a6f941c7
commit 067df34c50
16 changed files with 123 additions and 122 deletions

View File

@ -1,5 +1,5 @@
import React from 'react';
import { CloseIcon } from '@mui/icons-material';
import Close from '@mui/icons-material/Close';
interface ModalProps {
isOpen: boolean;
@ -32,7 +32,7 @@ const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children, maxWidt
onClick={onClose}
className="text-gray-400 hover:text-gray-500 focus:outline-none"
>
<CloseIcon size={20} />
<Close sx={{ fontSize: 20 }} />
</button>
</div>

View File

@ -15,27 +15,24 @@ import {
Divider
} from '@mui/material';
import MenuIcon from '@mui/icons-material/Menu';
import {
Login as LoginIcon,
Logout as LogoutIcon,
School as TeacherIcon,
Person as StudentIcon,
Dashboard as TLDrawDevIcon,
Build as DevToolsIcon,
Groups as MultiplayerIcon,
CalendarToday as CalendarIcon,
Assignment as TeacherPlannerIcon,
AssignmentTurnedIn as ExamMarkerIcon,
Settings as SettingsIcon,
Search as SearchIcon,
AdminPanelSettings as AdminIcon,
Home as HomeIcon,
// Timetable icons
Schedule as ScheduleIcon,
Class as ClassIcon,
Book as BookIcon,
HowToReg as EnrollmentIcon
} from '@mui/icons-material';
import Login from '@mui/icons-material/Login';
import Logout from '@mui/icons-material/Logout';
import Teacher from '@mui/icons-material/School';
import Student from '@mui/icons-material/Person';
import TLDrawDev from '@mui/icons-material/Dashboard';
import DevTools from '@mui/icons-material/Build';
import Multiplayer from '@mui/icons-material/Groups';
import Calendar from '@mui/icons-material/CalendarToday';
import TeacherPlanner from '@mui/icons-material/Assignment';
import ExamMarker from '@mui/icons-material/AssignmentTurnedIn';
import Settings from '@mui/icons-material/Settings';
import Search from '@mui/icons-material/Search';
import Admin from '@mui/icons-material/AdminPanelSettings';
import Home from '@mui/icons-material/Home';
import Schedule from '@mui/icons-material/Schedule';
import Class from '@mui/icons-material/Class';
import Book from '@mui/icons-material/Book';
import Enrollment from '@mui/icons-material/HowToReg';
import { HEADER_HEIGHT } from './Layout';
import { logger } from '../debugConfig';
import { GraphNavigator } from '../components/navigation/GraphNavigator';
@ -127,7 +124,7 @@ const Header: React.FC = () => {
}}
onClick={() => handleNavigation('/')}
>
<HomeIcon sx={{ color: theme.palette.primary.main }} />
<Home sx={{ color: theme.palette.primary.main }} />
Classroom Copilot
</Typography>
@ -156,7 +153,7 @@ const Header: React.FC = () => {
}
}}
>
<MenuIcon />
<Menu />
</IconButton>
<Menu
@ -189,7 +186,7 @@ const Header: React.FC = () => {
// Home
<MenuItem key="home" onClick={() => handleNavigation('/')}>
<ListItemIcon>
<HomeIcon />
<Home />
</ListItemIcon>
<ListItemText primary="Home" />
</MenuItem>,
@ -213,7 +210,7 @@ const Header: React.FC = () => {
</Typography>,
<MenuItem key="timetable" onClick={() => handleNavigation('/timetable')}>
<ListItemIcon>
<ScheduleIcon />
<Schedule />
</ListItemIcon>
<ListItemText
primary="My Timetable"
@ -222,7 +219,7 @@ const Header: React.FC = () => {
</MenuItem>,
<MenuItem key="classes" onClick={() => handleNavigation('/classes')}>
<ListItemIcon>
<ClassIcon />
<Class />
</ListItemIcon>
<ListItemText
primary="Browse Classes"
@ -231,7 +228,7 @@ const Header: React.FC = () => {
</MenuItem>,
<MenuItem key="my-classes" onClick={() => handleNavigation('/my-classes')}>
<ListItemIcon>
<BookIcon />
<Book />
</ListItemIcon>
<ListItemText
primary="My Classes"
@ -240,7 +237,7 @@ const Header: React.FC = () => {
</MenuItem>,
<MenuItem key="enrollment-requests" onClick={() => handleNavigation('/enrollment-requests')}>
<ListItemIcon>
<EnrollmentIcon />
<Enrollment />
</ListItemIcon>
<ListItemText
primary="Enrollment Requests"
@ -267,19 +264,19 @@ const Header: React.FC = () => {
</Typography>,
<MenuItem key="calendar" onClick={() => handleNavigation('/calendar')}>
<ListItemIcon>
<CalendarIcon />
<Calendar />
</ListItemIcon>
<ListItemText primary="Calendar" />
</MenuItem>,
<MenuItem key="teacher-planner" onClick={() => handleNavigation('/teacher-planner')}>
<ListItemIcon>
<TeacherPlannerIcon />
<TeacherPlanner />
</ListItemIcon>
<ListItemText primary="Teacher Planner" />
</MenuItem>,
<MenuItem key="exam-marker" onClick={() => handleNavigation('/exam-marker')}>
<ListItemIcon>
<ExamMarkerIcon />
<ExamMarker />
</ListItemIcon>
<ListItemText primary="Exam Marker" />
</MenuItem>,
@ -303,13 +300,13 @@ const Header: React.FC = () => {
</Typography>,
<MenuItem key="settings" onClick={() => handleNavigation('/settings')}>
<ListItemIcon>
<SettingsIcon />
<Settings />
</ListItemIcon>
<ListItemText primary="Settings" />
</MenuItem>,
<MenuItem key="search" onClick={() => handleNavigation('/search')}>
<ListItemIcon>
<SearchIcon />
<Search />
</ListItemIcon>
<ListItemText primary="Search" />
</MenuItem>,
@ -334,7 +331,7 @@ const Header: React.FC = () => {
</Typography>,
<MenuItem key="admin" onClick={() => handleNavigation('/admin')}>
<ListItemIcon>
<AdminIcon />
<Admin />
</ListItemIcon>
<ListItemText primary="Admin Dashboard" />
</MenuItem>
@ -344,7 +341,7 @@ const Header: React.FC = () => {
<Divider key="auth-divider" />,
<MenuItem key="signout" onClick={handleSignOut}>
<ListItemIcon>
<LogoutIcon />
<Logout />
</ListItemIcon>
<ListItemText primary="Sign Out" />
</MenuItem>
@ -352,14 +349,14 @@ const Header: React.FC = () => {
// Authentication Section for Non-authenticated Users
<MenuItem key="signin" onClick={() => handleNavigation('/login')}>
<ListItemIcon>
<LoginIcon />
<Login />
</ListItemIcon>
<ListItemText primary="Sign In" />
</MenuItem>,
<Divider key="signup-divider" />,
<MenuItem key="teacher-signup" onClick={() => handleSignupNavigation('teacher')}>
<ListItemIcon>
<TeacherIcon />
<Teacher />
</ListItemIcon>
<ListItemText
primary="Sign up as Teacher"
@ -368,7 +365,7 @@ const Header: React.FC = () => {
</MenuItem>,
<MenuItem key="student-signup" onClick={() => handleSignupNavigation('student')}>
<ListItemIcon>
<StudentIcon />
<Student />
</ListItemIcon>
<ListItemText
primary="Sign up as Student"

View File

@ -25,7 +25,7 @@ function NotFoundPublic() {
gap: 3
}}
>
<ErrorOutlineIcon sx={{ fontSize: 60, color: theme.palette.error.main }} />
<ErrorOutline sx={{ fontSize: 60, color: theme.palette.error.main }} />
<Typography variant="h2" component="h1" gutterBottom>
404
</Typography>

View File

@ -454,7 +454,7 @@ const SimpleUploadTest: React.FC = () => {
<Card>
<CardHeader
title="Upload Controls"
avatar={<UploadIcon />}
avatar={<Upload />}
/>
<CardContent>
<Box sx={{ mb: 2 }}>
@ -497,7 +497,7 @@ const SimpleUploadTest: React.FC = () => {
/>
<Button
variant="outlined"
startIcon={<UploadIcon />}
startIcon={<Upload />}
onClick={() => fileInputRef.current?.click()}
disabled={!selectedCabinet || loading}
>
@ -515,7 +515,7 @@ const SimpleUploadTest: React.FC = () => {
<Button
variant="outlined"
startIcon={<FolderOpenIcon />}
startIcon={<FolderOpen />}
onClick={handleDirectoryPicker}
disabled={!selectedCabinet || loading}
>
@ -524,7 +524,7 @@ const SimpleUploadTest: React.FC = () => {
<Button
variant="outlined"
startIcon={<RefreshIcon />}
startIcon={<Refresh />}
onClick={() => {
setCurrentPage(1);
setSearchTerm('');
@ -554,7 +554,7 @@ const SimpleUploadTest: React.FC = () => {
<Card>
<CardHeader
title="System Info"
avatar={<InfoIcon />}
avatar={<Info />}
/>
<CardContent>
<Box sx={{ mb: 2 }}>
@ -633,7 +633,7 @@ const SimpleUploadTest: React.FC = () => {
title={
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<FileIcon />
<InsertDriveFile />
<Typography variant="h6">
Files {pagination && `(${pagination.total_count} total)`}
</Typography>
@ -748,7 +748,7 @@ const SimpleUploadTest: React.FC = () => {
}
>
<ListItemIcon>
{file.is_directory ? <FolderIcon /> : <FileIcon />}
{file.is_directory ? <FolderIcon /> : <InsertDriveFile />}
</ListItemIcon>
<ListItemText
primary={
@ -812,7 +812,7 @@ const SimpleUploadTest: React.FC = () => {
<Dialog open={showUploadDialog} onClose={() => !isUploading && setShowUploadDialog(false)} maxWidth="md" fullWidth>
<DialogTitle>
<Box display="flex" alignItems="center" gap={1}>
<FolderOpenIcon />
<FolderOpen />
Directory Upload Progress
{isUploading && <LinearProgress sx={{ flexGrow: 1, ml: 2 }} />}
</Box>

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useParams, Link, useNavigate } from 'react-router-dom';
import { AccessTimeIcon, AddIcon, ArrowBackIcon, CalendarTodayIcon, DeleteIcon, EditIcon, MenuBookIcon, PeopleIcon } from '@mui/icons-material';
import { AccessTime, Add, ArrowBack, CalendarToday, Delete, Edit, MenuBook, People } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import { useUser } from '../../contexts/UserContext';
import Modal from '../../components/common/Modal';
@ -72,7 +72,7 @@ const ClassDetailPage: React.FC = () => {
to="/timetable/classes"
className="inline-flex items-center gap-2 text-gray-500 hover:text-gray-700 mb-4"
>
<ArrowBackIcon size={18} />
<ArrowBack size={18} />
Back to Classes
</Link>
@ -95,14 +95,14 @@ const ClassDetailPage: React.FC = () => {
to={`/timetable/classes/${classId}/edit`}
className="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors"
>
<EditIcon size={18} />
<Edit size={18} />
Edit
</Link>
<button
onClick={() => setShowDeleteModal(true)}
className="inline-flex items-center gap-2 px-4 py-2 bg-red-100 text-red-700 rounded-lg hover:bg-red-200 transition-colors"
>
<DeleteIcon size={18} />
<Delete size={18} />
Delete
</button>
</div>
@ -115,7 +115,7 @@ const ClassDetailPage: React.FC = () => {
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
<div className="flex items-center gap-3">
<div className="p-2 bg-blue-50 rounded-lg">
<CalendarTodayIcon className="text-blue-600" size={20} />
<CalendarToday className="text-blue-600" size={20} />
</div>
<div>
<p className="text-sm text-gray-500">Timetables</p>
@ -126,7 +126,7 @@ const ClassDetailPage: React.FC = () => {
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
<div className="flex items-center gap-3">
<div className="p-2 bg-green-50 rounded-lg">
<PeopleIcon className="text-green-600" size={20} />
<People className="text-green-600" size={20} />
</div>
<div>
<p className="text-sm text-gray-500">Students</p>
@ -137,7 +137,7 @@ const ClassDetailPage: React.FC = () => {
<div className="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
<div className="flex items-center gap-3">
<div className="p-2 bg-purple-50 rounded-lg">
<MenuBookIcon className="text-purple-600" size={20} />
<MenuBook className="text-purple-600" size={20} />
</div>
<div>
<p className="text-sm text-gray-500">Teachers</p>
@ -194,7 +194,7 @@ const ClassDetailPage: React.FC = () => {
to={`/timetable/classes/${classId}/timetables/new`}
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
<AddIcon size={18} />
<Add size={18} />
Add Timetable
</Link>
)}
@ -202,7 +202,7 @@ const ClassDetailPage: React.FC = () => {
{timetables.length === 0 ? (
<div className="text-center py-12 text-gray-500">
<AccessTimeIcon size={48} className="mx-auto mb-4 opacity-50" />
<AccessTime size={48} className="mx-auto mb-4 opacity-50" />
<p className="text-lg font-medium mb-2">No timetables yet</p>
<p>Create a timetable to start scheduling lessons</p>
</div>
@ -221,7 +221,7 @@ const ClassDetailPage: React.FC = () => {
{timetable.is_recurring && ' • Recurring'}
</p>
</div>
<ArrowBackIcon className="rotate-180 text-gray-400" size={18} />
<ArrowBack className="rotate-180 text-gray-400" size={18} />
</Link>
))}
</div>
@ -234,7 +234,7 @@ const ClassDetailPage: React.FC = () => {
<h2 className="text-lg font-semibold text-gray-900 mb-4">Enrolled Students</h2>
{enrolledStudents.length === 0 ? (
<div className="text-center py-12 text-gray-500">
<PeopleIcon size={48} className="mx-auto mb-4 opacity-50" />
<People size={48} className="mx-auto mb-4 opacity-50" />
<p className="text-lg font-medium mb-2">No students enrolled</p>
<p>Students can request enrollment or be added by teachers</p>
</div>

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { AddIcon, CalendarTodayIcon, FilterListIcon, MenuBookIcon, PeopleIcon, SearchIcon } from '@mui/icons-material';
import { Add, CalendarToday, FilterList, MenuBook, People, Search } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import { useUser } from '../../contexts/UserContext';
@ -70,7 +70,7 @@ const ClassesPage: React.FC = () => {
onClick={() => navigate('/timetable/classes/create')}
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
<AddIcon size={20} />
<Add size={20} />
Create Class
</button>
)}
@ -80,7 +80,7 @@ const ClassesPage: React.FC = () => {
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-4 mb-6">
<form onSubmit={handleSearch} className="flex flex-col md:flex-row gap-4">
<div className="flex-1 relative">
<SearchIcon className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" size={20} />
<Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" size={20} />
<input
type="text"
placeholder="Search classes by name or subject..."
@ -94,7 +94,7 @@ const ClassesPage: React.FC = () => {
onClick={() => setShowFilters(!showFilters)}
className="inline-flex items-center gap-2 px-4 py-2 border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
>
<FilterListIcon size={20} />
<FilterList size={20} />
Filters
</button>
<button
@ -172,7 +172,7 @@ const ClassesPage: React.FC = () => {
</div>
) : classes.length === 0 ? (
<div className="text-center py-12 bg-gray-50 rounded-xl">
<MenuBookIcon className="mx-auto h-12 w-12 text-gray-400 mb-4" />
<MenuBook className="mx-auto h-12 w-12 text-gray-400 mb-4" />
<h3 className="text-lg font-medium text-gray-900">No classes found</h3>
<p className="text-gray-600 mt-1">
{searchQuery || filterSubject || filterSchoolYear
@ -191,7 +191,7 @@ const ClassesPage: React.FC = () => {
>
<div className="flex items-start justify-between mb-4">
<div className="p-2 bg-blue-50 rounded-lg">
<MenuBookIcon className="text-blue-600" size={24} />
<MenuBook className="text-blue-600" size={24} />
</div>
<span className="px-2 py-1 bg-gray-100 text-gray-600 text-xs font-medium rounded-full">
{cls.subject}
@ -203,11 +203,11 @@ const ClassesPage: React.FC = () => {
</p>
<div className="flex items-center gap-4 text-sm text-gray-600">
<span className="flex items-center gap-1">
<PeopleIcon size={16} />
<People size={16} />
{cls.student_count} students
</span>
<span className="flex items-center gap-1">
<CalendarTodayIcon size={16} />
<CalendarToday size={16} />
{cls.timetable_count} timetables
</span>
</div>

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { CheckIcon, CloseIcon, FilterListIcon, KeyboardArrowDownIcon, PeopleIcon, PersonAddIcon, SearchIcon } from '@mui/icons-material';
import { Check, Close, FilterList, KeyboardArrowDown, People, PersonAdd, Search } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import Modal from '../../components/common/Modal';
@ -105,7 +105,7 @@ const EnrollmentRequestsPage: React.FC = () => {
<div className="flex flex-wrap items-center gap-4">
{/* Class Filter */}
<div className="flex items-center gap-2">
<FilterListIcon size={18} className="text-gray-400" />
<FilterList size={18} className="text-gray-400" />
<select
value={filters.class_id || ''}
onChange={(e) => setFilters(prev => ({ ...prev, class_id: e.target.value || undefined }))}
@ -137,7 +137,7 @@ const EnrollmentRequestsPage: React.FC = () => {
{/* Search */}
<div className="flex-1 min-w-[200px]">
<div className="relative">
<SearchIcon size={18} className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" />
<Search size={18} className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400" />
<input
type="text"
placeholder="Search by student name or email..."
@ -195,7 +195,7 @@ const EnrollmentRequestsPage: React.FC = () => {
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div className="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center">
<PersonAddIcon size={18} className="text-blue-600" />
<PersonAdd size={18} className="text-blue-600" />
</div>
<div className="ml-4">
<div className="text-sm font-medium text-gray-900">
@ -230,7 +230,7 @@ const EnrollmentRequestsPage: React.FC = () => {
}}
className="inline-flex items-center px-3 py-1 border border-transparent text-xs font-medium rounded text-green-700 bg-green-100 hover:bg-green-200"
>
<CheckIcon size={14} className="mr-1" />
<Check size={14} className="mr-1" />
Approve
</button>
<button
@ -241,7 +241,7 @@ const EnrollmentRequestsPage: React.FC = () => {
}}
className="inline-flex items-center px-3 py-1 border border-transparent text-xs font-medium rounded text-red-700 bg-red-100 hover:bg-red-200"
>
<CloseIcon size={14} className="mr-1" />
<Close size={14} className="mr-1" />
Reject
</button>
</div>
@ -259,7 +259,7 @@ const EnrollmentRequestsPage: React.FC = () => {
</div>
) : (
<div className="text-center py-16 bg-white rounded-lg shadow">
<PeopleIcon className="mx-auto h-12 w-12 text-gray-300" />
<People className="mx-auto h-12 w-12 text-gray-300" />
<h3 className="mt-4 text-lg font-medium text-gray-900">No enrollment requests</h3>
<p className="mt-2 text-gray-500">
{filters.status === 'pending'

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useParams, Link, useNavigate } from 'react-router-dom';
import { AccessTimeIcon, ArrowBackIcon, CalendarTodayIcon, CancelIcon, CheckCircleIcon, DeleteIcon, DescriptionIcon, EditIcon, LocationOnIcon, MenuBookIcon, PeopleIcon } from '@mui/icons-material';
import { AccessTime, ArrowBack, CalendarToday, Cancel, CheckCircle, Delete, Description, Edit, LocationOn, MenuBook, People } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import { useUser } from '../../contexts/UserContext';
import { format, parseISO } from 'date-fns';
@ -119,7 +119,7 @@ const LessonPage: React.FC = () => {
to={`/timetable/timetables/${currentTimetable?.id}`}
className="inline-flex items-center text-gray-500 hover:text-gray-700 mb-2"
>
<ArrowBackIcon size={16} className="mr-1" />
<ArrowBack size={16} className="mr-1" />
Back to Timetable
</Link>
<h1 className="text-3xl font-bold text-gray-900">{currentLesson.title}</h1>
@ -133,14 +133,14 @@ const LessonPage: React.FC = () => {
onClick={() => setIsEditModalOpen(true)}
className="inline-flex items-center px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
>
<EditIcon size={16} className="mr-2" />
<Edit size={16} className="mr-2" />
Edit
</button>
<button
onClick={handleDeleteLesson}
className="inline-flex items-center px-3 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors"
>
<DeleteIcon size={16} className="mr-2" />
<Delete size={16} className="mr-2" />
Delete
</button>
</div>
@ -151,12 +151,12 @@ const LessonPage: React.FC = () => {
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-lg font-semibold text-gray-900 mb-4 flex items-center">
<AccessTimeIcon size={20} className="mr-2 text-blue-600" />
<AccessTime size={20} className="mr-2 text-blue-600" />
Time & Location
</h2>
<div className="space-y-3">
<div className="flex items-start gap-3">
<CalendarTodayIcon size={18} className="text-gray-400 mt-0.5" />
<CalendarToday size={18} className="text-gray-400 mt-0.5" />
<div>
<p className="font-medium text-gray-900">Date</p>
<p className="text-gray-600">
@ -165,7 +165,7 @@ const LessonPage: React.FC = () => {
</div>
</div>
<div className="flex items-start gap-3">
<AccessTimeIcon size={18} className="text-gray-400 mt-0.5" />
<AccessTime size={18} className="text-gray-400 mt-0.5" />
<div>
<p className="font-medium text-gray-900">Time</p>
<p className="text-gray-600">
@ -175,7 +175,7 @@ const LessonPage: React.FC = () => {
</div>
{(currentLesson.location || currentLesson.room) && (
<div className="flex items-start gap-3">
<LocationOnIcon size={18} className="text-gray-400 mt-0.5" />
<LocationOn size={18} className="text-gray-400 mt-0.5" />
<div>
<p className="font-medium text-gray-900">Location</p>
<p className="text-gray-600">
@ -191,7 +191,7 @@ const LessonPage: React.FC = () => {
<div className="bg-white rounded-lg shadow p-6">
<h2 className="text-lg font-semibold text-gray-900 mb-4 flex items-center">
<MenuBookIcon size={20} className="mr-2 text-green-600" />
<MenuBook size={20} className="mr-2 text-green-600" />
Class Information
</h2>
<div className="space-y-3">
@ -218,7 +218,7 @@ const LessonPage: React.FC = () => {
<div className="bg-white rounded-lg shadow">
<div className="px-6 py-4 border-b border-gray-200">
<h2 className="text-lg font-semibold text-gray-900 flex items-center">
<PeopleIcon size={20} className="mr-2 text-purple-600" />
<People size={20} className="mr-2 text-purple-600" />
Attendance
</h2>
</div>

View File

@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import { AccessTimeIcon, KeyboardArrowRightIcon, MenuBookIcon, PeopleIcon, SchoolIcon } from '@mui/icons-material';
import { AccessTime, KeyboardArrowRight, MenuBook, People, School } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import { useUser } from '../../contexts/UserContext';
@ -78,7 +78,7 @@ const MyClassesPage: React.FC = () => {
{teachingClasses.length > 0 && (
<div className="mb-8">
<div className="flex items-center gap-2 mb-4">
<SchoolIcon className="text-purple-600" size={24} />
<School className="text-purple-600" size={24} />
<h2 className="text-xl font-semibold text-gray-900">Teaching</h2>
<span className="px-2 py-1 bg-purple-100 text-purple-700 text-sm font-medium rounded-full">
{teachingClasses.length}
@ -102,7 +102,7 @@ const MyClassesPage: React.FC = () => {
<p className="text-sm text-gray-500">{classItem.class.code}</p>
)}
</div>
<KeyboardArrowRightIcon className="text-gray-400 flex-shrink-0 ml-2" size={20} />
<KeyboardArrowRight className="text-gray-400 flex-shrink-0 ml-2" size={20} />
</div>
<p className="text-gray-600 text-sm mb-4 line-clamp-2">
@ -120,12 +120,12 @@ const MyClassesPage: React.FC = () => {
<div className="mt-4 pt-4 border-t border-gray-100 flex items-center gap-4 text-sm text-gray-500">
<div className="flex items-center gap-1">
<PeopleIcon size={14} />
<People size={14} />
<span>{classItem.class?.enrolled_count || 0} students</span>
</div>
{classItem.class?.academic_year && (
<div className="flex items-center gap-1">
<SchoolIcon size={14} />
<School size={14} />
<span>{classItem.class.academic_year}</span>
</div>
)}
@ -141,7 +141,7 @@ const MyClassesPage: React.FC = () => {
{enrolledClasses.length > 0 && (
<div className="mb-8">
<div className="flex items-center gap-2 mb-4">
<MenuBookIcon className="text-green-600" size={24} />
<MenuBook className="text-green-600" size={24} />
<h2 className="text-xl font-semibold text-gray-900">Enrolled</h2>
<span className="px-2 py-1 bg-green-100 text-green-700 text-sm font-medium rounded-full">
{enrolledClasses.length}
@ -165,7 +165,7 @@ const MyClassesPage: React.FC = () => {
<p className="text-sm text-gray-500">{classItem.class.code}</p>
)}
</div>
<KeyboardArrowRightIcon className="text-gray-400 flex-shrink-0 ml-2" size={20} />
<KeyboardArrowRight className="text-gray-400 flex-shrink-0 ml-2" size={20} />
</div>
<p className="text-gray-600 text-sm mb-4 line-clamp-2">
@ -180,14 +180,14 @@ const MyClassesPage: React.FC = () => {
<div className="mt-4 pt-4 border-t border-gray-100 flex items-center gap-4 text-sm text-gray-500">
<div className="flex items-center gap-1">
<SchoolIcon size={14} />
<School size={14} />
<span>
{classItem.class?.teachers?.[0]?.first_name} {classItem.class?.teachers?.[0]?.last_name}
</span>
</div>
{classItem.class?.academic_year && (
<div className="flex items-center gap-1">
<SchoolIcon size={14} />
<School size={14} />
<span>{classItem.class.academic_year}</span>
</div>
)}
@ -202,7 +202,7 @@ const MyClassesPage: React.FC = () => {
{/* Empty State */}
{myClasses.length === 0 && (
<div className="text-center py-16">
<MenuBookIcon className="mx-auto h-12 w-12 text-gray-300" />
<MenuBook className="mx-auto h-12 w-12 text-gray-300" />
<h3 className="mt-4 text-lg font-medium text-gray-900">No classes found</h3>
<p className="mt-2 text-gray-500">
You are not enrolled in or teaching any classes yet.

View File

@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import { useParams, Link, useNavigate } from 'react-router-dom';
import { AccessTimeIcon, AddIcon, ArrowBackIcon, CalendarTodayIcon, DeleteIcon, EditIcon, KeyboardArrowLeftIcon, KeyboardArrowRightIcon, LocationOnIcon } from '@mui/icons-material';
import { AccessTime, Add, ArrowBack, CalendarToday, Delete, Edit, KeyboardArrowLeft, KeyboardArrowRight, LocationOn } from '@mui/icons-material';
import useTimetableStore from '../../stores/timetableStore';
import { useUser } from '../../contexts/UserContext';
import { format, parseISO, addDays, startOfWeek, isSameDay } from 'date-fns';
@ -81,7 +81,7 @@ const TimetablePage: React.FC = () => {
to={`/timetable/classes/${currentTimetable.class_id}`}
className="inline-flex items-center gap-2 text-gray-500 hover:text-gray-700 mb-4"
>
<ArrowBackIcon size={18} />
<ArrowBack sx={{ fontSize: 18 }} />
Back to Class
</Link>
@ -90,7 +90,7 @@ const TimetablePage: React.FC = () => {
<h1 className="text-3xl font-bold text-gray-900 mb-2">{currentTimetable.name}</h1>
<div className="flex items-center gap-4 text-gray-500">
<span className="flex items-center gap-1">
<CalendarTodayIcon size={16} />
<CalendarToday sx={{ fontSize: 16 }} />
{format(parseISO(currentTimetable.effective_from), 'MMM d, yyyy')}
{currentTimetable.effective_until && ` - ${format(parseISO(currentTimetable.effective_until), 'MMM d, yyyy')}`}
</span>
@ -107,14 +107,14 @@ const TimetablePage: React.FC = () => {
to={`/timetable/timetables/${timetableId}/lessons/new`}
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
>
<AddIcon size={18} />
<Add sx={{ fontSize: 18 }} />
Add Lesson
</Link>
<button
onClick={handleDeleteTimetable}
className="inline-flex items-center gap-2 px-4 py-2 bg-red-100 text-red-700 rounded-lg hover:bg-red-200 transition-colors"
>
<DeleteIcon size={18} />
<Delete sx={{ fontSize: 18 }} />
Delete
</button>
</div>
@ -131,7 +131,7 @@ const TimetablePage: React.FC = () => {
{currentLessons.length === 0 ? (
<div className="p-12 text-center text-gray-500">
<AccessTimeIcon size={48} className="mx-auto mb-4 opacity-50" />
<AccessTime sx={{ fontSize: 48 }} className="mx-auto mb-4 opacity-50" />
<p className="text-lg font-medium mb-2">No lessons scheduled</p>
<p>Add lessons to build your timetable</p>
</div>
@ -171,7 +171,7 @@ const TimetablePage: React.FC = () => {
</div>
{lesson.location && (
<div className="flex items-center gap-1 text-sm text-gray-500">
<LocationOnIcon size={14} />
<LocationOn sx={{ fontSize: 14 }} />
{lesson.location}
</div>
)}

View File

@ -327,9 +327,9 @@ export const CCDoclingViewer: React.FC<{
<Box sx={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column' }}>
{!hideToolbar && (
<Box sx={{ p: 1, display: 'flex', alignItems: 'center', gap: 1, borderBottom: '1px solid var(--color-divider)' }}>
<IconButton size="small" onClick={() => handlePageChange(start - 1)} disabled={start <= 1}><ArrowBackIosNewIcon fontSize="inherit" /></IconButton>
<IconButton size="small" onClick={() => handlePageChange(start - 1)} disabled={start <= 1}><ArrowBackIosNew fontSize="inherit" /></IconButton>
<Box sx={{ fontSize: 12, color: 'var(--color-text-2)' }}>Section {start}{end}</Box>
<IconButton size="small" onClick={() => handlePageChange(end + 1)} disabled={end >= totalPages}><ArrowForwardIosIcon fontSize="inherit" /></IconButton>
<IconButton size="small" onClick={() => handlePageChange(end + 1)} disabled={end >= totalPages}><ArrowForwardIos fontSize="inherit" /></IconButton>
</Box>
)}
<Box sx={{ flex: 1, overflow: 'auto', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2, p: 2 }}>

View File

@ -3,10 +3,14 @@ import {
Box, CircularProgress, IconButton, Typography, Collapse, Chip,
List, ListItem, ListItemButton, ListItemIcon, ListItemText
} from '@mui/material';
import {
ExpandMore, ChevronRight, Description, Check, Schedule,
Visibility, Psychology, Home as OverviewIcon
} from '@mui/icons-material';
import ExpandMore from '@mui/icons-material/ExpandMore';
import ChevronRight from '@mui/icons-material/ChevronRight';
import Description from '@mui/icons-material/Description';
import Check from '@mui/icons-material/Check';
import Schedule from '@mui/icons-material/Schedule';
import Visibility from '@mui/icons-material/Visibility';
import Psychology from '@mui/icons-material/Psychology';
import Overview from '@mui/icons-material/Home';
import { supabase } from '../../../supabaseClient';
// Types
@ -345,7 +349,7 @@ export const CCEnhancedFilePanel: React.FC<CCEnhancedFilePanelProps> = ({
color={selectedView === 'overview' ? 'primary' : 'default'}
title="Processing Overview"
>
<OverviewIcon />
<CalendarViewMonth />
</IconButton>
<IconButton
size="small"

View File

@ -161,7 +161,7 @@ export const CCFileDetailPanel: React.FC<{
</Box>
<Box sx={{ p: 1, borderBottom: '1px solid var(--color-divider)', display: 'flex', alignItems: 'center', justifyContent: 'flex-start', gap: 1, flexShrink: 0, bgcolor: 'var(--color-panel)' }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
<IconButton size="small" onClick={() => onSelectPage(Math.max(1, selectedPage - 1))}><ArrowBackIosNewIcon fontSize="inherit" /></IconButton>
<IconButton size="small" onClick={() => onSelectPage(Math.max(1, selectedPage - 1))}><ArrowBackIosNew fontSize="inherit" /></IconButton>
<TextField
size="small"
value={selectedPage}
@ -170,7 +170,7 @@ export const CCFileDetailPanel: React.FC<{
InputProps={{ sx: { width: 64, '& input': { textAlign: 'center', padding: '6px' } } }}
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*', maxLength: 4 }}
/>
<IconButton size="small" onClick={() => onSelectPage(Math.min(manifest.page_count, selectedPage + 1))}><ArrowForwardIosIcon fontSize="inherit" /></IconButton>
<IconButton size="small" onClick={() => onSelectPage(Math.min(manifest.page_count, selectedPage + 1))}><ArrowForwardIos fontSize="inherit" /></IconButton>
<Typography variant="body2" sx={{ color: 'var(--color-text-2)' }}>/ {manifest.page_count}</Typography>
</Box>
</Box>
@ -186,8 +186,8 @@ export const CCFileDetailPanel: React.FC<{
</Select>
{outline && outline.sections.length > 0 && (
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
<IconButton size="small" title="Expand all" onClick={() => setCollapsed(new Set())}><ExpandMoreIcon fontSize="inherit" /></IconButton>
<IconButton size="small" title="Collapse all" onClick={() => setCollapsed(new Set(collectAllIds(outline.sections)))}><ChevronRightIcon fontSize="inherit" /></IconButton>
<IconButton size="small" title="Expand all" onClick={() => setCollapsed(new Set())}><ExpandMore fontSize="inherit" /></IconButton>
<IconButton size="small" title="Collapse all" onClick={() => setCollapsed(new Set(collectAllIds(outline.sections)))}><ChevronRight fontSize="inherit" /></IconButton>
</Box>
)}
</Box>
@ -202,8 +202,8 @@ export const CCFileDetailPanel: React.FC<{
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 1 }}>
<Typography variant="body2" sx={{ color: 'var(--color-text-2)', fontWeight: 600 }}>Sections</Typography>
<Box>
<IconButton size="small" title="Expand all" onClick={() => setCollapsed(new Set())}><ExpandMoreIcon fontSize="inherit" /></IconButton>
<IconButton size="small" title="Collapse all" onClick={() => setCollapsed(new Set(collectAllIds(outline.sections)))}><ChevronRightIcon fontSize="inherit" /></IconButton>
<IconButton size="small" title="Expand all" onClick={() => setCollapsed(new Set())}><ExpandMore fontSize="inherit" /></IconButton>
<IconButton size="small" title="Collapse all" onClick={() => setCollapsed(new Set(collectAllIds(outline.sections)))}><ChevronRight fontSize="inherit" /></IconButton>
</Box>
</Box>
)}
@ -291,7 +291,7 @@ const SectionTile: React.FC<{
borderBottom: '1px solid var(--color-divider)'
}}>
<IconButton size="small" onClick={(e) => { e.stopPropagation(); toggleCollapse(s.id); }}>
{isCollapsed ? <ChevronRightIcon fontSize="inherit" /> : <ExpandMoreIcon fontSize="inherit" />}
{isCollapsed ? <ChevronRight fontSize="inherit" /> : <ExpandMore fontSize="inherit" />}
</IconButton>
<Box onClick={() => onSelectPage(Math.max(1, s.start_page))}>
<Typography component="span" sx={{ color: 'var(--color-text-1)' }}>{s.title}</Typography>

View File

@ -36,7 +36,7 @@ function NotFound() {
gap: 3
}}
>
<ErrorOutlineIcon sx={{ fontSize: 60, color: theme.palette.error.main }} />
<ErrorOutline sx={{ fontSize: 60, color: theme.palette.error.main }} />
<Typography variant="h2" component="h1" gutterBottom>
404
</Typography>

View File

@ -325,9 +325,8 @@ export const enrollmentService = {
// Combined Export
// ============================================================================
export const timetableService = {
export const timetableServiceExports = {
...classService,
...timetableService,
...lessonService,
...enrollmentService,
};

View File

@ -1,6 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react';
import { Box, Typography, styled, Button, ThemeProvider, createTheme, useMediaQuery } from '@mui/material';
import { Save as SaveIcon, RestartAlt as ResetIcon } from '@mui/icons-material';
import Save from '@mui/icons-material/Save';
import Reset from '@mui/icons-material/RestartAlt';
import { useEditor, useToasts, loadSnapshot } from '@tldraw/tldraw';
import { useNavigationStore } from '../../../../../../stores/navigationStore';
import { UserNeoDBService } from '../../../../../../services/graph/userNeoDBService';
@ -173,7 +174,7 @@ export const CCNodeSnapshotPanel: React.FC = () => {
<ActionButton
variant="contained"
size="small"
startIcon={<SaveIcon />}
startIcon={<Save />}
onClick={handleSaveSnapshot}
disabled={isLoading}
sx={{ flex: 1 }}
@ -183,7 +184,7 @@ export const CCNodeSnapshotPanel: React.FC = () => {
<ActionButton
variant="contained"
size="small"
startIcon={<ResetIcon />}
startIcon={<RestartAlt />}
onClick={handleResetCanvas}
disabled={isLoading}
sx={{ flex: 1 }}