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:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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 || ''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user