From a58e4b6a3358e8eaa7f60eb69063bd9468cee4d8 Mon Sep 17 00:00:00 2001 From: Yumna Zaheed Date: Mon, 29 Sep 2025 15:31:01 +1000 Subject: [PATCH 1/6] modified course search tab width --- client/src/components/controls/Controls.tsx | 75 +++++++++++---------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/client/src/components/controls/Controls.tsx b/client/src/components/controls/Controls.tsx index 065fa3be3..2f00791dd 100644 --- a/client/src/components/controls/Controls.tsx +++ b/client/src/components/controls/Controls.tsx @@ -6,7 +6,6 @@ import { ControlsProps } from '../../interfaces/PropTypes'; import Autotimetabler from './Autotimetabler'; import CourseSelect from './CourseSelect'; import CustomEvents from './CustomEvent'; -import History from './History'; import TermSelect from './TermSelect'; const TermSelectWrapper = styled(Box)` @@ -27,23 +26,23 @@ const SelectWrapper = styled(Box)` flex-grow: 1; flex-shrink: 1; flex-basis: 0; + min-width: 420px; // Wider search bar `; -const AutotimetablerWrapper = styled(Box)` - flex: 1; - - ${({ theme }) => theme.breakpoints.down('sm')} { - flex: none; - } +const ButtonRow = styled(Box)` + display: flex; + justify-content: flex-end; + align-items: center; + width: 100%; + gap: 16px; `; -const CustomEventsWrapper = styled(Box)` - flex: 1; +const AutotimetablerWrapper = styled(Box)` + flex: none; `; -const HistoryWrapper = styled(Box)` - margin-top: 20px; - margin-left: 3px; +const CustomEventsWrapper = styled(Box)` + flex: none; `; const Controls: React.FC = ({ @@ -53,33 +52,37 @@ const Controls: React.FC = ({ handleRemoveCourse, }) => { return ( - - - - - - - - - + + {/* Term select and search bar */} + + + + + + + + + + + - - - - - - - - - - + {/* Create Event and Auto-Timetable buttons */} + + + + + + + + + ); }; -export default Controls; +export default Controls; \ No newline at end of file From 43a80eeb84a37fb15ac6f683197118f48ae73f13 Mon Sep 17 00:00:00 2001 From: Yumna Zaheed Date: Mon, 29 Sep 2025 15:31:38 +1000 Subject: [PATCH 2/6] aligned undo, redo, delete buttons with mytimetable --- .../timetableTabs/TimetableTabs.tsx | 130 ++++++++++-------- 1 file changed, 69 insertions(+), 61 deletions(-) diff --git a/client/src/components/timetableTabs/TimetableTabs.tsx b/client/src/components/timetableTabs/TimetableTabs.tsx index ed0371e91..3663b3d3d 100644 --- a/client/src/components/timetableTabs/TimetableTabs.tsx +++ b/client/src/components/timetableTabs/TimetableTabs.tsx @@ -26,6 +26,7 @@ import { } from '../../styles/TimetableTabStyles'; import storage from '../../utils/storage'; import TimetableTabContextMenu from './TimetableTabContextMenu'; +import History from '../controls/History'; const TimetableTabs: React.FC = () => { const TIMETABLE_LIMIT = 13; @@ -160,67 +161,74 @@ const TimetableTabs: React.FC = () => { setAnchorElement({ x: event.clientX, y: event.clientY }); }; + return ( - - - - - {(props) => ( - - {Object.keys(displayTimetables).length > 0 && term && displayTimetables[term] - ? displayTimetables[term]?.map((timetable: TimetableData, index: number) => ( - - {(props) => { - if (props.draggableProps.style?.transform) { - const horizShift = props.draggableProps.style?.transform.match(/(-?\d+)/g)?.map(Number)![0]; - // forcing horizontal movement - props.draggableProps.style.transform = `translate(${horizShift ? horizShift : 0}px, 0)`; - } - return ( - { - handleSwitchTimetables(displayTimetables[term], index); - }} - onContextMenu={(e) => { - handleRightTabClick(e, index); - }} - ref={props.innerRef} - {...props.draggableProps} - {...props.dragHandleProps} - sx={TabStyle(index, selectedTimetable)} - > - {displayTimetables[term][index].isPrimary && ( - - - - )} - {timetable.name} - {selectedTimetable === index ? ( - - - - ) : ( - <> - )} - - ); - }} - - )) - : null} - {props.placeholder} - - )} - - - - - - - - - - + + {/* Tabs section (left) */} + + + + + {(props) => ( + + {Object.keys(displayTimetables).length > 0 && term && displayTimetables[term] + ? displayTimetables[term]?.map((timetable: TimetableData, index: number) => ( + + {(props) => { + if (props.draggableProps.style?.transform) { + const horizShift = props.draggableProps.style?.transform.match(/(-?\d+)/g)?.map(Number)![0]; + props.draggableProps.style.transform = `translate(${horizShift ? horizShift : 0}px, 0)`; + } + return ( + { + handleSwitchTimetables(displayTimetables[term], index); + }} + onContextMenu={(e) => { + handleRightTabClick(e, index); + }} + ref={props.innerRef} + {...props.draggableProps} + {...props.dragHandleProps} + sx={TabStyle(index, selectedTimetable)} + > + {displayTimetables[term][index].isPrimary && ( + + + + )} + {timetable.name} + {selectedTimetable === index ? ( + + + + ) : ( + <> + )} + + ); + }} + + )) + : null} + {props.placeholder} + + )} + + + + + + + + + + + {/* History buttons (right) */} + + + + ); }; -export { TimetableTabs }; +export { TimetableTabs }; \ No newline at end of file From 92e3094674851347b84a4b3978518d9dc73fac1d Mon Sep 17 00:00:00 2001 From: Yumna Zaheed Date: Mon, 29 Sep 2025 16:31:45 +1000 Subject: [PATCH 3/6] reduced spacing between drop-down buttons --- client/src/components/controls/Controls.tsx | 86 +++++++-------------- 1 file changed, 29 insertions(+), 57 deletions(-) diff --git a/client/src/components/controls/Controls.tsx b/client/src/components/controls/Controls.tsx index 2f00791dd..dc2817fc5 100644 --- a/client/src/components/controls/Controls.tsx +++ b/client/src/components/controls/Controls.tsx @@ -1,4 +1,4 @@ -import { Box, Grid } from '@mui/material'; +import { Box } from '@mui/material'; import { styled } from '@mui/system'; import React from 'react'; @@ -7,42 +7,28 @@ import Autotimetabler from './Autotimetabler'; import CourseSelect from './CourseSelect'; import CustomEvents from './CustomEvent'; import TermSelect from './TermSelect'; +const ControlsBar = styled(Box)` + display: flex; + align-items: flex-end; // Align all controls to the bottom + padding-left: 66px; + gap: 12px; +`; const TermSelectWrapper = styled(Box)` - flex: 0 0 auto; - margin-top: 20px; - margin-right: 10px; min-width: 140px; - display: flex; - align-items: flex-start; + margin-bottom: 0; // Remove any margin that could misalign `; const SelectWrapper = styled(Box)` - display: flex; - flex-direction: row; - grid-column: 1 / -1; - grid-row: 1; - padding-top: 20px; - flex-grow: 1; - flex-shrink: 1; - flex-basis: 0; - min-width: 420px; // Wider search bar + flex-grow: 2; + min-width: 600px; // Wider search bar + margin-bottom: 0; `; const ButtonRow = styled(Box)` display: flex; - justify-content: flex-end; - align-items: center; - width: 100%; - gap: 16px; -`; - -const AutotimetablerWrapper = styled(Box)` - flex: none; -`; - -const CustomEventsWrapper = styled(Box)` - flex: none; + gap: 8px; // Reduced gap between buttons + margin-bottom: 0; `; const Controls: React.FC = ({ @@ -52,36 +38,22 @@ const Controls: React.FC = ({ handleRemoveCourse, }) => { return ( - - {/* Term select and search bar */} - - - - - - - - - - - - - {/* Create Event and Auto-Timetable buttons */} - - - - - - - - - - - + + + + + + + + + + + + ); }; From 4f132938cc7fb2af3c918a2008e97e0366e93910 Mon Sep 17 00:00:00 2001 From: yumnazaheed <150672503+yumnazaheed@users.noreply.github.com> Date: Wed, 8 Oct 2025 17:20:59 +1100 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Mark Tran <29350857+mark-trann@users.noreply.github.com> --- client/src/components/controls/Controls.tsx | 2 +- client/src/components/timetableTabs/TimetableTabs.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/controls/Controls.tsx b/client/src/components/controls/Controls.tsx index dc2817fc5..330d910d4 100644 --- a/client/src/components/controls/Controls.tsx +++ b/client/src/components/controls/Controls.tsx @@ -57,4 +57,4 @@ const Controls: React.FC = ({ ); }; -export default Controls; \ No newline at end of file +export default Controls; diff --git a/client/src/components/timetableTabs/TimetableTabs.tsx b/client/src/components/timetableTabs/TimetableTabs.tsx index 3663b3d3d..8862116c3 100644 --- a/client/src/components/timetableTabs/TimetableTabs.tsx +++ b/client/src/components/timetableTabs/TimetableTabs.tsx @@ -163,7 +163,7 @@ const TimetableTabs: React.FC = () => { return ( - + {/* Tabs section (left) */} @@ -231,4 +231,4 @@ const TimetableTabs: React.FC = () => { ); }; -export { TimetableTabs }; \ No newline at end of file +export { TimetableTabs }; From 02f8e0be16d2203459a8db95c8483dbc7083b587 Mon Sep 17 00:00:00 2001 From: Yumna Zaheed Date: Wed, 15 Oct 2025 01:02:58 +1100 Subject: [PATCH 5/6] improve tab and history button spacing --- client/src/App.tsx | 8 +- client/src/components/controls/Controls.tsx | 10 +-- client/src/components/controls/History.tsx | 77 ++++++++++--------- client/src/components/sidebar/Sidebar.tsx | 12 +-- .../timetableTabs/TimetableTabs.tsx | 31 ++++---- client/src/styles/TimetableTabStyles.tsx | 11 ++- 6 files changed, 84 insertions(+), 65 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index 1a6868c1d..694ae4d9e 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -2,7 +2,7 @@ import { Box, Button, GlobalStyles, StyledEngineProvider, ThemeProvider } from ' import { styled } from '@mui/system'; import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; -import React, { useContext, useEffect } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Outlet } from 'react-router-dom'; import getCourseInfo from './api/getCourseInfo'; @@ -99,6 +99,8 @@ const ICSButton = styled(Button)` `; const App: React.FC = () => { + + const [collapsed, setCollapsed] = useState(false); const { themeObject, currentTheme, @@ -638,7 +640,7 @@ const App: React.FC = () => { - + { {groupsSidebarCollapsed ? ( <> - + ) : ( diff --git a/client/src/components/controls/Controls.tsx b/client/src/components/controls/Controls.tsx index 330d910d4..5f090fde2 100644 --- a/client/src/components/controls/Controls.tsx +++ b/client/src/components/controls/Controls.tsx @@ -9,25 +9,25 @@ import CustomEvents from './CustomEvent'; import TermSelect from './TermSelect'; const ControlsBar = styled(Box)` display: flex; - align-items: flex-end; // Align all controls to the bottom + align-items: flex-end; padding-left: 66px; gap: 12px; `; const TermSelectWrapper = styled(Box)` min-width: 140px; - margin-bottom: 0; // Remove any margin that could misalign + margin-bottom: 0; `; const SelectWrapper = styled(Box)` flex-grow: 2; - min-width: 600px; // Wider search bar + min-width: 600px; margin-bottom: 0; `; const ButtonRow = styled(Box)` display: flex; - gap: 8px; // Reduced gap between buttons + gap: 8px; margin-bottom: 0; `; @@ -57,4 +57,4 @@ const Controls: React.FC = ({ ); }; -export default Controls; +export default Controls; \ No newline at end of file diff --git a/client/src/components/controls/History.tsx b/client/src/components/controls/History.tsx index 4afb53420..512fbb4f4 100644 --- a/client/src/components/controls/History.tsx +++ b/client/src/components/controls/History.tsx @@ -1,5 +1,6 @@ import { Delete, Redo, Undo } from '@mui/icons-material'; import { IconButton, Tooltip } from '@mui/material'; +import { Box } from '@mui/material'; import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; import { AppContext } from '../../context/AppContext'; @@ -31,7 +32,7 @@ const History: React.FC = () => { useContext(CourseContext); const { isDrag, setIsDrag, selectedTimetable, setSelectedTimetable, displayTimetables, setDisplayTimetables, term } = useContext(AppContext); - const { user } = useContext(UserContext); + const { user, groupsSidebarCollapsed } = useContext(UserContext); const timetableActions = useRef({}); const actionsPointer = useRef({}); @@ -332,46 +333,52 @@ const History: React.FC = () => { disableConfirm={disableReset.all} confirmButtonId="confirm-delete-button" /> - - { - setClearOpen(true); - }} - size="large" - > - - - - - + + { - changeHistory(-1); + setClearOpen(true); }} - size="large" + size={!groupsSidebarCollapsed ? 'small' : 'large'} > - + - - - - - { - changeHistory(1); - }} - size="large" - > - - - - + + + + { + changeHistory(-1); + }} + size={!groupsSidebarCollapsed ? 'small' : 'large'} + > + + + + + + + { + changeHistory(1); + }} + size={!groupsSidebarCollapsed ? 'small' : 'large'} + > + + + + + ); }; diff --git a/client/src/components/sidebar/Sidebar.tsx b/client/src/components/sidebar/Sidebar.tsx index 82ad2a024..417048cfc 100644 --- a/client/src/components/sidebar/Sidebar.tsx +++ b/client/src/components/sidebar/Sidebar.tsx @@ -169,21 +169,23 @@ const modalData = [ }, ]; -const Sidebar: React.FC = () => { +interface SidebarProps { + collapsed: boolean; + setCollapsed: (val: boolean) => void; +} + +const Sidebar: React.FC = ({ collapsed, setCollapsed }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')); const collapsedWidth = useMemo(() => (isMobile ? 0 : 80), [isMobile]); const isWide = useMediaQuery(theme.breakpoints.only('xl')); const [currLogo, setCurrLogo] = useState(notanglesLogo); - const [collapsed, setCollapsed] = useState(() => !isWide); const { groupsSidebarCollapsed } = useContext(UserContext); const handleCollapse = (val: boolean) => { setCollapsed(val); - // forces window resize event upon sidebar state changing to adjust position of cards - // Not currently used, but here is how you would do it if needed - // setTimeout(() => window.dispatchEvent(new Event('resize')), 120); + }; const modalComponents = useMemo( diff --git a/client/src/components/timetableTabs/TimetableTabs.tsx b/client/src/components/timetableTabs/TimetableTabs.tsx index 8862116c3..6ce8dee27 100644 --- a/client/src/components/timetableTabs/TimetableTabs.tsx +++ b/client/src/components/timetableTabs/TimetableTabs.tsx @@ -28,7 +28,11 @@ import storage from '../../utils/storage'; import TimetableTabContextMenu from './TimetableTabContextMenu'; import History from '../controls/History'; -const TimetableTabs: React.FC = () => { +interface TimetableTabsProps { + collapsed: boolean; +} + +const TimetableTabs: React.FC = ({ collapsed }) => { const TIMETABLE_LIMIT = 13; const { @@ -58,7 +62,7 @@ const TimetableTabs: React.FC = () => { setTabTheme(isDarkMode ? tabThemeDark : tabThemeLight); }, [isDarkMode]); - // Helper function to set the timetable state + const setTimetableState = ( selectedCourses: CourseData[], selectedClasses: SelectedClasses, @@ -73,9 +77,7 @@ const TimetableTabs: React.FC = () => { setSelectedTimetable(timetableIndex); }; - /** - * Timetable handlers - */ + // Creates new timetable const handleCreateTimetable = () => { if (!term) return; @@ -106,9 +108,7 @@ const TimetableTabs: React.FC = () => { } }; - /** - * Drag and drop functions for rearranging timetable tabs - */ + // Handles timetable switching by updating the selected courses, classes and events to the new timetable const handleSwitchTimetables = (timetables: TimetableData[], timetableIndex: number) => { const { selectedCourses, selectedClasses, createdEvents, assignedColors } = timetables[timetableIndex]; @@ -142,9 +142,7 @@ const TimetableTabs: React.FC = () => { handleSwitchTimetables(newTimetables, destination.index); }; - /** - * Dropdown menu tab handlers - */ + // Left click handler for the three dots icon (editing the timetable tab) const handleMenuClick = (e: React.MouseEvent) => { e.preventDefault(); @@ -164,8 +162,11 @@ const TimetableTabs: React.FC = () => { return ( - {/* Tabs section (left) */} - + + 5)} + > @@ -224,8 +225,8 @@ const TimetableTabs: React.FC = () => { - {/* History buttons (right) */} - + + diff --git a/client/src/styles/TimetableTabStyles.tsx b/client/src/styles/TimetableTabStyles.tsx index 9210d86a5..b8aa26cb7 100644 --- a/client/src/styles/TimetableTabStyles.tsx +++ b/client/src/styles/TimetableTabStyles.tsx @@ -34,10 +34,17 @@ export const StyledSnackbar = styled(Snackbar)(({ theme }) => ({ }, })); -export const TabsSection = styled(Box)` +export const TabsSection = styled(Box, { shouldForwardProp: (prop) => prop !== 'shouldScroll' })< + BoxProps & { shouldScroll?: boolean } +>` padding-top: 20px; margin-left: 66px; - overflow: auto; + ${(props) => props.shouldScroll ? ` + overflow: auto; + max-width: calc(100vw - 200px); /* Adjust based on your layout */ + ` : ` + overflow: visible; + `} &::-webkit-scrollbar { height: 5px; } From 0574862f2376d2b78f22d8ec050aa9f4eb0c1e7e Mon Sep 17 00:00:00 2001 From: Yumna Zaheed Date: Wed, 15 Oct 2025 01:18:11 +1100 Subject: [PATCH 6/6] reduced space between timetable tabs and history buttons --- client/src/components/timetableTabs/TimetableTabs.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/timetableTabs/TimetableTabs.tsx b/client/src/components/timetableTabs/TimetableTabs.tsx index 6ce8dee27..b21071311 100644 --- a/client/src/components/timetableTabs/TimetableTabs.tsx +++ b/client/src/components/timetableTabs/TimetableTabs.tsx @@ -164,7 +164,7 @@ const TimetableTabs: React.FC = ({ collapsed }) => { 5)} > @@ -226,7 +226,7 @@ const TimetableTabs: React.FC = ({ collapsed }) => { - +