diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx deleted file mode 100644 index 7fac997..0000000 --- a/src/components/Loading.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Rings } from 'react-loader-spinner'; - -export const Loading = () => { - return ( -
- -
- ); -}; diff --git a/src/components/MiniGrades.tsx b/src/components/MiniGrades.tsx index 0cfeab1..53faa63 100644 --- a/src/components/MiniGrades.tsx +++ b/src/components/MiniGrades.tsx @@ -1,9 +1,29 @@ import React from 'react'; import Chart from 'react-apexcharts'; +import { Rings } from 'react-loader-spinner'; import { miniGradeChartOptions } from '~utils/styling'; -export const MiniGrades = ({ series }: { series: ApexAxisChartSeries }) => { +export const MiniGrades = ({ + series, + loading, +}: { + series: ApexAxisChartSeries; + loading: boolean; +}) => { + if (loading) { + return ( + + ); + } return (

{professorData.name}

- + {!professorData.loading && ( + + )}
-
- +
+
diff --git a/src/components/MiniScore.tsx b/src/components/MiniScore.tsx index ad167d8..16f110a 100644 --- a/src/components/MiniScore.tsx +++ b/src/components/MiniScore.tsx @@ -26,10 +26,13 @@ export const MiniScore = ({ {score !== undefined ? (

- {name === 'WTA' ? Math.round(score) + '%' : score.toFixed(1)} + {score}

) : (

- professor === null - ? null - : professor.reduce( - (accumulator, academicSession) => { - return accumulator.map( - (value, index) => - value + academicSession.grade_distribution[index] ?? 0, - ); - }, - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - ), - ); - - //divide by total - gradeData = gradeData.map((professor) => { - if (professor === null) { - totalGrades.push(0); - return null; - } - const total = professor.reduce( - (accumulator, grade) => grade + accumulator, - 0, - ); - totalGrades.push(total); - return professor.map((grade) => (grade / total) * 100); - }); + let nebulaProfessor, nebulaGrades, rmp; - return [totalGrades, gradeData]; -} - -export async function buildProfessorProfiles(payload: ShowCourseTabPayload) { - let { professors } = payload; - professors = professors.map((prof) => { - const parts = prof.split(' '); - return { - profFirst: parts[0], - profLast: parts[parts.length - 1], - }; - }); - - let nebulaProfessors, nebulaGrades, rmps; - - const nebulaProfessorsPromises = Promise.all( - professors.map(fetchNebulaProfessor), - ).then((result) => (nebulaProfessors = result)); + const nebulaProfessorsPromise = fetchNebulaProfessor(professorSplit).then( + (result) => (nebulaProfessor = result), + ); - const nebulaGradesPromises = Promise.all( - professors.map(fetchNebulaGrades), - ).then((result) => (nebulaGrades = result)); + const nebulaGradesPromise = fetchNebulaGrades(professorSplit).then( + (result) => (nebulaGrades = result), + ); - const rmpsPromises = Promise.all( - professors.map((prof) => - requestProfessorFromRmp({ - professorName: prof.profFirst + ' ' + prof.profLast, - schoolId: SCHOOL_ID, - }), - ), - ).then((result) => (rmps = result)); + const rmpsPromise = requestProfessorFromRmp({ + professorName: professorSplit.profFirst + ' ' + professorSplit.profLast, + schoolId: SCHOOL_ID, + }).then((result) => (rmp = result)); await Promise.all([ - nebulaProfessorsPromises, - nebulaGradesPromises, - rmpsPromises, + nebulaProfessorsPromise, + nebulaGradesPromise, + rmpsPromise, ]); - let totalGrades = []; - [totalGrades, nebulaGrades] = combineAndNormalizeGrades(nebulaGrades); + let totalGrades = 0; + if (nebulaGrades !== null) { + //combine academic sections + nebulaGrades = nebulaGrades.reduce( + (accumulator, academicSession) => { + return accumulator.map( + (value, index) => + value + academicSession.grade_distribution[index] ?? 0, + ); + }, + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ); - const professorProfiles: ProfessorProfileInterface[] = []; - for (let i = 0; i < professors.length; i++) { - professorProfiles.push({ - name: professors[i].profFirst + ' ' + professors[i].profLast, - profilePicUrl: nebulaProfessors[i]?.image_uri, - rmpId: rmps[i]?.legacyId, - rmpScore: rmps[i]?.avgRating - ? rmps[i]?.avgRating === 0 - ? undefined - : rmps[i]?.avgRating - : undefined, - diffScore: rmps[i]?.avgDifficulty - ? rmps[i].avgDifficulty === 0 - ? undefined - : rmps[i]?.avgDifficulty - : undefined, - wtaScore: rmps[i]?.wouldTakeAgainPercent - ? rmps[i]?.wouldTakeAgainPercent === -1 - ? undefined - : rmps[i]?.wouldTakeAgainPercent - : undefined, - rmpTags: rmps[i]?.teacherRatingTags - .sort((a, b) => a.tagCount - b.tagCount) - .map((tag) => tag.tagName), - gradeDistribution: [ - { - name: professors[i].profFirst + ' ' + professors[i].profLast, - data: nebulaGrades[i] ?? [], - }, - ], - totalGrades: totalGrades[i], - ratingsDistribution: rmps[i] - ? Object.values(rmps[i].ratingsDistribution).reverse().slice(1) - : [], - totalRatings: rmps[i]?.ratingsDistribution?.total ?? 0, - }); + //divide by total + totalGrades = nebulaGrades.reduce( + (accumulator, grade) => grade + accumulator, + 0, + ); + nebulaGrades = nebulaGrades.map((grade) => (grade / totalGrades) * 100); } - return professorProfiles; + + return { + name: professor, + profilePicUrl: nebulaProfessor?.image_uri, + rmpId: rmp?.legacyId, + rmpScore: rmp?.avgRating !== 0 ? rmp?.avgRating : undefined, + diffScore: rmp?.avgDifficulty !== 0 ? rmp?.avgDifficulty : undefined, + wtaScore: + rmp?.wouldTakeAgainPercent !== -1 + ? rmp?.wouldTakeAgainPercent + : undefined, + rmpTags: rmp?.teacherRatingTags + .sort((a, b) => a.tagCount - b.tagCount) + .map((tag) => tag.tagName), + gradeDistribution: [ + { + name: professor, + data: nebulaGrades ?? [], + }, + ], + totalGrades: totalGrades, + ratingsDistribution: rmp + ? Object.values(rmp.ratingsDistribution).reverse().slice(1) + : [], + totalRatings: rmp?.ratingsDistribution?.total ?? 0, + loading: false, + }; } diff --git a/src/pages/CoursePage.tsx b/src/pages/CoursePage.tsx index f2d0133..eac9321 100644 --- a/src/pages/CoursePage.tsx +++ b/src/pages/CoursePage.tsx @@ -4,10 +4,9 @@ import { useLocation } from 'react-router-dom'; import type { ShowCourseTabPayload } from '~background'; import { Landing } from '~components/Landing'; -import { Loading } from '~components/Loading'; import { MiniProfessor } from '~components/MiniProfessor'; import { - buildProfessorProfiles, + buildProfessorProfile, ProfessorProfileInterface, } from '~data/builder'; @@ -22,36 +21,53 @@ async function getCourseData() { export const CoursePage = () => { // TODO: CHANGE INTERFACE const { state }: { state: ProfessorProfileInterface[] } = useLocation(); - const [loading, setLoading] = useState(true); - const [profiles, setProfiles] = useState(null); + const [onCoursebook, setOnCoursebook] = useState(false); + const [profiles, setProfiles] = useState([]); useEffect(() => { if (!state) { - setLoading(true); + setOnCoursebook(true); getCourseData().then((payload) => { - buildProfessorProfiles(payload) - .then((profiles) => { - setProfiles(profiles); - }) - .finally(() => setLoading(false)); + if (payload === null) { + setOnCoursebook(false); + } else { + const newProfiles = []; + for (let i = 0; i < payload.professors.length; i++) { + newProfiles.push({ + name: payload.professors[i], + loading: true, + }); + } + setProfiles(newProfiles); + + for (let i = 0; i < payload.professors.length; i++) { + buildProfessorProfile(payload.header, payload.professors[i]).then( + (profile) => { + setProfiles((old) => { + const newProfiles = [...old]; + newProfiles[i] = profile; + return newProfiles; + }); + }, + ); + } + } }); } else { setProfiles(state); - setLoading(false); + setOnCoursebook(true); } }, []); return (
- {!loading && - profiles && + {onCoursebook && profiles.map((item, index) => (
))} - {loading && } - {!loading && !profiles && } + {!onCoursebook && }
); };