From 4995d7ca340cb28655b3d8499811840f34ddbb04 Mon Sep 17 00:00:00 2001 From: August Fu Date: Wed, 14 Feb 2024 16:22:08 -0500 Subject: [PATCH] fix ratings badge, drag & drop in search panel, style improvements --- .../components/Requirements/QObject.tsx | 20 ++++++----- .../components/Requirements/Requirement.tsx | 2 +- .../degree-plan/components/Search/Course.tsx | 33 +++++++++++++------ .../components/Search/SearchPanel.tsx | 14 +++++--- .../degree-plan/pages/FourYearPlanPage.tsx | 16 ++++----- frontend/degree-plan/styles/globals.css | 15 +++++++++ 6 files changed, 65 insertions(+), 35 deletions(-) diff --git a/frontend/degree-plan/components/Requirements/QObject.tsx b/frontend/degree-plan/components/Requirements/QObject.tsx index 9729908c3..7a677e113 100644 --- a/frontend/degree-plan/components/Requirements/QObject.tsx +++ b/frontend/degree-plan/components/Requirements/QObject.tsx @@ -82,10 +82,11 @@ interface SearchConditionProps { chosenOptions: Course["full_code"][]; setChosenOptions: (arg0: Course["full_code"][]) => void; setSearchClosed: (status: boolean) => void; - handleSearch: (reqId: number) => void; + handleSearch: (reqId: number, reqQuery: string) => void; reqId: number; + reqQuery: string; } -const SearchCondition = ({ compound, chosenOptions, setChosenOptions, setSearchClosed, handleSearch, reqId}: SearchConditionProps) => { +const SearchCondition = ({ compound, chosenOptions, setChosenOptions, setSearchClosed, handleSearch, reqId, reqQuery}: SearchConditionProps) => { const conditions = compound.clauses.filter((clause) => clause.type === "LEAF") as Condition[]; const compounds = compound.clauses.filter((clause) => clause.type !== "LEAF") as Compound[]; @@ -128,7 +129,7 @@ const SearchCondition = ({ compound, chosenOptions, setChosenOptions, setSearchC compounds.forEach((compound) => display.push( {'('}asnd - + {')'}asdf )); @@ -144,7 +145,7 @@ const SearchCondition = ({ compound, chosenOptions, setChosenOptions, setSearchC [elem, and] : [elem] )} -
{handleSearch(reqId);}}> +
{handleSearch(reqId, reqQuery);}}> @@ -158,15 +159,16 @@ interface TerminalProps { chosenOptions: Course["full_code"][]; setChosenOptions: (arg0: Course["full_code"][]) => void; reqId: number; + reqQuery: string; handleSearch: (reqId: number) => void; } -const Terminal = ({ q, chosenOptions, setChosenOptions, handleSearch, reqId }: TerminalProps) => { +const Terminal = ({ q, chosenOptions, setChosenOptions, handleSearch, reqId, reqQuery }: TerminalProps) => { assert(q.type !== "OR"); if (q.type === 'LEAF' && q.key === "full_code") return ( ); if (q.type === 'LEAF') return ( - + ); if (q.type === 'AND' && q.clauses.length == 2) { const semester = q.clauses.find((clause) => clause.type === "LEAF" && clause.key === "semester") @@ -180,7 +182,7 @@ const Terminal = ({ q, chosenOptions, setChosenOptions, handleSearch, reqId }: T /> ); } - return ; + return ; } const CourseOptionsSeparator = styled.div` @@ -190,7 +192,7 @@ const CourseOptionsSeparator = styled.div` font-weight: 500; `; -const QObject = ({ q, reqId, handleSearch }: { q: string; reqId: number; handleSearch: (reqId: number) => void; }) => { +const QObject = ({ q, reqId, handleSearch }: { q: string; reqId: number; handleSearch: (reqId: number, reqQuery: string) => void; }) => { const qObjParser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar)); let parsed = qObjParser.feed(q).results[0] as ParsedQObj; const [chosenOptions, setChosenOptions] = useState([]); @@ -202,7 +204,7 @@ const QObject = ({ q, reqId, handleSearch }: { q: string; reqId: number; handleS return ( {parsed.clauses - .map((clause) => ) + .map((clause) => ) .flatMap((elem, index) => ( index < parsed.clauses.length - 1 ? [elem, or] : diff --git a/frontend/degree-plan/components/Requirements/Requirement.tsx b/frontend/degree-plan/components/Requirements/Requirement.tsx index 6cad4372d..fa1fd0614 100644 --- a/frontend/degree-plan/components/Requirements/Requirement.tsx +++ b/frontend/degree-plan/components/Requirements/Requirement.tsx @@ -13,7 +13,7 @@ const RuleTitle = styled.div` justify-content: space-between; align-items: center; width: 100%; - background-color: #F5F5F5; + background-color: var(--primary-color-light); color: #575757; padding: 0.25rem .5rem; margin: 0.5rem 0; diff --git a/frontend/degree-plan/components/Search/Course.tsx b/frontend/degree-plan/components/Search/Course.tsx index ad47cbf5d..c8fe9b964 100644 --- a/frontend/degree-plan/components/Search/Course.tsx +++ b/frontend/degree-plan/components/Search/Course.tsx @@ -1,5 +1,7 @@ import React, { useState } from "react"; import styled from "styled-components"; +import { useDrag } from "react-dnd"; +import { ItemTypes } from "../dnd/constants"; import Badge from "./Badge"; // import { Course as CourseType } from "../../types"; @@ -62,13 +64,17 @@ const CourseTitle = styled.span` color: #888888; `; -const CourseQualityContainer = styled.div<{ $isRecCourse: boolean }>` - margin-right: 2px; - width: ${({ $isRecCourse: isRecCourse }) => (isRecCourse ? "20.75%" : "20%")}; +const CourseQualityContainer = styled.div` + margin-right: 1.5px; + width: 20%; + padding-left: 7px; + padding-top: 5px; `; -const CourseDifficultyContainer = styled.div<{ $isRecCourse: boolean }>` - width: ${({ $isRecCourse: isRecCourse }) => (isRecCourse ? "20.75%" : "20%")}; +const CourseDifficultyContainer = styled.div` + width: 20%; + padding-left: 7px; + padding-top: 5px; `; const InfoPopup = styled.div<{ $show: boolean }>` @@ -106,8 +112,15 @@ export default function Course({ onClickDelete, isStar, }: CourseProps) { - const existIsRecCourse = isRecCourse ?? false; - const [showInfo, setShowInfo] = useState(false); + /** React dnd */ + const [{ isDragging, color }, drag, dragPreview] = useDrag(() => ({ + type: ItemTypes.COURSE, + item: {course: {...course, satisfyIds:[]}, semester:-1}, + collect: (monitor) => ({ + isDragging: !!monitor.isDragging(), + color: monitor.isDragging() ? 'none' : 'none' + }) + })) return ( // eslint-disable-next-line @@ -119,16 +132,16 @@ export default function Course({ > - {course.id.replace(/-/g, " ")} + {course.id.replace(/-/g, " ")} {course.title} - + {/*course.course_quality*/} - + {/*course.difficulty*/} diff --git a/frontend/degree-plan/components/Search/SearchPanel.tsx b/frontend/degree-plan/components/Search/SearchPanel.tsx index 81d57b3ff..9e6e6031c 100644 --- a/frontend/degree-plan/components/Search/SearchPanel.tsx +++ b/frontend/degree-plan/components/Search/SearchPanel.tsx @@ -21,17 +21,21 @@ const SearchContainer = styled.div` label { font-size: 0.75rem; }; + padding-left: 0.6em; + padding-right: 0.5em; `; const SearchField = styled.input` - min-width: 17rem; - background-color: #f4f4f4; - padding-left: 1em; + width: 100%; + min-width: 10rem; + background-color: var(--background-grey); + padding-left: 0.5em; border-radius: 5px; border-width: 0.8px; + outline: transparent !important; `; -const SearchPanel = ({setClosed, reqId, showCourseDetail, searchReqId}:any) => { +const SearchPanel = ({setClosed, reqId, reqQuery, showCourseDetail, searchReqId}:any) => { const { data: courses, isLoading: isLoadingCourses } = useSWR(`api/degree/courses/${reqId}`, { refreshInterval: 0, fallbackData: [] }); type ISearchResultCourse = {course: ICourseQ} @@ -80,7 +84,7 @@ const SearchPanel = ({setClosed, reqId, showCourseDetail, searchReqId}:any) => { value={queryString} onChange={(e) => setQueryString(e.target.value)} autoComplete="off" - placeholder="Search" + placeholder={reqQuery} // disabled={isDisabled} /> diff --git a/frontend/degree-plan/pages/FourYearPlanPage.tsx b/frontend/degree-plan/pages/FourYearPlanPage.tsx index f9756feec..82b45dc5c 100644 --- a/frontend/degree-plan/pages/FourYearPlanPage.tsx +++ b/frontend/degree-plan/pages/FourYearPlanPage.tsx @@ -44,7 +44,7 @@ const Divider = styled.div` width: 10px; height: 20vh; border-radius: 10px; - background-color: #C5D2F6; + background-color: var(--primary-color-dark); margin-left: 3px; margin-right: 3px; margin-top: 30vh; @@ -76,6 +76,7 @@ const FourYearPlanPage = () => { const [courseDetailOpen, setCourseDetailOpen] = useState(false); const [courseDetail, setCourseDetail] = useState({}); + const [reqQuery, setReqQuery] = useState(""); const [highlightReqId, setHighlightReqId] = useState(-1); @@ -132,18 +133,13 @@ const FourYearPlanPage = () => { const [reqId, setReqId] = useState(undefined); const [loading, setLoading] = useState(false); - const handleSearch = async (id: number) => { + const handleSearch = async (id: number, query: string) => { // setHighlightReqId(id); - console.log(id); setSearchClosed(false); + console.log(query); setLoading(true); + setReqQuery(query); if (id != undefined) setReqId(id); - - // axios.get(`/degree/courses/${id}`).then(res => { - // let newData = [...res.data]; - // setResults(newData); - // setLoading(false); - // }); } const showCourseDetail = (course: any) => { @@ -163,7 +159,7 @@ const FourYearPlanPage = () => {