From 9438e17f88f36e6488f4c97f800ee9f0e75ae615 Mon Sep 17 00:00:00 2001 From: kcar Date: Wed, 27 May 2026 11:22:26 +0100 Subject: [PATCH] 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 --- .../shared/navigation/CCGraphNavPanel.tsx | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/utils/tldraw/ui-overrides/components/shared/navigation/CCGraphNavPanel.tsx b/src/utils/tldraw/ui-overrides/components/shared/navigation/CCGraphNavPanel.tsx index 06bc82a..dfe5aaf 100644 --- a/src/utils/tldraw/ui-overrides/components/shared/navigation/CCGraphNavPanel.tsx +++ b/src/utils/tldraw/ui-overrides/components/shared/navigation/CCGraphNavPanel.tsx @@ -19,7 +19,9 @@ import { GridOn as GridIcon, Settings as SetupIcon, Edit as EditIcon, + Launch as LaunchIcon, } from '@mui/icons-material'; +import { useNavigate } from 'react-router-dom'; import { useNavigationStore } from '../../../../../../stores/navigationStore'; import { useAuth } from '../../../../../../contexts/AuthContext'; import { NeoGraphNode } from '../../../../../../types/navigation'; @@ -124,6 +126,7 @@ interface TreeItemProps { function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) { const ctx = useContext(NavPanelContext); + const navigate = useNavigate(); const [expanded, setExpanded] = useState(node.is_section && node.status === 'populated'); const [children, setChildren] = useState(node.children || []); const [loading, setLoading] = useState(false); @@ -132,6 +135,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) { const isCalendarSection = isSection && node.section_id === 'calendar'; const isTimetableSection = isSection && node.section_id === 'timetable'; 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 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 showTimetableEdit = isTimetableSection && node.status === 'populated' && ss && ss.status !== 'no_school' && !!ss.teacher_has_timetable; + const showTimetableView = isTimetableSection && node.status === 'populated'; + const showClassesView = isClassesSection && node.status === 'populated'; if (isSection) { return ( @@ -223,7 +229,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) { ) )} - {isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && ( + {isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && !isClassesSection && ( {node.status === 'no_school' ? @@ -249,7 +255,7 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) { {node.label} - {isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && node.status && ( + {isEmpty && !isCalendarSection && !isTimetableSection && !isSchoolSection && !isClassesSection && node.status && ( {node.status === 'no_school' ? '—' : '…'} @@ -319,6 +325,28 @@ function TreeItem({ node, depth, onSelect, onExpand }: TreeItemProps) { )} + {showTimetableView && ( + + { e.stopPropagation(); navigate('/my-lessons'); }} + > + + + + )} + {showClassesView && ( + + { e.stopPropagation(); navigate('/my-classes'); }} + > + + + + )} {/* Calendar mode toggle */}