diff --git a/site/src/component/SideBar/SideBar.tsx b/site/src/component/SideBar/SideBar.tsx index 8ac43cbb..ab2cc4d4 100644 --- a/site/src/component/SideBar/SideBar.tsx +++ b/site/src/component/SideBar/SideBar.tsx @@ -1,15 +1,15 @@ import { useEffect, useState } from 'react'; -import { NavLink } from 'react-router-dom'; -import { Icon } from 'semantic-ui-react'; import { XCircle } from 'react-bootstrap-icons'; import { useCookies } from 'react-cookie'; -import './Sidebar.scss'; +import { NavLink } from 'react-router-dom'; import { CSSTransition } from 'react-transition-group'; +import { Icon } from 'semantic-ui-react'; import Logo from '../../asset/peterportal-banner-logo.svg'; +import './Sidebar.scss'; -import { useAppSelector, useAppDispatch } from '../..//store/hooks'; -import { setSidebarStatus } from '../../store/slices/uiSlice'; import axios, { AxiosResponse } from 'axios'; +import { useAppDispatch, useAppSelector } from '../..//store/hooks'; +import { setSidebarStatus } from '../../store/slices/uiSlice'; import Footer from '../Footer/Footer'; const SideBar = () => { diff --git a/site/src/component/SideBar/Sidebar.scss b/site/src/component/SideBar/Sidebar.scss index 73a65e1b..3a234854 100644 --- a/site/src/component/SideBar/Sidebar.scss +++ b/site/src/component/SideBar/Sidebar.scss @@ -9,7 +9,6 @@ flex-direction: column; justify-content: flex-start; align-items: center; - ul { list-style: none; margin: 0; diff --git a/site/src/pages/RoadmapPage/AddCoursePopup.tsx b/site/src/pages/RoadmapPage/AddCoursePopup.tsx index 9e36b824..4bbc8068 100644 --- a/site/src/pages/RoadmapPage/AddCoursePopup.tsx +++ b/site/src/pages/RoadmapPage/AddCoursePopup.tsx @@ -1,11 +1,11 @@ -import React, { FC, useState } from 'react'; -import Form from 'react-bootstrap/Form'; +import React, { FC, useEffect, useState } from 'react'; import Button from 'react-bootstrap/Button'; -import './AddCoursePopup.scss'; -import { useAppDispatch, useAppSelector } from '../../store/hooks'; -import { moveCourse, setShowAddCourse } from '../../store/slices/roadmapSlice'; +import Form from 'react-bootstrap/Form'; import Modal from 'react-bootstrap/Modal'; import { quarterDisplayNames } from '../../helpers/planner'; +import { useAppDispatch, useAppSelector } from '../../store/hooks'; +import { moveCourse, setShowAddCourse, setShowSearch } from '../../store/slices/roadmapSlice'; +import './AddCoursePopup.scss'; interface AddCoursePopupProps {} @@ -13,9 +13,16 @@ const AddCoursePopup: FC = () => { const dispatch = useAppDispatch(); const planner = useAppSelector((state) => state.roadmap.yearPlans); const showForm = useAppSelector((state) => state.roadmap.showAddCourse); - const [year, setYear] = useState(-1); - const [quarter, setQuarter] = useState(-1); + const currentYearAndQuarter = useAppSelector((state) => state.roadmap.currentYearAndQuarter); + const [year, setYear] = useState(currentYearAndQuarter?.year ?? -1); + const [quarter, setQuarter] = useState(currentYearAndQuarter?.quarter ?? -1); const [validated, setValidated] = useState(false); + const activeCourse = useAppSelector((state) => state.roadmap.activeCourse); + + useEffect(() => { + setYear(currentYearAndQuarter?.year ?? -1); + setQuarter(currentYearAndQuarter?.quarter ?? -1); + }, [currentYearAndQuarter]); const closeForm = () => { // close form @@ -53,13 +60,19 @@ const AddCoursePopup: FC = () => { }), ); + // hide the search bar to view the roadmap + dispatch(setShowSearch({ show: false })); + closeForm(); }; const addCourseForm = (

Add Course

-

Where do you want to add this course?

+

+ Where do you want to add {activeCourse ? activeCourse.department + ' ' + activeCourse.courseNumber : 'a course'} + ? +

School Year = () => { name="year" id="year" required + value={year === -1 ? '' : year} onChange={(e) => { const parsed = parseInt(e.target.value); if (isNaN(parsed)) { @@ -98,6 +112,7 @@ const AddCoursePopup: FC = () => { name="quarter" id="quarter" required + value={quarter === -1 ? '' : quarter} onChange={(e) => { const parsed = parseInt(e.target.value); if (!isNaN(parsed)) { diff --git a/site/src/pages/RoadmapPage/CourseHitItem.tsx b/site/src/pages/RoadmapPage/CourseHitItem.tsx index a603f8bd..01cf182f 100644 --- a/site/src/pages/RoadmapPage/CourseHitItem.tsx +++ b/site/src/pages/RoadmapPage/CourseHitItem.tsx @@ -1,11 +1,11 @@ import { FC } from 'react'; -import { setActiveCourse, setShowAddCourse, setShowSearch } from '../../store/slices/roadmapSlice'; +import { Draggable } from 'react-beautiful-dnd'; import { useAppDispatch } from '../../store/hooks'; +import { setActiveCourse, setShowAddCourse } from '../../store/slices/roadmapSlice'; import Course from './Course'; -import { Draggable } from 'react-beautiful-dnd'; -import { CourseGQLData } from '../../types/types'; import { useIsMobile } from '../../helpers/util'; +import { CourseGQLData } from '../../types/types'; interface CourseHitItemProps extends CourseGQLData { index: number; @@ -19,7 +19,6 @@ const CourseHitItem: FC = (props: CourseHitItemProps) => { dispatch(setActiveCourse(props)); dispatch(setShowAddCourse(true)); // also hide the search bar to view the roadmap - dispatch(setShowSearch(false)); }; const onMobileKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { diff --git a/site/src/pages/RoadmapPage/Header.tsx b/site/src/pages/RoadmapPage/Header.tsx index eab0fae0..12522d02 100644 --- a/site/src/pages/RoadmapPage/Header.tsx +++ b/site/src/pages/RoadmapPage/Header.tsx @@ -1,11 +1,11 @@ import React, { FC, useState } from 'react'; -import './Header.scss'; -import { Button, ButtonGroup, Popover, Overlay } from 'react-bootstrap'; -import { ArrowLeftRight, Save, Plus, List, Trash } from 'react-bootstrap-icons'; -import { setShowTransfer, setShowSearch, clearPlanner } from '../../store/slices/roadmapSlice'; +import { Button, ButtonGroup, Overlay, Popover } from 'react-bootstrap'; +import { ArrowLeftRight, List, Save, Trash } from 'react-bootstrap-icons'; +import { useIsDesktop, useIsMobile } from '../../helpers/util'; import { useAppDispatch } from '../../store/hooks'; +import { clearPlanner, setShowTransfer } from '../../store/slices/roadmapSlice'; +import './Header.scss'; import Transfer from './Transfer'; -import { useIsDesktop, useIsMobile } from '../../helpers/util'; interface HeaderProps { courseCount: number; @@ -72,16 +72,6 @@ const Header: FC = ({ courseCount, unitCount, saveRoadmap, missingP
{isMobile && ( <> - diff --git a/site/src/pages/RoadmapPage/Quarter.scss b/site/src/pages/RoadmapPage/Quarter.scss index 8a879e43..b20129b7 100644 --- a/site/src/pages/RoadmapPage/Quarter.scss +++ b/site/src/pages/RoadmapPage/Quarter.scss @@ -1,7 +1,11 @@ [data-theme='dark'] { - .quarter .quarter-header .quarter-title { + .quarter .quarter-header .quarter-title, + .quarter .quarter-add-course { color: #eee; } + .plus-icon { + fill: #eee; + } .quarter-menu-btn:hover, .quarter-menu-btn:focus, @@ -44,6 +48,11 @@ color: #808080; font-size: 16px; } + + .quarter-add-course { + color: #202e47; + font-size: 15px; + } } .quarter-menu-btn { @@ -59,6 +68,10 @@ z-index: 1; } +.plus-icon { + fill: #000000; +} + .red-menu-btn, .red-menu-btn:hover, .red-menu-btn:focus, diff --git a/site/src/pages/RoadmapPage/Quarter.tsx b/site/src/pages/RoadmapPage/Quarter.tsx index 2eb0fcbd..4bb5ddf2 100644 --- a/site/src/pages/RoadmapPage/Quarter.tsx +++ b/site/src/pages/RoadmapPage/Quarter.tsx @@ -1,16 +1,17 @@ import { FC, useContext, useRef, useState } from 'react'; -import './Quarter.scss'; import { Draggable } from 'react-beautiful-dnd'; -import Course from './Course'; - -import { useAppDispatch, useAppSelector } from '../../store/hooks'; -import { deleteQuarter, clearQuarter, deleteCourse } from '../../store/slices/roadmapSlice'; -import { PlannerQuarterData } from '../../types/types'; import { Button, OverlayTrigger, Popover } from 'react-bootstrap'; -import { ThreeDots } from 'react-bootstrap-icons'; +import { Plus, ThreeDots } from 'react-bootstrap-icons'; +import { quarterDisplayNames } from '../../helpers/planner'; +import { useIsMobile } from '../../helpers/util'; +import { useAppDispatch, useAppSelector } from '../../store/hooks'; +import { clearQuarter, deleteCourse, deleteQuarter, setShowSearch } from '../../store/slices/roadmapSlice'; import ThemeContext from '../../style/theme-context'; +import { PlannerQuarterData } from '../../types/types'; +import './Quarter.scss'; import { StrictModeDroppable } from './StrictModeDroppable'; -import { quarterDisplayNames } from '../../helpers/planner'; + +import Course from './Course'; interface QuarterProps { year: number; @@ -24,7 +25,7 @@ const Quarter: FC = ({ year, yearIndex, quarterIndex, data }) => { const quarterTitle = quarterDisplayNames[data.name]; const invalidCourses = useAppSelector((state) => state.roadmap.invalidCourses); const quarterContainerRef = useRef(null); - + const isMobile = useIsMobile(); const [showQuarterMenu, setShowQuarterMenu] = useState(false); const { darkMode } = useContext(ThemeContext); @@ -157,6 +158,21 @@ const Quarter: FC = ({ year, yearIndex, quarterIndex, data }) => { ); }} + + {isMobile && ( + <> + + + )}
); }; diff --git a/site/src/pages/RoadmapPage/SearchSidebar.tsx b/site/src/pages/RoadmapPage/SearchSidebar.tsx index e2ff68e6..883ef666 100644 --- a/site/src/pages/RoadmapPage/SearchSidebar.tsx +++ b/site/src/pages/RoadmapPage/SearchSidebar.tsx @@ -1,14 +1,14 @@ import './SearchSidebar.scss'; import CloseButton from 'react-bootstrap/CloseButton'; -import SearchModule from '../../component/SearchModule/SearchModule'; import SearchHitContainer from '../../component/SearchHitContainer/SearchHitContainer'; +import SearchModule from '../../component/SearchModule/SearchModule'; import CourseHitItem from './CourseHitItem'; +import { useIsMobile } from '../../helpers/util'; import { useAppDispatch } from '../../store/hooks'; import { setShowSearch } from '../../store/slices/roadmapSlice'; import { StrictModeDroppable } from './StrictModeDroppable'; -import { useIsMobile } from '../../helpers/util'; const SearchSidebar = () => { const dispatch = useAppDispatch(); @@ -21,7 +21,7 @@ const SearchSidebar = () => { { - dispatch(setShowSearch(false)); + dispatch(setShowSearch({ show: false })); }} /> diff --git a/site/src/store/slices/roadmapSlice.ts b/site/src/store/slices/roadmapSlice.ts index 5d790672..78195f1c 100644 --- a/site/src/store/slices/roadmapSlice.ts +++ b/site/src/store/slices/roadmapSlice.ts @@ -1,17 +1,17 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import type { RootState } from '../store'; +import { defaultYear, quarterDisplayNames } from '../../helpers/planner'; import { - PlannerData, - PlannerYearData, CourseGQLData, - YearIdentifier, - QuarterIdentifier, CourseIdentifier, InvalidCourseData, - TransferData, + PlannerData, PlannerQuarterData, + PlannerYearData, + QuarterIdentifier, + TransferData, + YearIdentifier, } from '../../types/types'; -import { defaultYear, quarterDisplayNames } from '../../helpers/planner'; +import type { RootState } from '../store'; // Define a type for the slice state interface RoadmapState { @@ -31,6 +31,8 @@ interface RoadmapState { showAddCourse: boolean; // Whether or not to alert the user of unsaved changes before leaving unsavedChanges: boolean; + // Selected quarter and year for adding a course on mobile + currentYearAndQuarter: { year: number; quarter: number } | null; } // Define the initial state using that type @@ -43,6 +45,7 @@ const initialState: RoadmapState = { showSearch: false, showAddCourse: false, unsavedChanges: false, + currentYearAndQuarter: null, }; // Payload to pass in to move a course @@ -259,8 +262,11 @@ export const roadmapSlice = createSlice({ deleteTransfer: (state, action: PayloadAction) => { state.transfers.splice(action.payload, 1); }, - setShowSearch: (state, action: PayloadAction) => { - state.showSearch = action.payload; + setShowSearch: (state, action: PayloadAction<{ show: boolean; year?: number; quarter?: number }>) => { + state.showSearch = action.payload.show; + if (action.payload.year !== undefined && action.payload.quarter !== undefined) { + state.currentYearAndQuarter = { year: action.payload.year, quarter: action.payload.quarter }; + } }, setShowAddCourse: (state, action: PayloadAction) => { state.showAddCourse = action.payload;