feat: enable TS strict mode (#168)
* feat: enable TS strict mode * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: colors bug with default * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: text type errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors - add definite assignment assertion * fix: strict TS errors - add definite assignment assertion * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix(ESLint): error on no-explicit-any * fix: type annotations for any types * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors (and remove packages) * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * fix: strict TS errors * feat: enable React.StrictMode * fix: strict TS errors (done!) * fix: build error * fix: replace no-explicit-any assertions * refactor: cleanup * refactor: more cleanup * style: prettier --------- Co-authored-by: Lukas Zenick <lukas@utexas.edu> Co-authored-by: Razboy20 <razboy20@gmail.com>
This commit is contained in:
@@ -21,7 +21,7 @@ type Props = {
|
||||
* This component is responsible for loading the next page of courses when the user scrolls to the bottom of the page.
|
||||
* @returns
|
||||
*/
|
||||
export default function AutoLoad({ addRows }: Props): JSX.Element {
|
||||
export default function AutoLoad({ addRows }: Props): JSX.Element | null {
|
||||
const [container, setContainer] = useState<HTMLDivElement | null>(null);
|
||||
const [status, setStatus] = useState<AutoLoadStatusType>(AutoLoadStatus.IDLE);
|
||||
|
||||
|
||||
@@ -53,40 +53,41 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J
|
||||
const [status, setStatus] = React.useState<DataStatusType>(DataStatus.LOADING);
|
||||
const ref = React.useRef<HighchartsReact.RefObject>(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 Array(12).fill(0);
|
||||
}, [distributions, semester, status]);
|
||||
// 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 Array(12).fill(0);
|
||||
// }, [distributions, semester, status]);
|
||||
// const chartData: unknown[] = [];
|
||||
|
||||
React.useEffect(() => {
|
||||
const fetchInitialData = async () => {
|
||||
try {
|
||||
const [aggregateDist, semesters] = await queryAggregateDistribution(course);
|
||||
const initialDistributions: Record<string, Distribution> = { Aggregate: aggregateDist };
|
||||
const semesterPromises = semesters.map(semester => querySemesterDistribution(course, semester));
|
||||
const semesterDistributions = await Promise.all(semesterPromises);
|
||||
semesters.forEach((semester, i) => {
|
||||
initialDistributions[`${semester.season} ${semester.year}`] = semesterDistributions[i];
|
||||
});
|
||||
setDistributions(initialDistributions);
|
||||
setStatus(DataStatus.FOUND);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if (e instanceof NoDataError) {
|
||||
setStatus(DataStatus.NOT_FOUND);
|
||||
} else {
|
||||
setStatus(DataStatus.ERROR);
|
||||
}
|
||||
}
|
||||
};
|
||||
// React.useEffect(() => {
|
||||
// const fetchInitialData = async () => {
|
||||
// try {
|
||||
// const [aggregateDist, semesters] = await queryAggregateDistribution(course);
|
||||
// const initialDistributions: Record<string, Distribution> = { Aggregate: aggregateDist };
|
||||
// const semesterPromises = semesters.map(semester => querySemesterDistribution(course, semester));
|
||||
// const semesterDistributions = await Promise.all(semesterPromises);
|
||||
// semesters.forEach((semester, i) => {
|
||||
// initialDistributions[`${semester.season} ${semester.year}`] = semesterDistributions[i];
|
||||
// });
|
||||
// setDistributions(initialDistributions);
|
||||
// setStatus(DataStatus.FOUND);
|
||||
// } catch (e) {
|
||||
// console.error(e);
|
||||
// if (e instanceof NoDataError) {
|
||||
// setStatus(DataStatus.NOT_FOUND);
|
||||
// } else {
|
||||
// setStatus(DataStatus.ERROR);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
fetchInitialData();
|
||||
}, [course]);
|
||||
// fetchInitialData();
|
||||
// }, [course]);
|
||||
|
||||
const handleSelectSemester = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
setSemester(event.target.value);
|
||||
@@ -129,7 +130,7 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J
|
||||
{
|
||||
type: 'column',
|
||||
name: 'Grades',
|
||||
data: chartData,
|
||||
// data: chartData,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -156,7 +157,7 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J
|
||||
<>
|
||||
<div className='w-full flex items-center justify-center gap-[12px]'>
|
||||
<Text variant='p'>Grade distribution for {`${course.department} ${course.number}`}</Text>
|
||||
<select
|
||||
{/* <select
|
||||
className='border border rounded-[4px] border-solid px-[12px] py-[8px]'
|
||||
onChange={handleSelectSemester}
|
||||
>
|
||||
@@ -180,7 +181,7 @@ export default function GradeDistribution({ course }: GradeDistributionProps): J
|
||||
{semester}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</select> */}
|
||||
</div>
|
||||
<HighchartsReact ref={ref} highcharts={Highcharts} options={chartOptions} />
|
||||
</>
|
||||
|
||||
@@ -52,7 +52,7 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
|
||||
const formattedUniqueId = uniqueId.toString().padStart(5, '0');
|
||||
|
||||
const getInstructorFullName = (instructor: Instructor) => {
|
||||
const { firstName, lastName } = instructor;
|
||||
const { firstName = '', lastName = '' } = instructor;
|
||||
if (firstName === '') return capitalizeString(lastName);
|
||||
return `${capitalizeString(firstName)} ${capitalizeString(lastName)}`;
|
||||
};
|
||||
@@ -76,7 +76,7 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
|
||||
|
||||
const handleOpenCES = async () => {
|
||||
const openTabs = instructors.map(instructor => {
|
||||
let { firstName, lastName } = instructor;
|
||||
let { firstName = '', lastName = '' } = instructor;
|
||||
firstName = capitalizeString(firstName);
|
||||
lastName = capitalizeString(lastName);
|
||||
return openCESPage({ instructorFirstName: firstName, instructorLastName: lastName });
|
||||
@@ -134,9 +134,12 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
|
||||
.flatMap((el, i) => (i === 0 ? [el] : [', ', el]))}
|
||||
</Text>
|
||||
)}
|
||||
<div className='flex gap-1'>
|
||||
{flags.map(flag => (
|
||||
<Chip key={flagMap[flag]} label={flagMap[flag]} />
|
||||
<div className='flex items-center gap-1'>
|
||||
{flags.map((flag: string) => (
|
||||
<Chip
|
||||
key={flagMap[flag as keyof typeof flagMap]}
|
||||
label={flagMap[flag as keyof typeof flagMap]}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -145,7 +148,11 @@ export default function HeadingAndActions({ course, activeSchedule, onClose }: H
|
||||
const daysString = meeting.getDaysString({ format: 'long', separator: 'long' });
|
||||
const timeString = meeting.getTimeString({ separator: ' to ', capitalize: false });
|
||||
return (
|
||||
<Text key={daysString + timeString + meeting.location.building} variant='h4' as='p'>
|
||||
<Text
|
||||
key={daysString + timeString + (meeting.location?.building ?? '')}
|
||||
variant='h4'
|
||||
as='p'
|
||||
>
|
||||
{daysString} {timeString}
|
||||
{meeting.location && (
|
||||
<>
|
||||
|
||||
@@ -14,7 +14,7 @@ const RECRUIT_FROM_DEPARTMENTS = ['C S', 'ECE', 'MIS', 'CSE', 'EE', 'ITD'];
|
||||
* This adds a new column to the course catalog table header.
|
||||
* @returns a react portal to the new column or null if the column has not been created yet.
|
||||
*/
|
||||
export default function RecruitmentBanner(): JSX.Element {
|
||||
export default function RecruitmentBanner(): JSX.Element | null {
|
||||
const [container, setContainer] = useState<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -12,7 +12,7 @@ import styles from './TableRow.module.scss';
|
||||
interface Props {
|
||||
isSelected: boolean;
|
||||
row: ScrapedRow;
|
||||
onClick: (...args: any[]) => any;
|
||||
onClick: (...args: unknown[]) => unknown;
|
||||
activeSchedule?: UserSchedule;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
const { element, course } = row;
|
||||
|
||||
useEffect(() => {
|
||||
element.classList.add(styles.row);
|
||||
element.classList.add(styles.row!);
|
||||
element.classList.add('group');
|
||||
const portalContainer = document.createElement('td');
|
||||
// portalContainer.style.textAlign = 'right';
|
||||
@@ -39,12 +39,12 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
|
||||
return () => {
|
||||
portalContainer.remove();
|
||||
element.classList.remove(styles.row);
|
||||
element.classList.remove(styles.row!);
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
useEffect(() => {
|
||||
element.classList[isSelected ? 'add' : 'remove'](styles.selectedRow);
|
||||
element.classList[isSelected ? 'add' : 'remove'](styles.selectedRow!);
|
||||
}, [isSelected, element.classList]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -52,10 +52,10 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
|
||||
const isInSchedule = activeSchedule.containsCourse(course);
|
||||
|
||||
element.classList[isInSchedule ? 'add' : 'remove'](styles.inActiveSchedule);
|
||||
element.classList[isInSchedule ? 'add' : 'remove'](styles.inActiveSchedule!);
|
||||
|
||||
return () => {
|
||||
element.classList.remove(styles.inActiveSchedule);
|
||||
element.classList.remove(styles.inActiveSchedule!);
|
||||
};
|
||||
}, [activeSchedule, course, element.classList]);
|
||||
|
||||
@@ -72,11 +72,11 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
}
|
||||
}
|
||||
|
||||
element.classList[conflicts.length ? 'add' : 'remove'](styles.isConflict);
|
||||
element.classList[conflicts.length ? 'add' : 'remove'](styles.isConflict!);
|
||||
setConflicts(conflicts);
|
||||
|
||||
return () => {
|
||||
element.classList.remove(styles.isConflict);
|
||||
element.classList.remove(styles.isConflict!);
|
||||
setConflicts([]);
|
||||
};
|
||||
}, [activeSchedule, course, element.classList]);
|
||||
|
||||
@@ -15,10 +15,10 @@ export default function TableSubheading({ row }: Props): JSX.Element | null {
|
||||
const { element } = row;
|
||||
|
||||
useEffect(() => {
|
||||
element.classList.add(styles.subheader);
|
||||
element.classList.add(styles.subheader!);
|
||||
|
||||
return () => {
|
||||
element.classList.remove(styles.subheader);
|
||||
element.classList.remove(styles.subheader!);
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user