feat(timetable): add navigation links to Header component

This commit is contained in:
Agent Zero 2026-02-26 03:28:08 +00:00
parent 11c139b410
commit a64836c94a

View File

@ -29,7 +29,12 @@ import {
Settings as SettingsIcon, Settings as SettingsIcon,
Search as SearchIcon, Search as SearchIcon,
AdminPanelSettings as AdminIcon, AdminPanelSettings as AdminIcon,
Home as HomeIcon Home as HomeIcon,
// Timetable icons
Schedule as ScheduleIcon,
Class as ClassIcon,
Book as BookIcon,
HowToReg as EnrollmentIcon
} from '@mui/icons-material'; } from '@mui/icons-material';
import { HEADER_HEIGHT } from './Layout'; import { HEADER_HEIGHT } from './Layout';
import { logger } from '../debugConfig'; import { logger } from '../debugConfig';
@ -80,7 +85,6 @@ const Header: React.FC = () => {
try { try {
logger.debug('auth-service', '🔄 Signing out user', { userId: user?.id }); logger.debug('auth-service', '🔄 Signing out user', { userId: user?.id });
await signOut(); await signOut();
// Clear local state immediately
setIsAuthenticated(false); setIsAuthenticated(false);
setAnchorEl(null); setAnchorEl(null);
logger.debug('auth-service', '✅ User signed out'); logger.debug('auth-service', '✅ User signed out');
@ -103,73 +107,50 @@ const Header: React.FC = () => {
<Toolbar sx={{ <Toolbar sx={{
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
minHeight: `${HEADER_HEIGHT}px !important`,
height: `${HEADER_HEIGHT}px`,
gap: 2,
px: { xs: 1, sm: 2 }
}}>
<Box sx={{
display: 'flex',
alignItems: 'center', alignItems: 'center',
gap: 2, height: '100%'
minWidth: { xs: 'auto', sm: '200px' }
}}> }}>
{showGraphNavigation && (
<GraphNavigator />
)}
<Typography <Typography
variant="h6" variant="h6"
component="div" component="div"
className="app-title"
sx={{ sx={{
flexGrow: showGraphNavigation ? 0 : 1,
fontWeight: 600,
cursor: 'pointer', cursor: 'pointer',
color: theme.palette.text.primary, display: 'flex',
'&:hover': { alignItems: 'center',
color: theme.palette.primary.main gap: 1
},
fontSize: { xs: '1rem', sm: '1.25rem' }
}} }}
onClick={() => navigate(isAuthenticated ? '/dashboard' : '/')} onClick={() => handleNavigation('/')}
> >
<HomeIcon sx={{ color: theme.palette.primary.main }} />
Classroom Copilot Classroom Copilot
</Typography> </Typography>
</Box>
<Box sx={{ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
position: 'absolute', {isAuthenticated && (
left: '50%', <Typography
transform: 'translateX(-50%)', variant="body2"
display: 'flex',
justifyContent: 'center',
visibility: showGraphNavigation ? 'visible' : 'hidden',
width: {
xs: 'calc(100% - 160px)', // More space for menu and title
sm: 'calc(100% - 200px)', // Standard spacing
md: 'auto' // Full width on medium and up
},
maxWidth: '800px',
'& .navigation-controls': {
display: { xs: 'none', sm: 'flex' }
},
'& .context-section': {
display: { xs: 'none', md: 'flex' }
},
'& .context-toggle': {
display: 'flex' // Always show the profile/institute toggle
}
}}>
<GraphNavigator />
</Box>
<Box sx={{
display: 'flex',
justifyContent: 'flex-end',
minWidth: { xs: 'auto', sm: '200px' },
ml: 'auto'
}}>
<IconButton
className="menu-button"
color="inherit"
onClick={handleMenuOpen}
edge="end"
sx={{ sx={{
color: theme.palette.text.secondary,
display: { xs: 'none', sm: 'block' }
}}
>
{user?.email}
</Typography>
)}
<IconButton
color="inherit"
aria-label="menu"
onClick={handleMenuOpen}
sx={{
border: `1px solid ${theme.palette.divider}`,
borderRadius: 1,
'&:hover': { '&:hover': {
bgcolor: theme.palette.action.hover bgcolor: theme.palette.action.hover
} }
@ -177,64 +158,126 @@ const Header: React.FC = () => {
> >
<MenuIcon /> <MenuIcon />
</IconButton> </IconButton>
<Menu <Menu
anchorEl={anchorEl} anchorEl={anchorEl}
open={Boolean(anchorEl)} open={Boolean(anchorEl)}
onClose={handleMenuClose} onClose={handleMenuClose}
slotProps={{ PaperProps={{
paper: {
elevation: 3,
sx: { sx: {
bgcolor: theme.palette.background.paper, width: 280,
color: theme.palette.text.primary, maxHeight: '80vh'
minWidth: '240px'
}
} }
}} }}
> >
<Typography
variant="subtitle2"
sx={{
px: 2,
py: 1.5,
color: theme.palette.text.secondary,
fontWeight: 600,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem'
}}
>
Navigation
</Typography>
{isAuthenticated ? [ {isAuthenticated ? [
<MenuItem key="dashboard" onClick={() => handleNavigation('/dashboard')}> // Home
<MenuItem key="home" onClick={() => handleNavigation('/')}>
<ListItemIcon> <ListItemIcon>
<HomeIcon /> <HomeIcon />
</ListItemIcon> </ListItemIcon>
<ListItemText primary="Dashboard" /> <ListItemText primary="Home" />
</MenuItem>, </MenuItem>,
<Divider key="dashboard-divider" />, <Divider key="home-divider" />,
// Development Tools Section
<MenuItem key="tldraw" onClick={() => handleNavigation('/tldraw-dev')}>
<ListItemIcon>
<TLDrawDevIcon />
</ListItemIcon>
<ListItemText primary="TLDraw Dev" />
</MenuItem>,
<MenuItem key="dev" onClick={() => handleNavigation('/dev')}>
<ListItemIcon>
<DevToolsIcon />
</ListItemIcon>
<ListItemText primary="Dev Tools" />
</MenuItem>,
<Divider key="dev-divider" />,
// Main Features Section // Timetable Section
<MenuItem key="multiplayer" onClick={() => handleNavigation('/multiplayer')}> <Typography
key="timetable-header"
variant="subtitle2"
sx={{
px: 2,
py: 1,
color: theme.palette.primary.main,
fontWeight: 600,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem'
}}
>
Timetable & Classes
</Typography>,
<MenuItem key="timetable" onClick={() => handleNavigation('/timetable')}>
<ListItemIcon> <ListItemIcon>
<MultiplayerIcon /> <ScheduleIcon />
</ListItemIcon> </ListItemIcon>
<ListItemText primary="Multiplayer" /> <ListItemText
primary="My Timetable"
secondary="View your schedule"
/>
</MenuItem>, </MenuItem>,
<MenuItem key="classes" onClick={() => handleNavigation('/classes')}>
<ListItemIcon>
<ClassIcon />
</ListItemIcon>
<ListItemText
primary="Browse Classes"
secondary="Find and enroll in classes"
/>
</MenuItem>,
<MenuItem key="my-classes" onClick={() => handleNavigation('/my-classes')}>
<ListItemIcon>
<BookIcon />
</ListItemIcon>
<ListItemText
primary="My Classes"
secondary="Manage your classes"
/>
</MenuItem>,
<MenuItem key="enrollment-requests" onClick={() => handleNavigation('/enrollment-requests')}>
<ListItemIcon>
<EnrollmentIcon />
</ListItemIcon>
<ListItemText
primary="Enrollment Requests"
secondary="Review pending enrollments"
/>
</MenuItem>,
<Divider key="timetable-divider" />,
// Features Section
<Typography
key="features-header"
variant="subtitle2"
sx={{
px: 2,
py: 1,
color: theme.palette.text.secondary,
fontWeight: 600,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem'
}}
>
Features
</Typography>,
<MenuItem key="calendar" onClick={() => handleNavigation('/calendar')}> <MenuItem key="calendar" onClick={() => handleNavigation('/calendar')}>
<ListItemIcon> <ListItemIcon>
<CalendarIcon /> <CalendarIcon />
</ListItemIcon> </ListItemIcon>
<ListItemText primary="Calendar" /> <ListItemText primary="Calendar" />
</MenuItem>, </MenuItem>,
<MenuItem key="planner" onClick={() => handleNavigation('/teacher-planner')}> <MenuItem key="teacher-planner" onClick={() => handleNavigation('/teacher-planner')}>
<ListItemIcon> <ListItemIcon>
<TeacherPlannerIcon /> <TeacherPlannerIcon />
</ListItemIcon> </ListItemIcon>
<ListItemText primary="Teacher Planner" /> <ListItemText primary="Teacher Planner" />
</MenuItem>, </MenuItem>,
<MenuItem key="exam" onClick={() => handleNavigation('/exam-marker')}> <MenuItem key="exam-marker" onClick={() => handleNavigation('/exam-marker')}>
<ListItemIcon> <ListItemIcon>
<ExamMarkerIcon /> <ExamMarkerIcon />
</ListItemIcon> </ListItemIcon>
@ -243,6 +286,21 @@ const Header: React.FC = () => {
<Divider key="features-divider" />, <Divider key="features-divider" />,
// Utilities Section // Utilities Section
<Typography
key="utilities-header"
variant="subtitle2"
sx={{
px: 2,
py: 1,
color: theme.palette.text.secondary,
fontWeight: 600,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem'
}}
>
Utilities
</Typography>,
<MenuItem key="settings" onClick={() => handleNavigation('/settings')}> <MenuItem key="settings" onClick={() => handleNavigation('/settings')}>
<ListItemIcon> <ListItemIcon>
<SettingsIcon /> <SettingsIcon />
@ -259,6 +317,21 @@ const Header: React.FC = () => {
// Admin Section // Admin Section
...(isAdmin ? [ ...(isAdmin ? [
<Divider key="admin-divider" />, <Divider key="admin-divider" />,
<Typography
key="admin-header"
variant="subtitle2"
sx={{
px: 2,
py: 1,
color: theme.palette.error.main,
fontWeight: 600,
letterSpacing: '0.5px',
textTransform: 'uppercase',
fontSize: '0.75rem'
}}
>
Administration
</Typography>,
<MenuItem key="admin" onClick={() => handleNavigation('/admin')}> <MenuItem key="admin" onClick={() => handleNavigation('/admin')}>
<ListItemIcon> <ListItemIcon>
<AdminIcon /> <AdminIcon />