Skip to content

Commit f46c41b

Browse files
GiangNPhamemw8105DedsecKnightFarhanJamil0001jor-dango
authored
Rate my professor (#69)
* backend for RMP database * frontend to render RMP data * fix bug: data not changing between sections + N/A before RMP data fully loaded * feat: added grade distribution for Summer 2024 (#66) Co-authored-by: Mike Nguyen <34334226+DedsecKnight@users.noreply.github.com> * Update to actions/cache@v3 (#68) * feat: added grade distribution for Fall 2024 (#67) Co-authored-by: Mike Nguyen <34334226+DedsecKnight@users.noreply.github.com> * testing different layout of RMP info * changing the professor details container * changing the professor details container and style * fix build issues with removing suggested courses section * fix bug: name not matched * wokring on UI changes * RMP data design updated on SectionContent component * RMP data design updated on SectionContent component * added color to RMPScore and Difficulty * updated builtwithlove * updated tooltip styling * modified tooltip styling slightly * Removed extraneous code * fixed small build isues * fixed small build isues * fix bug: some of the courses may not be found so cannot render the instructor's data --------- Co-authored-by: Evan Wright <emw8105@gmail.com> Co-authored-by: Mike Nguyen <34334226+DedsecKnight@users.noreply.github.com> Co-authored-by: Farhan Jamil <32781195+FarhanJamil0001@users.noreply.github.com> Co-authored-by: FarhanJamil0001 <farrigalaxy321@gmail.com> Co-authored-by: jor-dango <jtan208295@gmail.com>
1 parent be5d28a commit f46c41b

File tree

13 files changed

+58548
-81
lines changed

13 files changed

+58548
-81
lines changed

client/public/rmp-logo.png

9.15 KB
Loading

client/src/components/Core.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ const TrendsText = styled.p`
6161
margin-bottom: 0;
6262
`;
6363

64+
const BuiltWithLove = styled.p`
65+
display: flex;
66+
align-items: center;
67+
justify-content: center;
68+
gap: 0.5rem;
69+
font-size: 1.2rem;
70+
margin: 0.5rem 0;
71+
font-weight: 550;
72+
`;
73+
6474
const NebulaLogo = styled.img`
6575
height: 1.375rem;
6676
filter: drop-shadow(0 0 4px rgb(0 0 0 / 0.6));
@@ -90,11 +100,10 @@ function Core({ children }: CoreProps) {
90100
<NebulaLogo src="/nebula-logo.svg" />
91101
<TrendsText>Compare everything in one place with <b>UTD Trends</b></TrendsText>
92102
</TrendsLink>
93-
<p>
103+
<BuiltWithLove>
94104
Built with <HeartTwoTone twoToneColor="#eb2f96" /> by{" "}
95-
<a href="https://www.acmutd.co" target={"blank"}>ACM Dev</a>. Raw data available{" "}
96-
<a href="https://github.com/acmutd/utd-grades/tree/master/raw_data" target={"blank"}>for download</a>.
97-
</p>
105+
<a href="https://www.acmutd.co" target={"blank"}>ACM Dev</a>
106+
</BuiltWithLove>
98107
<p>
99108
Designed by <a href="https://www.arimilli.io" target={"blank"}>Bharat Arimilli</a>. Thanks to{" "}
100109
<a href="https://garrettgu.com/" target={"blank"}>Garrett Gu</a>,{" "}
@@ -103,6 +112,9 @@ function Core({ children }: CoreProps) {
103112
<Popover content={donors}>
104113
<span style={{ textDecoration: "underline" }}>donors</span>.
105114
</Popover>
115+
116+
<a href="https://github.com/acmutd/utd-grades/tree/master/raw_data" target={"blank"}> Raw data available for download</a>
117+
106118
</p>
107119
</Footer>
108120
</Container>

client/src/components/SearchResults.tsx

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import type { RMPInstructor } from "@utd-grades/db";
12
import { Col, Row } from "antd";
23
import type { NextRouter } from "next/router";
3-
import React, { useEffect, useRef } from "react";
4+
import React, { useEffect, useRef, useState } from "react";
45
import { useQuery } from "react-query";
56
import { animateScroll as scroll } from "react-scroll";
67
import styled from "styled-components";
78
import type { SearchQuery } from "../types";
9+
import { normalizeName } from "../utils/index";
810
import { useDb } from "../utils/useDb";
911
import Search from "./Search";
1012
import SearchResultsContent from "./SearchResultsContent";
@@ -53,6 +55,7 @@ export default function Results({ search, sectionId, router }: ResultsProps) {
5355

5456
const { data: db } = useDb();
5557

58+
// this is to get all of the other sections of the same class (for the side bar)
5659
const {
5760
data: sections,
5861
status: sectionsStatus,
@@ -64,6 +67,7 @@ export default function Results({ search, sectionId, router }: ResultsProps) {
6467
{ enabled: !!db }
6568
);
6669

70+
// get the section data
6771
const {
6872
data: section,
6973
status: sectionStatus,
@@ -90,6 +94,58 @@ export default function Results({ search, sectionId, router }: ResultsProps) {
9094
{ enabled: !!section }
9195
);
9296

97+
// some professors have the same name so we need to get the whole list
98+
const normalName: string[] = normalizeName(
99+
`${section?.instructor1?.first} ${section?.instructor1?.last}`
100+
);
101+
102+
const { data: instructors } = useQuery<RMPInstructor[]>(
103+
["instructors", sectionId],
104+
async () => {
105+
const results = await Promise.all(normalName.map((name) => db!.getInstructorsByName(name)));
106+
return results.flat();
107+
},
108+
{ enabled: !!section }
109+
);
110+
111+
// from that list, we need to find the one that holds the session -> update the instructor and course rating
112+
const [instructor, setInstructor] = useState<RMPInstructor>();
113+
const [courseRating, setCourseRating] = useState<number | null>(null);
114+
115+
useEffect(() => {
116+
if (instructors && section) {
117+
// when there is only professor that matches the needed name -> set the instructor to that prof
118+
// this helps prevent that some of the courses may not be listed in the RMP data but we still want to the prof data
119+
120+
// however, if there're 2 profs with the same name and the course we're looking for is not listed in either instructor's RMP courses
121+
// then we don't know who to return
122+
// this will not be a problem when the new RMP data is updated
123+
if (instructors.length === 1) {
124+
setInstructor(instructors[0]);
125+
const rating = db!.getCourseRating(
126+
instructors[0]!.instructor_id,
127+
`${section.subject}${section.catalogNumber}`
128+
);
129+
setCourseRating(rating);
130+
} else {
131+
for (const ins of instructors) {
132+
const rating = db!.getCourseRating(
133+
ins.instructor_id,
134+
`${section.subject}${section.catalogNumber}`
135+
);
136+
if (rating) {
137+
setInstructor(ins);
138+
setCourseRating(rating);
139+
break;
140+
}
141+
}
142+
}
143+
} else {
144+
setInstructor(undefined);
145+
setCourseRating(null);
146+
}
147+
}, [instructors, section, db]);
148+
93149
useEffect(() => {
94150
// Automatically select section if there is only one choice
95151
if (sections && sections.length == 1) {
@@ -158,6 +214,8 @@ export default function Results({ search, sectionId, router }: ResultsProps) {
158214
<SearchResultsContent
159215
section={section!} // FIXME: need to actually do something if these are null
160216
relatedSections={relatedSections!}
217+
instructor={instructor!}
218+
courseRating={courseRating}
161219
loadingSection={sectionStatus === "loading"}
162220
handleRelatedSectionClick={handleRelatedSectionClick}
163221
error={sectionError}

client/src/components/SearchResultsContent.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Grades } from "@utd-grades/db";
1+
import type { Grades, RMPInstructor } from "@utd-grades/db";
22
import { Spin } from "antd";
33
import React from "react";
44
import styled from "styled-components";
@@ -27,6 +27,8 @@ const Spinner = styled(Spin)`
2727

2828
interface SearchResultsContentProps {
2929
section: Grades;
30+
instructor: RMPInstructor;
31+
courseRating: number | null;
3032
relatedSections: Grades[];
3133
loadingSection: boolean;
3234
handleRelatedSectionClick: (search: string, id: number) => void;
@@ -35,17 +37,21 @@ interface SearchResultsContentProps {
3537

3638
export default function SearchResultsContent({
3739
section,
38-
relatedSections,
40+
instructor,
41+
courseRating,
42+
// relatedSections,
3943
loadingSection,
40-
handleRelatedSectionClick,
44+
// handleRelatedSectionClick,
4145
error,
4246
}: SearchResultsContentProps) {
4347
if (section) {
4448
return (
4549
<SectionContent
4650
section={section}
47-
relatedSections={relatedSections}
48-
handleRelatedSectionClick={handleRelatedSectionClick}
51+
instructor={instructor}
52+
courseRating={courseRating}
53+
// relatedSections={relatedSections}
54+
// handleRelatedSectionClick={handleRelatedSectionClick}
4955
/>
5056
);
5157
} else if (loadingSection) {

0 commit comments

Comments
 (0)