From 0ef268c7de58bd8c632d32f07a093dee82d9d7e3 Mon Sep 17 00:00:00 2001 From: Philip Truong <71199572+ptruong0@users.noreply.github.com> Date: Thu, 22 Feb 2024 00:47:17 -0800 Subject: [PATCH] Add a filter by course or professor to reviews (#429) * draft * works * compare roadmap with prev state * Update site/package.json Co-authored-by: Jacob Sommer * check empty roadmap * new dropdowns * sort alphabetically, include review counts * Update site/src/component/Review/Review.tsx Co-authored-by: Jacob Sommer * Update site/src/component/Review/Review.tsx Co-authored-by: Jacob Sommer * prettier * prettier --------- Co-authored-by: Jacob Sommer --- site/src/component/Review/Review.tsx | 77 +++++++++++++++++++++++ site/src/pages/CoursePage/CoursePage.scss | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/site/src/component/Review/Review.tsx b/site/src/component/Review/Review.tsx index e71ee077..8b2189b7 100644 --- a/site/src/component/Review/Review.tsx +++ b/site/src/component/Review/Review.tsx @@ -25,6 +25,7 @@ const Review: FC = (props) => { const reviewData = useAppSelector(selectReviews); const [voteColors, setVoteColors] = useState([]); const [sortingOption, setSortingOption] = useState(SortingOption.MOST_RECENT); + const [filterOption, setFilterOption] = useState(''); const [showOnlyVerifiedReviews, setShowOnlyVerifiedReviews] = useState(false); const getColors = async (vote: VoteColorsRequest) => { @@ -102,6 +103,16 @@ const Review: FC = (props) => { sortedReviews = reviewData.slice(0); } + if (filterOption.length > 0) { + if (props.course) { + // filter course reviews by specific professor + sortedReviews = sortedReviews.filter((review) => review.professorID === filterOption); + } else if (props.professor) { + // filter professor reviews by specific course + sortedReviews = sortedReviews.filter((review) => review.courseID === filterOption); + } + } + switch (sortingOption) { case SortingOption.MOST_RECENT: sortedReviews.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); @@ -118,6 +129,20 @@ const Review: FC = (props) => { break; } + // calculate frequencies of professors or courses in list of reviews + let reviewFreq = new Map(); + if (props.course) { + reviewFreq = sortedReviews.reduce( + (acc, review) => acc.set(review.professorID, (acc.get(review.professorID) || 0) + 1), + reviewFreq, + ); + } else if (props.professor) { + reviewFreq = sortedReviews.reduce( + (acc, review) => acc.set(review.courseID, (acc.get(review.courseID) || 0) + 1), + reviewFreq, + ); + } + const openReviewForm = () => { dispatch(setFormStatus(true)); document.body.style.overflow = 'hidden'; @@ -146,6 +171,58 @@ const Review: FC = (props) => { value={sortingOption} onChange={(_, s) => setSortingOption(s.value as SortingOption)} /> + {props.course && ( + { + const name = `${props.course?.instructors[profID].name} (${reviewFreq.get(profID) || 0})`; + return { + text: name, + value: profID, + }; + }) + .sort((a, b) => a.text.localeCompare(b.text)), + ) + } + value={filterOption} + onChange={(_, s) => setFilterOption(s.value as string)} + /> + )} + {props.professor && ( + { + const name = + props.professor?.courses[courseID].department + + ' ' + + props.professor?.courses[courseID].courseNumber + + ` (${reviewFreq.get(courseID) || 0})`; + return { + text: name, + value: courseID, + }; + }) + .sort((a, b) => a.text.localeCompare(b.text)), + ) + } + value={filterOption} + onChange={(_, s) => setFilterOption(s.value as string)} + /> + )}