From c46e4a51c98fc183ef01ee1a579c2c013951d551 Mon Sep 17 00:00:00 2001 From: Abhinav Chadaga Date: Mon, 19 Feb 2024 21:37:46 -0600 Subject: [PATCH] change from reducer pattern to state variables, remove chartData from state --- .../GradeDistribution.tsx | 81 ++++++------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx index b86699c3..b1915d37 100644 --- a/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx +++ b/src/views/components/injected/CourseCatalogInjectedPopup/GradeDistribution.tsx @@ -38,45 +38,22 @@ const GRADE_COLORS: Record = { F: colors.gradeDistribution.f, }; -interface State { - semester: string; - distributions: Record; - status: DataStatus; - chartData: { y: number; color: string | null }[]; -} - -type Action = - | { type: 'SET_SEMESTER'; semester: string } - | { type: 'SET_DISTRIBUTIONS'; distributions: Record } - | { type: 'SET_STATUS'; status: DataStatus } - | { type: 'SET_CHART_DATA'; chartData: { y: number; color: string | null }[] }; - -const initialState: State = { - semester: 'Aggregate', - distributions: {}, - status: DataStatus.LOADING, - chartData: [], -}; - -function reducer(state: State, action: Action): State { - switch (action.type) { - case 'SET_SEMESTER': - return { ...state, semester: action.semester }; - case 'SET_DISTRIBUTIONS': - return { ...state, distributions: action.distributions }; - case 'SET_STATUS': - return { ...state, status: action.status }; - case 'SET_CHART_DATA': - return { ...state, chartData: action.chartData }; - default: - return state; - } -} - const GradeDistribution: React.FC = ({ course }) => { - const [state, dispatch] = React.useReducer(reducer, initialState); + const [semester, setSemester] = React.useState('Aggregate'); + const [distributions, setDistributions] = React.useState>({}); + const [status, setStatus] = React.useState(DataStatus.LOADING); const ref = React.useRef(null); + const chartData = React.useMemo(() => { + if (status === DataStatus.FOUND && distributions[semester]) { + return Object.entries(distributions[semester]).map(([grade, count]) => ({ + y: count, + color: GRADE_COLORS[grade as LetterGrade], + })); + } + return []; + }, [distributions, semester, status]); + React.useEffect(() => { const fetchInitialData = async () => { try { @@ -87,14 +64,14 @@ const GradeDistribution: React.FC = ({ course }) => { semesters.forEach((semester, i) => { initialDistributions[`${semester.season} ${semester.year}`] = semesterDistributions[i]; }); - dispatch({ type: 'SET_DISTRIBUTIONS', distributions: initialDistributions }); - dispatch({ type: 'SET_STATUS', status: DataStatus.FOUND }); + setDistributions(initialDistributions); + setStatus(DataStatus.FOUND); } catch (e) { console.error(e); if (e instanceof NoDataError) { - dispatch({ type: 'SET_STATUS', status: DataStatus.NOT_FOUND }); + setStatus(DataStatus.NOT_FOUND); } else { - dispatch({ type: 'SET_STATUS', status: DataStatus.ERROR }); + setStatus(DataStatus.ERROR); } } }; @@ -102,18 +79,8 @@ const GradeDistribution: React.FC = ({ course }) => { fetchInitialData(); }, [course]); - React.useEffect(() => { - if (state.status === DataStatus.FOUND && state.distributions[state.semester]) { - const chartData = Object.entries(state.distributions[state.semester]).map(([grade, count]) => ({ - y: count, - color: GRADE_COLORS[grade as LetterGrade], - })); - dispatch({ type: 'SET_CHART_DATA', chartData }); - } - }, [state.distributions, state.semester, state.status]); - const handleSelectSemester = (event: React.ChangeEvent) => { - dispatch({ type: 'SET_SEMESTER', semester: event.target.value }); + setSemester(event.target.value); }; const chartOptions: Highcharts.Options = { @@ -153,17 +120,17 @@ const GradeDistribution: React.FC = ({ course }) => { { type: 'column', name: 'Grades', - data: state.chartData, + data: chartData, }, ], }; return (
- {state.status === DataStatus.LOADING && } - {state.status === DataStatus.NOT_FOUND && No grade distribution data found} - {state.status === DataStatus.ERROR && Error fetching grade distribution data} - {state.status === DataStatus.FOUND && ( + {status === DataStatus.LOADING && } + {status === DataStatus.NOT_FOUND && No grade distribution data found} + {status === DataStatus.ERROR && Error fetching grade distribution data} + {status === DataStatus.FOUND && ( <>
Grade distribution for {`${course.department} ${course.number}`} @@ -171,7 +138,7 @@ const GradeDistribution: React.FC = ({ course }) => { className='border border rounded-[4px] border-solid px-[12px] py-[8px]' onChange={handleSelectSemester} > - {Object.keys(state.distributions) + {Object.keys(distributions) .sort((k1, k2) => { if (k1 === 'Aggregate') { return -1;