feat: refactor all components in injected

This commit is contained in:
doprz
2024-03-04 14:51:14 -06:00
parent f93a98e46a
commit 0c44849e15
10 changed files with 27 additions and 30 deletions

View File

@@ -10,7 +10,7 @@ import { useKeyPress } from '@views/hooks/useKeyPress';
import useSchedules from '@views/hooks/useSchedules';
import { CourseCatalogScraper } from '@views/lib/CourseCatalogScraper';
import getCourseTableRows from '@views/lib/getCourseTableRows';
import type { SiteSupport, SiteSupportType } from '@views/lib/getSiteSupport';
import type { SiteSupportType } from '@views/lib/getSiteSupport';
import { populateSearchInputs } from '@views/lib/populateSearchInputs';
import React, { useEffect, useState } from 'react';
@@ -21,7 +21,7 @@ interface Props {
/**
* This is the top level react component orchestrating the course catalog page.
*/
export default function CourseCatalogMain({ support }: Props) {
export default function CourseCatalogMain({ support }: Props): JSX.Element {
const [rows, setRows] = React.useState<ScrapedRow[]>([]);
const [selectedCourse, setSelectedCourse] = useState<Course | null>(null);

View File

@@ -21,7 +21,7 @@ import SettingsIcon from '~icons/material-symbols/settings';
* Renders the main popup component.
* This component displays the main schedule, courses, and options buttons.
*/
export default function PopupMain() {
export default function PopupMain(): JSX.Element {
const [activeSchedule, schedules] = useSchedules();
const [isPopupVisible, setIsPopupVisible] = useState(false);
const popupRef = useRef(null);

View File

@@ -9,6 +9,7 @@ type Props = {
* @param props className
* @returns The content for the settings page
*/
export default function Settings({ className }: Props) {
export default function Settings({ className }: Props): JSX.Element {
// TODO: Implement the settings page
return <div className={className}>this will be finished laterrrrrrr</div>;
}

View File

@@ -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) {
export default function AutoLoad({ addRows }: Props): JSX.Element {
const [container, setContainer] = useState<HTMLDivElement | null>(null);
const [status, setStatus] = useState<AutoLoadStatusType>(AutoLoadStatus.IDLE);

View File

@@ -14,10 +14,10 @@ const LoadStatus = {
LOADING: 'LOADING',
DONE: 'DONE',
ERROR: 'ERROR',
} as const;
} as const satisfies Record<string, string>;
type LoadStatusType = (typeof LoadStatus)[keyof typeof LoadStatus];
async function fetchDescription(course: Course): Promise<string[]> {
const fetchDescription = async (course: Course): Promise<string[]> => {
if (!course.description?.length) {
const response = await fetch(course.url);
const text = await response.text();
@@ -27,7 +27,7 @@ async function fetchDescription(course: Course): Promise<string[]> {
course.description = scraper.getDescription(doc);
}
return course.description;
}
};
/**
* Renders the description component.
@@ -37,7 +37,7 @@ async function fetchDescription(course: Course): Promise<string[]> {
* @param {Course} props.course - The course for which to display the description.
* @returns {JSX.Element} The rendered description component.
*/
const Description: React.FC<DescriptionProps> = ({ course }: DescriptionProps) => {
export default function Description({ course }: DescriptionProps): JSX.Element {
const [description, setDescription] = React.useState<string[]>([]);
const [status, setStatus] = React.useState<LoadStatusType>(LoadStatus.LOADING);
@@ -82,6 +82,4 @@ const Description: React.FC<DescriptionProps> = ({ course }: DescriptionProps) =
)}
</>
);
};
export default Description;
}

View File

@@ -21,7 +21,7 @@ const DataStatus = {
FOUND: 'FOUND',
NOT_FOUND: 'NOT_FOUND',
ERROR: 'ERROR',
} as const;
} as const satisfies Record<string, string>;
type DataStatusType = (typeof DataStatus)[keyof typeof DataStatus];
const GRADE_COLORS = {
@@ -47,7 +47,7 @@ const GRADE_COLORS = {
* @param {Course} props.course - The course for which to display the grade distribution.
* @returns {JSX.Element} The grade distribution chart component.
*/
const GradeDistribution: React.FC<GradeDistributionProps> = ({ course }) => {
export default function GradeDistribution({ course }: GradeDistributionProps): JSX.Element {
const [semester, setSemester] = React.useState('Aggregate');
const [distributions, setDistributions] = React.useState<Record<string, Distribution>>({});
const [status, setStatus] = React.useState<DataStatusType>(DataStatus.LOADING);
@@ -187,6 +187,4 @@ const GradeDistribution: React.FC<GradeDistributionProps> = ({ course }) => {
)}
</div>
);
};
export default GradeDistribution;
}

View File

@@ -38,6 +38,12 @@ export const handleOpenCalendar = async (): Promise<void> => {
openNewTab({ url });
};
/**
* Capitalizes the first letter of a string and converts the rest of the letters to lowercase.
*
* @param str - The string to be capitalized.
* @returns The capitalized string.
*/
const capitalizeString = (str: string) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
/**
@@ -49,11 +55,7 @@ const capitalizeString = (str: string) => str.charAt(0).toUpperCase() + str.slic
* @param {Function} props.onClose - The function to close the popup.
* @returns {JSX.Element} The rendered component.
*/
const HeadingAndActions: React.FC<HeadingAndActionProps> = ({
course,
activeSchedule,
onClose,
}: HeadingAndActionProps): JSX.Element => {
export default function HeadingAndActions({ course, activeSchedule, onClose }: HeadingAndActionProps): JSX.Element {
const { courseName, department, number: courseNumber, uniqueId, instructors, flags, schedule } = course;
const courseAdded = activeSchedule.courses.some(ourCourse => ourCourse.uniqueId === uniqueId);
@@ -173,6 +175,4 @@ const HeadingAndActions: React.FC<HeadingAndActionProps> = ({
<Divider orientation='horizontal' size='100%' />
</div>
);
};
export default HeadingAndActions;
}

View File

@@ -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() {
export default function RecruitmentBanner(): JSX.Element {
const [container, setContainer] = useState<HTMLDivElement | null>(null);
useEffect(() => {
@@ -55,7 +55,7 @@ export default function RecruitmentBanner() {
* Determines if recruitment can be done from the current department.
* @returns {boolean} True if recruitment can be done from the current department, false otherwise.
*/
export function canRecruitFrom(): boolean {
export const canRecruitFrom = (): boolean => {
const params = ['fos_fl', 'fos_cn'];
let department = '';
params.forEach(p => {
@@ -68,4 +68,4 @@ export function canRecruitFrom(): boolean {
return false;
}
return RECRUIT_FROM_DEPARTMENTS.includes(department);
}
};

View File

@@ -6,7 +6,7 @@ import ReactDOM from 'react-dom';
* 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 TableHead({ children }: PropsWithChildren) {
export default function TableHead({ children }: PropsWithChildren): JSX.Element | null {
const [container, setContainer] = useState<HTMLTableCellElement | null>(null);
useEffect(() => {

View File

@@ -11,7 +11,7 @@ interface Props {
* This component is injected into each row of the course catalog table.
* @returns a react portal to the new td in the column or null if the column has not been created yet.
*/
export default function TableSubheading({ row }: Props) {
export default function TableSubheading({ row }: Props): JSX.Element | null {
const { element } = row;
useEffect(() => {