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 065fa3be3..5f090fde2 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';
@@ -6,44 +6,29 @@ 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 ControlsBar = styled(Box)`
+ display: flex;
+ align-items: flex-end;
+ 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;
`;
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;
+ flex-grow: 2;
+ min-width: 600px;
+ margin-bottom: 0;
`;
-const AutotimetablerWrapper = styled(Box)`
- flex: 1;
-
- ${({ theme }) => theme.breakpoints.down('sm')} {
- flex: none;
- }
-`;
-
-const CustomEventsWrapper = styled(Box)`
- flex: 1;
-`;
-
-const HistoryWrapper = styled(Box)`
- margin-top: 20px;
- margin-left: 3px;
+const ButtonRow = styled(Box)`
+ display: flex;
+ gap: 8px;
+ margin-bottom: 0;
`;
const Controls: React.FC = ({
@@ -53,33 +38,23 @@ const Controls: React.FC = ({
handleRemoveCourse,
}) => {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
);
};
-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 ed0371e91..b21071311 100644
--- a/client/src/components/timetableTabs/TimetableTabs.tsx
+++ b/client/src/components/timetableTabs/TimetableTabs.tsx
@@ -26,8 +26,13 @@ import {
} from '../../styles/TimetableTabStyles';
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 {
@@ -57,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,
@@ -72,9 +77,7 @@ const TimetableTabs: React.FC = () => {
setSelectedTimetable(timetableIndex);
};
- /**
- * Timetable handlers
- */
+
// Creates new timetable
const handleCreateTimetable = () => {
if (!term) return;
@@ -105,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];
@@ -141,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();
@@ -160,67 +159,77 @@ 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}
-
- )}
-
-
-
-
-
-
-
-
-
-
+
+
+ 5)}
+ >
+
+
+
+ {(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}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
export { TimetableTabs };
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;
}