Skip to content

Commit

Permalink
Make course menu bar resizeable (#1042)
Browse files Browse the repository at this point in the history
  • Loading branch information
martanman authored Jun 26, 2023
1 parent 9978980 commit cc74c22
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 9 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ tmp.*
**/.vscode
**/.DS_Store
.idea
**/Session.vim

# "sensitive" data (i.e. raw zID)
backend/data/scrapers/enrolmentDataRaw.json
backend/data/scrapers/enrolmentDataRaw.json
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,4 @@ const CourseDescriptionPanel = ({
);
};

export default CourseDescriptionPanel;
export default React.memo(CourseDescriptionPanel);
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,4 @@ const CourseMenu = ({ structure }: Props) => {
);
};

export default CourseMenu;
export default React.memo(CourseMenu);
1 change: 1 addition & 0 deletions frontend/src/pages/CourseSelector/CourseMenu/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const SidebarWrapper = styled.div`
overflow: auto;
overflow-x: hidden;
height: 100%;
width: 100%;
border-right: 1px solid ${({ theme }) => theme.courseMenu?.borderColor};
`;

Expand Down
38 changes: 35 additions & 3 deletions frontend/src/pages/CourseSelector/CourseSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import axios from 'axios';
import { Structure } from 'types/api';
Expand Down Expand Up @@ -55,18 +55,50 @@ const CourseSelector = () => {
if (programCode) fetchStructure();
}, [programCode, specs]);

const divRef = useRef<null | HTMLDivElement>(null);
const [menuOffset, setMenuOffset] = useState<number | undefined>(undefined);
useEffect(() => {
const minMenuWidth = 100;
const maxMenuWidth = (60 * window.innerWidth) / 100;
const resizerDiv = divRef.current as HTMLDivElement;
const setNewWidth = (clientX: number) => {
if (clientX > minMenuWidth && clientX < maxMenuWidth) {
resizerDiv.style.left = `${clientX}px`;
setMenuOffset(clientX);
}
};
const handleResize = (ev: globalThis.MouseEvent) => {
setNewWidth(ev.clientX);
};
const endResize = (ev: MouseEvent) => {
setNewWidth(ev.clientX);
window.removeEventListener('mousemove', handleResize);
window.removeEventListener('mouseup', endResize); // remove myself
};
const startResize = (ev: MouseEvent) => {
ev.preventDefault(); // stops highlighting text
window.addEventListener('mousemove', handleResize);
window.addEventListener('mouseup', endResize);
};
resizerDiv?.addEventListener('mousedown', startResize);
return () => resizerDiv?.removeEventListener('mousedown', startResize);
}, []);

const onCourseClick = useCallback((code: string) => dispatch(addTab(code)), [dispatch]);

return (
<PageTemplate>
<S.ContainerWrapper>
<CourseBanner />
<CourseTabs />
<S.ContentWrapper>
<S.ContentWrapper offset={menuOffset}>
<CourseMenu structure={structure} />
<S.ContentResizer ref={divRef} offset={menuOffset} />
{courseCode ? (
<div style={{ overflow: 'auto' }}>
<CourseDescriptionPanel
courseCode={courseCode}
onCourseClick={(code) => dispatch(addTab(code))}
onCourseClick={onCourseClick}
courseDescInfoCache={courseDescInfoCache}
/>
</div>
Expand Down
17 changes: 14 additions & 3 deletions frontend/src/pages/CourseSelector/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,23 @@ const ContainerWrapper = styled.div`
height: calc(100vh - var(--navbar-height));
`;

const ContentWrapper = styled.div`
const ContentWrapper = styled.div<{ offset?: number }>`
display: grid;
grid-template-columns: 20vw auto;
grid-template-columns: ${({ offset }) => (offset ? `${offset}px` : '20vw')} auto;
height: var(--cs-bottom-cont-height);
`;

const ContentResizer = styled.div<{ offset?: number }>`
cursor: col-resize;
height: 100%;
width: 6px;
background-color: transparent;
position: fixed;
left: ${({ offset }) => (offset ? `${offset}px` : '20vw')};
margin-left: -3px;
z-index: 100;
`;

const InfographicContainer = styled.div`
@keyframes fadeIn {
0% {
Expand Down Expand Up @@ -40,4 +51,4 @@ const InfographicContainer = styled.div`
}
`;

export default { ContainerWrapper, ContentWrapper, InfographicContainer };
export default { ContainerWrapper, ContentResizer, ContentWrapper, InfographicContainer };

0 comments on commit cc74c22

Please sign in to comment.