refactor: Replace Webpack with Vite (#53)
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
import { ScrapedRow } from '@shared/types/Course';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { ScrapedRow } from 'src/shared/types/Course';
|
||||
import useInfiniteScroll from 'src/views/hooks/useInfiniteScroll';
|
||||
import { CourseCatalogScraper } from 'src/views/lib/CourseCatalogScraper';
|
||||
import { SiteSupport } from 'src/views/lib/getSiteSupport';
|
||||
import useInfiniteScroll from '@views/hooks/useInfiniteScroll';
|
||||
import { CourseCatalogScraper } from '@views/lib/CourseCatalogScraper';
|
||||
import { SiteSupport } from '@views/lib/getSiteSupport';
|
||||
import {
|
||||
loadNextCourseCatalogPage,
|
||||
AutoLoadStatus,
|
||||
loadNextCourseCatalogPage,
|
||||
removePaginationButtons,
|
||||
} from 'src/views/lib/loadNextCourseCatalogPage';
|
||||
import Spinner from '../../common/Spinner/Spinner';
|
||||
} from '@views/lib/loadNextCourseCatalogPage';
|
||||
import styles from './AutoLoad.module.scss';
|
||||
|
||||
type Props = {
|
||||
@@ -53,16 +52,21 @@ export default function AutoLoad({ addRows }: Props) {
|
||||
addRows(scrapedRows);
|
||||
}, [addRows]);
|
||||
|
||||
if (!container || status === AutoLoadStatus.IDLE) {
|
||||
if (!container || status === AutoLoadStatus.DONE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createPortal(
|
||||
<div>
|
||||
{status === AutoLoadStatus.LOADING && (
|
||||
<div>
|
||||
<Spinner />
|
||||
<h2>Loading Next Page...</h2>
|
||||
{status !== AutoLoadStatus.ERROR && (
|
||||
<div
|
||||
style={{
|
||||
height: '500px',
|
||||
backgroundColor: '#f4f4f4',
|
||||
}}
|
||||
>
|
||||
{/* <Spinner />
|
||||
<h2>Loading Next Page...</h2> */}
|
||||
</div>
|
||||
)}
|
||||
{status === AutoLoadStatus.ERROR && (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import 'src/views/styles/base.module.scss';
|
||||
@use 'src/views/styles/colors.module.scss';
|
||||
|
||||
.container {
|
||||
margin: 20px;
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
.restriction {
|
||||
color: $speedway_brick;
|
||||
color: colors.$speedway_brick;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Course } from '@shared/types/Course';
|
||||
import classNames from 'classnames';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Course } from 'src/shared/types/Course';
|
||||
import Spinner from 'src/views/components/common/Spinner/Spinner';
|
||||
import Text from 'src/views/components/common/Text/Text';
|
||||
import { CourseCatalogScraper } from 'src/views/lib/CourseCatalogScraper';
|
||||
import { SiteSupport } from 'src/views/lib/getSiteSupport';
|
||||
import Spinner from '@views/components/common/Spinner/Spinner';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import { CourseCatalogScraper } from '@views/lib/CourseCatalogScraper';
|
||||
import { SiteSupport } from '@views/lib/getSiteSupport';
|
||||
import Card from '../../../common/Card/Card';
|
||||
import styles from './CourseDescription.module.scss';
|
||||
|
||||
@@ -18,6 +18,9 @@ enum LoadStatus {
|
||||
ERROR = 'ERROR',
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default function CourseDescription({ course }: Props) {
|
||||
const [description, setDescription] = useState<string[]>([]);
|
||||
const [status, setStatus] = useState<LoadStatus>(LoadStatus.LOADING);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { background } from '@shared/messages';
|
||||
import { Course } from '@shared/types/Course';
|
||||
import { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import React from 'react';
|
||||
import { background } from 'src/shared/messages';
|
||||
import { Course } from 'src/shared/types/Course';
|
||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||
import { Button } from 'src/views/components/common/Button/Button';
|
||||
import Card from 'src/views/components/common/Card/Card';
|
||||
import Icon from 'src/views/components/common/Icon/Icon';
|
||||
import Text from 'src/views/components/common/Text/Text';
|
||||
import { Button } from '@views/components/common/Button/Button';
|
||||
import Card from '@views/components/common/Card/Card';
|
||||
import Icon from '@views/components/common/Icon/Icon';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import styles from './CourseButtons.module.scss';
|
||||
|
||||
type Props = {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Course } from '@shared/types/Course';
|
||||
import { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import React from 'react';
|
||||
import { Course } from 'src/shared/types/Course';
|
||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||
import Card from 'src/views/components/common/Card/Card';
|
||||
import Icon from 'src/views/components/common/Icon/Icon';
|
||||
import Link from 'src/views/components/common/Link/Link';
|
||||
import Text from 'src/views/components/common/Text/Text';
|
||||
import Card from '@views/components/common/Card/Card';
|
||||
import Icon from '@views/components/common/Icon/Icon';
|
||||
import Link from '@views/components/common/Link/Link';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import CourseButtons from './CourseButtons/CourseButtons';
|
||||
import styles from './CourseHeader.module.scss';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Course } from '@shared/types/Course';
|
||||
import { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import React from 'react';
|
||||
import { Course } from 'src/shared/types/Course';
|
||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||
import Popup from '../../common/Popup/Popup';
|
||||
import CourseDescription from './CourseDescription/CourseDescription';
|
||||
import CourseHeader from './CourseHeader/CourseHeader';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@import 'src/views/styles/base.module.scss';
|
||||
@use 'src/views/styles/colors.module.scss';
|
||||
@use 'src/views/styles/elevation.module.scss';
|
||||
|
||||
.chartContainer {
|
||||
height: 250px;
|
||||
@@ -14,11 +15,11 @@
|
||||
justify-content: center;
|
||||
|
||||
select {
|
||||
z-index: $MAX_Z_INDEX;
|
||||
z-index: elevation.$MAX_Z_INDEX;
|
||||
padding: 4px;
|
||||
font-family: 'Inter';
|
||||
border-radius: 8px;
|
||||
border-color: $charcoal;
|
||||
border-color: colors.$charcoal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/* eslint-disable no-nested-ternary */
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import HighchartsReact from 'highcharts-react-official';
|
||||
import { Course, Semester } from '@shared/types/Course';
|
||||
import { Distribution, LetterGrade } from '@shared/types/Distribution';
|
||||
import Highcharts from 'highcharts';
|
||||
import Card from 'src/views/components/common/Card/Card';
|
||||
import { Course, Semester } from 'src/shared/types/Course';
|
||||
import colors from 'src/views/styles/colors.module.scss';
|
||||
import Spinner from 'src/views/components/common/Spinner/Spinner';
|
||||
import Text from 'src/views/components/common/Text/Text';
|
||||
import Icon from 'src/views/components/common/Icon/Icon';
|
||||
import { Distribution, LetterGrade } from 'src/shared/types/Distribution';
|
||||
import HighchartsReact from 'highcharts-react-official';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import Card from '@views/components/common/Card/Card';
|
||||
import Icon from '@views/components/common/Icon/Icon';
|
||||
import Spinner from '@views/components/common/Spinner/Spinner';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import {
|
||||
NoDataError,
|
||||
queryAggregateDistribution,
|
||||
querySemesterDistribution,
|
||||
} from 'src/views/lib/database/queryDistribution';
|
||||
} from '@views/lib/database/queryDistribution';
|
||||
import colors from '@views/styles/colors.module.scss';
|
||||
import styles from './GradeDistribution.module.scss';
|
||||
|
||||
enum DataStatus {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import 'src/views/styles/base.module.scss';
|
||||
@use 'src/views/styles/colors.module.scss';
|
||||
|
||||
.container {
|
||||
background-color: $burnt_orange;
|
||||
background-color: colors.$burnt_orange;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 12px;
|
||||
|
||||
@@ -15,6 +15,9 @@ export default function TableHead({ children }: PropsWithChildren) {
|
||||
const lastTableHeadCell = document.querySelector('table thead th:last-child');
|
||||
lastTableHeadCell!.after(container);
|
||||
setContainer(container);
|
||||
return () => {
|
||||
container.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!container) {
|
||||
|
||||
@@ -1,33 +1,21 @@
|
||||
@import 'src/views/styles/base.module.scss';
|
||||
|
||||
.rowButton {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.selectedRow {
|
||||
* {
|
||||
background: $burnt_orange !important;
|
||||
color: white !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.inActiveSchedule {
|
||||
* {
|
||||
color: $turtle_pond !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
|
||||
.isConflict {
|
||||
* {
|
||||
color: $speedway_brick !important;
|
||||
font-weight: normal !important;
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
}
|
||||
@use 'src/views/styles/colors.module.scss';
|
||||
|
||||
.row {
|
||||
> td:first-child {
|
||||
padding-left: 12px !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
> td:last-child {
|
||||
padding-right: 12px !important;
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
> * {
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
}
|
||||
.conflictTooltip {
|
||||
position: relative;
|
||||
display: none;
|
||||
@@ -54,4 +42,46 @@
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
|
||||
// :global(ul.flag) li {
|
||||
// transform: scale(1.5); // omg the flags are on ONE LONG GIF FILE AND SHIFTED BY Y COORDINATES
|
||||
// }
|
||||
}
|
||||
|
||||
.rowButton {
|
||||
margin: 0.25rem 0;
|
||||
&:active {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
place-items: center;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.selectedRow {
|
||||
> * {
|
||||
background: colors.$burnt_orange !important;
|
||||
color: white !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.rowButton {
|
||||
background: colors.$burnt_orange !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.inActiveSchedule {
|
||||
* {
|
||||
color: colors.$turtle_pond !important;
|
||||
font-weight: bold !important;
|
||||
}
|
||||
}
|
||||
|
||||
.isConflict {
|
||||
* {
|
||||
color: colors.$speedway_brick !important;
|
||||
font-weight: normal !important;
|
||||
text-decoration: line-through !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Course, ScrapedRow } from '@shared/types/Course';
|
||||
import { UserSchedule } from '@shared/types/UserSchedule';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Course, ScrapedRow } from 'src/shared/types/Course';
|
||||
import { UserSchedule } from 'src/shared/types/UserSchedule';
|
||||
import { Button } from '../../common/Button/Button';
|
||||
import Icon from '../../common/Icon/Icon';
|
||||
import Text from '../../common/Text/Text';
|
||||
@@ -29,6 +29,7 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
||||
useEffect(() => {
|
||||
element.classList.add(styles.row);
|
||||
const portalContainer = document.createElement('td');
|
||||
portalContainer.style.textAlign = 'right';
|
||||
const lastTableCell = element.querySelector('td:last-child');
|
||||
lastTableCell!.after(portalContainer);
|
||||
setContainer(portalContainer);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@use 'src/views/styles/fonts.module.scss';
|
||||
|
||||
.subheader {
|
||||
h2 {
|
||||
font-size: fonts.$medium_size;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ScrapedRow } from '@shared/types/Course';
|
||||
import { useEffect } from 'react';
|
||||
import styles from './TableSubheading.module.scss';
|
||||
|
||||
interface Props {
|
||||
row: ScrapedRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
const { element } = row;
|
||||
|
||||
useEffect(() => {
|
||||
element.classList.add(styles.subheader);
|
||||
|
||||
return () => {
|
||||
element.classList.remove(styles.subheader);
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user