From fac79a38d6fdeaba0fc0cf611400a33330a270b2 Mon Sep 17 00:00:00 2001 From: Andrew Qian Date: Thu, 28 Nov 2024 11:22:57 -0500 Subject: [PATCH] added bars for difficulty + workload ratings --- client/index.d.ts | 2 + client/src/modules/Admin/Components/Admin.tsx | 2 +- .../src/modules/Course/Components/Course.tsx | 2 +- .../src/modules/Course/Components/Gauge.tsx | 73 -------- .../src/modules/Course/Components/Gauges.tsx | 87 +++++++--- .../modules/Course/Styles/Course.module.css | 2 +- .../modules/Course/Styles/Gauge.module.css | 54 ------ .../modules/Course/Styles/Gauges.module.css | 30 +++- .../Results/Components/PreviewCard.jsx | 157 ++++++------------ client/tsconfig.json | 2 +- 10 files changed, 149 insertions(+), 262 deletions(-) create mode 100644 client/index.d.ts delete mode 100644 client/src/modules/Course/Components/Gauge.tsx delete mode 100644 client/src/modules/Course/Styles/Gauge.module.css diff --git a/client/index.d.ts b/client/index.d.ts new file mode 100644 index 00000000..5073e141 --- /dev/null +++ b/client/index.d.ts @@ -0,0 +1,2 @@ +declare module '*.svg'; +declare module '*.png'; diff --git a/client/src/modules/Admin/Components/Admin.tsx b/client/src/modules/Admin/Components/Admin.tsx index 1f7db656..907d8baf 100644 --- a/client/src/modules/Admin/Components/Admin.tsx +++ b/client/src/modules/Admin/Components/Admin.tsx @@ -7,7 +7,7 @@ import { Review } from 'common'; import { useAuthMandatoryLogin } from '../../../auth/auth_utils'; -import UpdateReview from './AdminReview'; +import UpdateReview from './AdminReview.js'; import Stats from './Stats'; import ManageAdminModal from './ManageAdminModal'; diff --git a/client/src/modules/Course/Components/Course.tsx b/client/src/modules/Course/Components/Course.tsx index 729244a2..251d5bb3 100644 --- a/client/src/modules/Course/Components/Course.tsx +++ b/client/src/modules/Course/Components/Course.tsx @@ -36,7 +36,7 @@ export const Course = () => { const { number, subject, input } = useParams(); const [selectedClass, setSelectedClass] = useState(); - const [courseReviews, setCourseReviews] = useState(); + const [courseReviews, setCourseReviews] = useState([]); const [pageStatus, setPageStatus] = useState(PageStatus.Loading); const [scrolled, setScrolled] = useState(false); diff --git a/client/src/modules/Course/Components/Gauge.tsx b/client/src/modules/Course/Components/Gauge.tsx deleted file mode 100644 index 4a68a873..00000000 --- a/client/src/modules/Course/Components/Gauge.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { CircularProgressbar, buildStyles } from 'react-circular-progressbar'; -import 'react-circular-progressbar/dist/styles.css'; -import styles from '../Styles/Gauge.module.css'; - -type GaugeProps = { - rating: number | undefined; - label: string; - isOverall: boolean; -}; - -type GaugeState = { - color: string; - percentage: number; - rating: number | string; -}; - -export default function Gauge({ rating, label, isOverall }: GaugeProps) { - const [gaugeState, setGaugeState] = useState({ - color: '#000', - percentage: 0.0, - rating: 0.0 - }); - - useEffect(() => { - if (rating && !isNaN(rating)) { - let percentage = 20 * rating; // rating is 1-5 - let color; - - let red = `hsl(4, 100%, 71%)`; - let yellow = `hsl(47, 94%, 58%)`; - let green = `hsl(101, 64%, 43%)`; - - let ratingRounded = parseFloat(rating.toFixed(1)); - - if (0 <= ratingRounded && ratingRounded < 3) { - color = isOverall ? red : green; - } else if (3.0 <= ratingRounded && ratingRounded < 4) { - color = yellow; - } else { - color = isOverall ? green : red; - } - - setGaugeState({ - percentage: percentage, - color: color, - rating: rating.toFixed(1) - }); - } else { - setGaugeState({ color: '#000', rating: '-', percentage: 0.0 }); - } - }, [setGaugeState, rating, isOverall]); - - return ( -
-
-
{gaugeState.rating}
-
{label}
-
-
- -
-
- ); -} diff --git a/client/src/modules/Course/Components/Gauges.tsx b/client/src/modules/Course/Components/Gauges.tsx index 3f7c7e61..d8fb9d97 100644 --- a/client/src/modules/Course/Components/Gauges.tsx +++ b/client/src/modules/Course/Components/Gauges.tsx @@ -20,10 +20,10 @@ type GaugesProps = { } const Gauges = ({overall, difficulty, workload}: GaugesProps) => { - const [stars, setStars] = useState([]) - const [overallEmote, setOverallEmote] = useState(); - const [difficultyEmote, setDifficultyEmote] = useState(); - const [workloadEmote, setWorkloadEmote] = useState(); + const [stars, setStars] = useState([]) + const [overallEmote, setOverallEmote] = useState(); + const [difficultyEmote, setDifficultyEmote] = useState(); + const [workloadEmote, setWorkloadEmote] = useState(); useEffect(() => { if (overall) { @@ -61,19 +61,54 @@ const Gauges = ({overall, difficulty, workload}: GaugesProps) => { } } else { setStars([Gray, Gray, Gray, Gray, Gray]) + setOverallEmote(undefined) } }, [overall]) + useEffect(() => { + if (difficulty) { + if (0 <= difficulty && difficulty < 3) { + setDifficultyEmote(SadFace) + } else if (3 <= difficulty && difficulty < 3.8) { + setDifficultyEmote(MehFace) + } else { + setDifficultyEmote(HappyFace) + } + } else { + setDifficultyEmote(undefined) + } + }, [difficulty]) + + useEffect(() => { + if (workload) { + if (0 <= workload && workload < 3) { + setWorkloadEmote(SadFace) + } else if (3 <= workload && workload < 3.8) { + setWorkloadEmote(MehFace) + } else { + setWorkloadEmote(HappyFace) + } + } else { + setWorkloadEmote(undefined) + } + }, [workload]) + return (
- {overall ? overall.toPrecision(2) : "0.0"} - + {overall ? overall.toPrecision(2) : "--"} + overall-rating-emote
{stars.map((star) => { - return + return rating-star })}
@@ -81,21 +116,35 @@ const Gauges = ({overall, difficulty, workload}: GaugesProps) => {
-
-
Difficulty
-
- Bars +
+
Difficulty
+
+
+
+
+
+
-
{difficulty ? difficulty.toPrecision(2) : "0.0"}
- +
{difficulty ? difficulty.toPrecision(2) : "-"}
+ difficulty-rating-emote
-
-
Workload
-
- Bars +
+
Workload
+
+ + + + +
-
{workload ? workload.toPrecision(2) : "0.0"}
- +
{workload ? workload.toPrecision(2) : "-"}
+ workload-rating-emote
diff --git a/client/src/modules/Course/Styles/Course.module.css b/client/src/modules/Course/Styles/Course.module.css index 0ddc920c..2dba34d5 100644 --- a/client/src/modules/Course/Styles/Course.module.css +++ b/client/src/modules/Course/Styles/Course.module.css @@ -100,7 +100,7 @@ } .reviewscontainer { - padding: 5%; + padding: 24px 0px; } .classinfo { diff --git a/client/src/modules/Course/Styles/Gauge.module.css b/client/src/modules/Course/Styles/Gauge.module.css deleted file mode 100644 index 5a7b84d3..00000000 --- a/client/src/modules/Course/Styles/Gauge.module.css +++ /dev/null @@ -1,54 +0,0 @@ -@import '../../../index.css'; - -.container { - display: flex; - flex-direction: row; - max-width: 160px; - height: 80px; - align-items: center; -} - -.textcolumn { - font-weight: var(--regular-weight); - height: 100%; - display: flex; - flex-flow: column; - justify-content: center; - max-width: 70px; - - text-align: center; -} - -.rating { - font-size: 2rem; -} - -.label { - font-size: var(--font-small-size); -} - -.circle { - height: 60px; - width: 70px; - padding: 0 5px; - align-content: center; -} - -.gaugeCircle { - height: 100%; -} - -@media only screen and (max-width: 510px) { - .rating { - font-size: 1.5rem; - } - - .label { - font-size: 10px; - } - - .circle { - height: 80px; - width: 55px; - } -} diff --git a/client/src/modules/Course/Styles/Gauges.module.css b/client/src/modules/Course/Styles/Gauges.module.css index 4ef2b419..e0b69d58 100644 --- a/client/src/modules/Course/Styles/Gauges.module.css +++ b/client/src/modules/Course/Styles/Gauges.module.css @@ -43,13 +43,39 @@ flex-flow: column nowrap; justify-content: center; height: 82px; - gap: 24px; + gap: 20px; } -.bars { +.horizontal { display: flex; flex-flow: row nowrap; align-items: center; justify-content: space-between; gap: 14px; +} + +.category { + min-width: 60px; +} + +.bars { + display: flex; + flex-flow: row nowrap; + align-items: center; + justify-content: center; + gap: 5px; +} + +.bar { + height: 8px; + width: 40px; + border-radius: 4px; + background-color: var(--clr-gray-200); + + display: flex; +} + +.ratingNum { + font-size: 20px; + font-weight: 590; } \ No newline at end of file diff --git a/client/src/modules/Results/Components/PreviewCard.jsx b/client/src/modules/Results/Components/PreviewCard.jsx index 006e5433..ddc5fc1b 100644 --- a/client/src/modules/Results/Components/PreviewCard.jsx +++ b/client/src/modules/Results/Components/PreviewCard.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import axios from 'axios'; import { lastOfferedSems } from 'common/CourseCard'; -import Gauge from '../../Course/Components/Gauge'; +import Gauges from '../../Course/Components/Gauges'; import ReviewCard from '../../Course/Components/ReviewCard'; import styles from '../Styles/CoursePreview.module.css'; @@ -33,7 +33,6 @@ export default class PreviewCard extends Component { topReviewLikes: 0 }; - this.updateColors = this.updateColors.bind(this); this.updateTopReview = this.updateTopReview.bind(this); this.updateGauges = this.updateGauges.bind(this); } @@ -63,8 +62,8 @@ export default class PreviewCard extends Component { ? this.props.course.classWorkload : '-' }, - () => this.updateColors() ); + this.updateTopReview(); } // Updates the top review to be the one with the most likes @@ -95,52 +94,6 @@ export default class PreviewCard extends Component { }); } - // Updates the colors of the metrics - updateColors() { - if (3.0 <= this.state.rating && this.state.rating < 4.0) { - this.setState({ - ratingColor: '#f9cc30' - }); - } else if (4.0 <= this.state.rating && this.state.rating <= 5.0) { - this.setState({ - ratingColor: '#53B277' - }); - } else { - this.setState({ - ratingColor: '#E64458' - }); - } - - if (0 < this.state.diff && this.state.diff < 3.0) { - this.setState({ - diffColor: '#53B277' - }); - } else if (3.0 <= this.state.diff && this.state.diff < 4.0) { - this.setState({ - diffColor: '#f9cc30' - }); - } else { - this.setState({ - diffColor: '#E64458' - }); - } - - if (0 < this.state.workload && this.state.workload < 3.0) { - this.setState({ - workloadColor: '#53B277' - }); - } else if (3.0 <= this.state.workload && this.state.workload < 4.0) { - this.setState({ - workloadColor: '#f9cc30' - }); - } else { - this.setState({ - workloadColor: '#E64458' - }); - } - this.updateTopReview(); - } - render() { let theClass = this.props.course; const offered = lastOfferedSems(theClass); @@ -165,71 +118,55 @@ export default class PreviewCard extends Component {
- {!this.props.transformGauges && ( -
- - - -
- )} - + + {this.state.numReviews !== 0 && (
Top Review
)} - {!this.props.transformGauges && ( -
- {/*If class has review show top review and link*/} - {this.state.numReviews !== 0 && ( - - )} - - {this.state.numReviews !== 0 && this.state.numReviews > 1 && ( - - See {this.state.numReviews} more review - {this.state.numReviews > 1 ? 's' : ''} - - )} - - {/*If class has 0 reviews text and button*/} - {this.state.numReviews === 0 && ( -
No reviews yet
- )} - {(this.state.numReviews === 0 || this.state.numReviews === 1) && ( - - Leave a Review - - )} -
- )} +
+ {/*If class has review show top review and link*/} + {this.state.numReviews !== 0 && ( + + )} + + {this.state.numReviews !== 0 && this.state.numReviews > 1 && ( + + See {this.state.numReviews} more review + {this.state.numReviews > 1 ? 's' : ''} + + )} + + {/*If class has 0 reviews text and button*/} + {this.state.numReviews === 0 && ( +
No reviews yet
+ )} + {(this.state.numReviews === 0 || this.state.numReviews === 1) && ( + + Leave a Review + + )} +
); } diff --git a/client/tsconfig.json b/client/tsconfig.json index aecc29e5..70c15a34 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -16,5 +16,5 @@ "jsx": "react", "noFallthroughCasesInSwitch": true }, - "include": ["src"] + "exclude": ["node_modules"] }