feat(nav): add launch buttons for My Timetable and My Classes sections
Add useNavigate + Launch icon to TreeItem; timetable section shows a launch button routing to /my-lessons, classes section routes to /my-classes. Both buttons only appear when the section status is populated. Exclude classes section from the unlinked/pending icon fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
61ef95a35e
commit
9438e17f88
@ -19,7 +19,9 @@ import {
|
|||||||
GridOn as GridIcon,
|
GridOn as GridIcon,
|
||||||
Settings as SetupIcon,
|
Settings as SetupIcon,
|
||||||
Edit as EditIcon,
|
Edit as EditIcon,
|
||||||
|
Launch as LaunchIcon,
|
||||||
} from '@mui/icons-material';
|
} from '@mui/icons-material';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useNavigationStore } from '../../../../../../stores/navigationStore';
|
import { useNavigationStore } from '../../../../../../stores/navigationStore';
|
||||||
import { useAuth } from '../../../../../../contexts/AuthContext';
|
import { useAuth } from '../../../../../../contexts/AuthContext';
|
||||||
import { NeoGraphNode } from '../../../../../../types/navigation';
|
import { NeoGraphNode } from '../../../../../../types/navigation';
|
||||||
@ -124,6 +126,7 @@ interface TreeItemProps {
|
|||||||
|
|
||||||
function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
||||||
const ctx = useContext(NavPanelContext);
|
const ctx = useContext(NavPanelContext);
|
||||||
|
const navigate = useNavigate();
|
||||||
const [expanded, setExpanded] = useState(node.is_section && node.status === 'populated');
|
const [expanded, setExpanded] = useState(node.is_section && node.status === 'populated');
|
||||||
const [children, setChildren] = useState<TreeNode[]>(node.children || []);
|
const [children, setChildren] = useState<TreeNode[]>(node.children || []);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@ -132,6 +135,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
|||||||
const isCalendarSection = isSection && node.section_id === 'calendar';
|
const isCalendarSection = isSection && node.section_id === 'calendar';
|
||||||
const isTimetableSection = isSection && node.section_id === 'timetable';
|
const isTimetableSection = isSection && node.section_id === 'timetable';
|
||||||
const isSchoolSection = isSection && node.section_id === 'school';
|
const isSchoolSection = isSection && node.section_id === 'school';
|
||||||
|
const isClassesSection = isSection && node.section_id === 'classes';
|
||||||
const SectionIcon = node.section_id ? SECTION_ICONS[node.section_id] : null;
|
const SectionIcon = node.section_id ? SECTION_ICONS[node.section_id] : null;
|
||||||
const Icon = SectionIcon || NODE_ICONS[node.node_type] || HomeIcon;
|
const Icon = SectionIcon || NODE_ICONS[node.node_type] || HomeIcon;
|
||||||
|
|
||||||
@ -196,6 +200,8 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
|||||||
const showLegacySetup = isTimetableSection && node.status === 'empty' && !ss;
|
const showLegacySetup = isTimetableSection && node.status === 'empty' && !ss;
|
||||||
const showTimetableEdit = isTimetableSection && node.status === 'populated'
|
const showTimetableEdit = isTimetableSection && node.status === 'populated'
|
||||||
&& ss && ss.status !== 'no_school' && !!ss.teacher_has_timetable;
|
&& ss && ss.status !== 'no_school' && !!ss.teacher_has_timetable;
|
||||||
|
const showTimetableView = isTimetableSection && node.status === 'populated';
|
||||||
|
const showClassesView = isClassesSection && node.status === 'populated';
|
||||||
|
|
||||||
if (isSection) {
|
if (isSection) {
|
||||||
return (
|
return (
|
||||||
@ -223,7 +229,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
{isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && (
|
{isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && !isClassesSection && (
|
||||||
<Box sx={{ width: 18, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<Box sx={{ width: 18, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||||
{node.status === 'no_school'
|
{node.status === 'no_school'
|
||||||
? <UnlinkedIcon sx={{ fontSize: 11, color: 'text.disabled' }} />
|
? <UnlinkedIcon sx={{ fontSize: 11, color: 'text.disabled' }} />
|
||||||
@ -249,7 +255,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
|||||||
{node.label}
|
{node.label}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
{isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && node.status && (
|
{isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && !isClassesSection && node.status && (
|
||||||
<Tooltip title={STATUS_MESSAGES[node.status]} placement="right">
|
<Tooltip title={STATUS_MESSAGES[node.status]} placement="right">
|
||||||
<Typography variant="caption" sx={{ fontSize: '0.6rem', color: 'text.disabled', ml: 0.5, flexShrink: 0 }}>
|
<Typography variant="caption" sx={{ fontSize: '0.6rem', color: 'text.disabled', ml: 0.5, flexShrink: 0 }}>
|
||||||
{node.status === 'no_school' ? '—' : '…'}
|
{node.status === 'no_school' ? '—' : '…'}
|
||||||
@ -319,6 +325,28 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
|
{showTimetableView && (
|
||||||
|
<Tooltip title="View as lesson list" placement="right">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
sx={{ p: 0.25, ml: 0.5, color: 'text.secondary' }}
|
||||||
|
onClick={e => { e.stopPropagation(); navigate('/my-lessons'); }}
|
||||||
|
>
|
||||||
|
<LaunchIcon sx={{ fontSize: 13 }} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{showClassesView && (
|
||||||
|
<Tooltip title="View my classes" placement="right">
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
sx={{ p: 0.25, ml: 0.5, color: 'text.secondary' }}
|
||||||
|
onClick={e => { e.stopPropagation(); navigate('/my-classes'); }}
|
||||||
|
>
|
||||||
|
<LaunchIcon sx={{ fontSize: 13 }} />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Calendar mode toggle */}
|
{/* Calendar mode toggle */}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user