added onclose to popup, coursepopup now displaying time info, renamed vars, added compiler for scss to typescript and tsconfig plugins

This commit is contained in:
Sriram Hariharan
2023-03-06 21:02:29 -06:00
parent 9b76f8afa0
commit 950c4a573a
9 changed files with 663 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
import classNames from 'classnames';
import React, { PropsWithChildren } from 'react';
import React, { PropsWithChildren, useCallback } from 'react';
import styles from './Popup.module.scss';
interface Props {
@@ -8,21 +8,52 @@ interface Props {
className?: string;
/** Should it display a subtle dark overlay over the rest of the screen */
overlay?: boolean;
onClose?: () => void;
}
/**
*
* A reusable popup component that can be used to display content on the page
* @returns
*/
export default function Popup(props: PropsWithChildren<Props>) {
export default function Popup({ onClose, children, className, style, testId, overlay }: PropsWithChildren<Props>) {
const containerRef = React.useRef<HTMLDivElement>(null);
const bodyRef = React.useRef<HTMLDivElement>(null);
const handleClickOutside = useCallback(
(event: MouseEvent) => {
if (!bodyRef.current) return;
if (!bodyRef.current.contains(event.target as Node)) {
onClose?.();
}
},
[onClose, bodyRef]
);
React.useEffect(() => {
const shadowRoot = document.getElementById('ut-registration-plus-container')?.shadowRoot;
if (!shadowRoot) return;
shadowRoot.addEventListener('mousedown', handleClickOutside);
return () => {
shadowRoot.removeEventListener('mousedown', handleClickOutside);
};
}, [handleClickOutside]);
return (
<div
style={props.style}
style={style}
ref={containerRef}
className={classNames(styles.container, {
[styles.overlay]: props.overlay,
[styles.overlay]: overlay,
})}
data-testid={props.testId}
data-testid={testId}
>
<div className={classNames(styles.body, props.className)}>{props.children}</div>
<div ref={bodyRef} className={classNames(styles.body, className)}>
{children}
</div>
</div>
);
}

View File

@@ -18,7 +18,7 @@ interface Props {
export default function CoursePopup({ course, onClose }: Props) {
console.log(course);
return (
<Popup className={styles.popup} overlay>
<Popup className={styles.popup} overlay onClose={onClose}>
<Icon className={styles.close} size='large' name='close' onClick={onClose} />
<Card className={styles.body}>
<Text className={styles.title} size='large' weight='bold' color='black'>
@@ -40,6 +40,28 @@ export default function CoursePopup({ course, onClose }: Props) {
format: 'first_last',
})}
</Text>
{course.schedule.meetings.map(meeting => (
<Text size='medium'>
<Text span size='medium' weight='bold' color='black'>
{meeting.getDaysString({
format: 'long',
separator: 'short',
})}
</Text>
{' at '}
<Text span size='medium'>
{meeting.getTimeString({
separator: 'to',
capitalize: true,
})}
</Text>
{' in '}
<Link span size='medium' weight='bold' color='bluebonnet'>
{meeting.location?.building}
</Link>
</Text>
))}
</Card>
</Popup>
);

View File

@@ -14,7 +14,7 @@ enum TableDataSelector {
STATUS = 'td[data-th="Status"]',
SCHEDULE_DAYS = 'td[data-th="Days"]>span',
SCHEDULE_HOURS = 'td[data-th="Hour"]>span',
SCHEDULE_ROOM = 'td[data-th="Room"]>span',
SCHEDULE_LOCATION = 'td[data-th="Room"]>span',
FLAGS = 'td[data-th="Flags"] ul li',
}
@@ -283,7 +283,7 @@ export class CourseCatalogScraper {
getSchedule(row: HTMLTableRowElement): CourseSchedule {
const dayLines = row.querySelectorAll(TableDataSelector.SCHEDULE_DAYS);
const hourLines = row.querySelectorAll(TableDataSelector.SCHEDULE_HOURS);
const roomLines = row.querySelectorAll(TableDataSelector.SCHEDULE_ROOM);
const locLines = row.querySelectorAll(TableDataSelector.SCHEDULE_LOCATION);
if (dayLines.length !== hourLines.length) {
throw new Error('Schedule data is malformed');
@@ -296,7 +296,7 @@ export class CourseCatalogScraper {
CourseSchedule.parse(
dayLines[i].textContent || '',
hourLines[i].textContent || '',
roomLines[i].textContent || ''
locLines[i].textContent || ''
)
);
}