diff --git a/api/src/controllers/professors.ts b/api/src/controllers/professors.ts index 1d1b871c..e5d334f2 100644 --- a/api/src/controllers/professors.ts +++ b/api/src/controllers/professors.ts @@ -49,8 +49,12 @@ router.post('/api/batch', (req: Request<{}, {}, { professors: string[] }>, res) router.get('/api/grades/:name', function (req, res, next) { let r = fetch(process.env.PUBLIC_API_URL + 'grades/raw?instructor=' + encodeURIComponent(req.params.name)); - r.then((response) => response.json()) - .then((data) => res.send(data)) + let status = 200; + + r.then((response) => { + status = response.status; + return response.json(); + }).then((data) => res.status(status).send(data)) }); export default router; \ No newline at end of file diff --git a/site/src/component/GradeDist/Chart.tsx b/site/src/component/GradeDist/Chart.tsx index 2d3bd9e9..2bbe6f87 100644 --- a/site/src/component/GradeDist/Chart.tsx +++ b/site/src/component/GradeDist/Chart.tsx @@ -118,7 +118,7 @@ export default class Chart extends React.Component { */ styleTooltip = (event: BarTooltipDatum) => { return ( -
+
{event.data.label}: {eval('event.data.' + event.data.label)} diff --git a/site/src/component/GradeDist/GradeDist.tsx b/site/src/component/GradeDist/GradeDist.tsx index b87fdd03..b500355c 100644 --- a/site/src/component/GradeDist/GradeDist.tsx +++ b/site/src/component/GradeDist/GradeDist.tsx @@ -54,19 +54,15 @@ const GradeDist: FC = (props) => { }) .then(res => { setGradeDistData(res.data); + }).catch(error => { + setGradeDistData([]); + console.error(error.response); }); } - // initial request to get grade dist data + // reset any data from a previous course or professor, get new data for course or professor useEffect(() => { - if (gradeDistData == null) { - fetchGradeDistData(); - } - }) - - // get new data if choose a new course or professor - useEffect(() => { - setGradeDistData([]); + setGradeDistData(null!); fetchGradeDistData(); }, [props.course?.id, props.professor?.ucinetid]) @@ -239,10 +235,13 @@ const GradeDist: FC = (props) => {
); - } else { + } else if (gradeDistData == null) { // null if still fetching, don't display anything while it still loads + return null; + } else { // gradeDistData is empty, did not receive any data from API call or received an error, display an error message return ( -
-
+ <> + Error: could not retrieve grade distribution data. + ); } } diff --git a/site/src/component/GradeDist/Pie.tsx b/site/src/component/GradeDist/Pie.tsx index 969311c9..3f60da4d 100644 --- a/site/src/component/GradeDist/Pie.tsx +++ b/site/src/component/GradeDist/Pie.tsx @@ -7,7 +7,7 @@ const gradeScale = ['A', 'A-', 'B+', 'B', 'B-', 'C+', 'C', 'C-', 'D+', 'D', 'D-' const gpaScale = [4.0, 3.7, 3.3, 3.0, 2.7, 2.3, 2.0, 1.7, 1.3, 1.0, 0, 7] interface Slice { - id: 'A' | 'B' | 'C' | 'D' | 'F'; + id: 'A' | 'B' | 'C' | 'D' | 'F' | 'P' | 'NP'; value: number; label: string; color: string; @@ -25,6 +25,7 @@ export default class Pie extends React.Component { totalPNP = 0; averageGPA = ''; averageGrade = ''; + averagePNP = ''; getClassData = () => { let gradeACount = 0, gradeBCount = 0, gradeCCount = 0, gradeDCount = 0, @@ -34,6 +35,7 @@ export default class Pie extends React.Component { this.totalPNP = 0; this.averageGPA = ''; this.averageGrade = ''; + this.averagePNP = ''; var sum = 0 @@ -51,12 +53,41 @@ export default class Pie extends React.Component { this.total += data.gradeACount + data.gradeBCount + data.gradeCCount + data.gradeDCount + data.gradeFCount + data.gradePCount + data.gradeNPCount; this.totalPNP += data.gradePCount + data.gradeNPCount; + + if(data.gradePCount >= data.gradeNPCount) + { + this.averagePNP = 'P'; + } + else + { + this.averagePNP = 'NP'; + } } }); this.averageGPA = (sum / (this.total - this.totalPNP)).toFixed(1) this.gpaToGradeConverter(this.averageGPA); + if(this.totalPNP == this.total) + { + let data: Slice[] = [ + { + 'id': 'P', + 'label': 'P', + 'value': gradePCount, + 'color': '#4AB486' + }, + { + 'id': 'NP', + 'label': 'NP', + 'value': gradeNPCount, + 'color': '#E36436' + } + + ]; + return data; + } + let data: Slice[] = [ { 'id': 'A', @@ -87,19 +118,20 @@ export default class Pie extends React.Component { 'label': 'F', 'value': gradeFCount, 'color': '#E8966D' + }, + { + 'id': 'P', + 'label': 'P', + 'value': gradePCount, + 'color': '#4AB486' + }, + { + 'id': 'NP', + 'label': 'NP', + 'value': gradeNPCount, + 'color': '#E36436' } - // { - // 'id': 'P', - // 'label': 'P', - // 'value': gradePCount, - // 'color': '#4AB486' - // }, - // { - // 'id': 'NP', - // 'label': 'NP', - // 'value': gradeNPCount, - // 'color': '#E36436' - // }, + ]; return data; } @@ -124,26 +156,27 @@ export default class Pie extends React.Component { enableArcLinkLabels={false} innerRadius={0.8} padAngle={2} - colors={['#60A3D1', '#81C284', '#F5D77F', '#ECAD6D', '#E8966D']} + colors={['#60A3D1', '#81C284', '#F5D77F', '#ECAD6D', '#E8966D', '#4AB486', '#E36436']} cornerRadius={3} borderWidth={1} borderColor={{ from: 'color', modifiers: [['darker', 0.2]] }} tooltip={(props: PieTooltipProps) => (
- {props.datum.id}: {(props.datum.value / (this.total - this.totalPNP) * 100).toFixed(2)}% + {props.datum.id}: {(props.datum.value / (this.total) * 100).toFixed(2)}%
)} />
-

Average Grade: {this.averageGrade} ({this.averageGPA})

+ {this.totalPNP == this.total ?

Average Grade: {this.averagePNP}

: null} + {this.totalPNP != this.total ?

Average Grade: {this.averageGrade} ({this.averageGPA})

: null}

Total Enrolled: {this.total}

{this.totalPNP > 0 ? {this.totalPNP} enrolled as P/NP : null}
diff --git a/site/src/component/SideBar/Sidebar.scss b/site/src/component/SideBar/Sidebar.scss index 1af5f358..890ef790 100644 --- a/site/src/component/SideBar/Sidebar.scss +++ b/site/src/component/SideBar/Sidebar.scss @@ -61,7 +61,7 @@ } .sidebar-login { - margin-bottom: 5vh; + margin-bottom: 5vh; .sidebar-login-icon { margin-right: 1vw; @@ -115,6 +115,11 @@ flex-direction: column; justify-content: space-between; align-items: center; + + .sidebar-login { + margin-top: -20vh; + margin-bottom: 35vh; + } } .sidebar.mini { display: none;