Link component, Card component, Course Popup component styling, and wrangling with the serialization type"

This commit is contained in:
Sriram Hariharan
2023-03-05 22:52:11 -06:00
parent 6d69cd2548
commit ad8a06d831
10 changed files with 147 additions and 49 deletions

View File

@@ -0,0 +1,8 @@
@import 'src/views/styles/base.module.scss';
.card {
background: $white;
border: 1px solid #c3cee0;
box-sizing: border-box;
border-radius: 8px;
}

View File

@@ -0,0 +1,27 @@
import classNames from 'classnames';
import React, { Component } from 'react';
import styles from './Card.module.scss';
export type Props = {
style?: React.CSSProperties;
className?: string;
onClick?: (...args) => void;
children?: React.ReactNode;
testId?: string;
};
/**
* A reusable Card component that can be used to wrap other components
*/
export default function Card(props: Props) {
return (
<div
style={props.style}
className={classNames(styles.card, props.className)}
onClick={props.onClick}
data-testid={props.testId}
>
{props.children}
</div>
);
}

View File

@@ -0,0 +1,5 @@
.link {
font-family: 'Inter', sans-serif;
text-decoration: underline;
cursor: pointer;
}

View File

@@ -0,0 +1,25 @@
import classNames from 'classnames';
import React, { PropsWithChildren } from 'react';
import { bMessenger } from 'src/shared/messages';
import Text, { TextProps } from '../Text/Text';
import styles from './Link.module.scss';
type Props = TextProps & {
url?: string;
};
/**
* A reusable Text component with props that build on top of the design system for the extension
*/
export default function Link(props: PropsWithChildren<Props>) {
let passedProps = {
...props,
};
const { url } = props;
if (url && !props.onClick) {
passedProps.onClick = () => bMessenger.openNewTab({ url });
}
return <Text {...passedProps} className={classNames(styles.link, props.className)} />;
}

View File

@@ -17,16 +17,12 @@ export default function Popup(props: PropsWithChildren<Props>) {
return (
<div
style={props.style}
className={classNames(
styles.container,
{
[styles.overlay]: props.overlay,
},
props.className
)}
className={classNames(styles.container, {
[styles.overlay]: props.overlay,
})}
data-testid={props.testId}
>
<div className={styles.body}>{props.children}</div>
<div className={classNames(styles.body, props.className)}>{props.children}</div>
</div>
);
}

View File

@@ -4,9 +4,9 @@ import colors, { ISassColors } from 'src/views/styles/colors.module.scss';
import fonts, { Size, Weight } from 'src/views/styles/fonts.module.scss';
import styles from './Text.module.scss';
type Props = {
export type TextProps = {
color?: keyof ISassColors;
weight: Weight;
weight?: Weight;
size: Size;
span?: boolean;
className?: string;
@@ -18,7 +18,7 @@ type Props = {
/**
* A reusable Text component with props that build on top of the design system for the extension
*/
export default function Text(props: PropsWithChildren<Props>) {
export default function Text(props: PropsWithChildren<TextProps>) {
const style = props.style || {};
style.textAlign ??= props.align;

View File

@@ -1,35 +1,30 @@
.popupBody {
height: auto;
color: white;
padding: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.popup {
border-radius: 12px;
position: relative;
.coursePopupBase {
position: fixed;
transform: translateY(-50%);
top: 15px;
right: 15px;
z-index: 2147483647;
}
.close {
position: absolute;
top: 12px;
right: 12px;
cursor: pointer;
}
.coursePopupHeader {
display: flex;
height: 50;
background-color: #29465b;
width: 100%;
.closePopupButton {
display: flex;
.body {
height: auto;
color: white;
padding: 12px;
margin: 40px;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin: 5px;
margin-left: auto;
cursor: pointer;
color: white;
.title {
display: flex;
align-items: center;
justify-content: center;
.uniqueId {
margin-left: 8px;
}
}
}
}

View File

@@ -1,7 +1,10 @@
import React from 'react';
import { Course } from 'src/shared/types/Course';
import Card from '../../common/Card/Card';
import Icon from '../../common/Icon/Icon';
import Link from '../../common/Link/Link';
import Popup from '../../common/Popup/Popup';
import Text from '../../common/Text/Text';
import styles from './CoursePopup.module.scss';
interface Props {
@@ -14,11 +17,24 @@ interface Props {
*/
export default function CoursePopup({ course, onClose }: Props) {
return (
<Popup overlay>
<div className={styles.popupBody}>
<div className={styles.courseTitle}>{course.courseName}</div>
<div className={styles.courseDescription}>{course.uniqueId}</div>
</div>
<Popup className={styles.popup} overlay>
<Icon className={styles.close} size='large' name='close' onClick={onClose} />
<Card className={styles.body}>
<Text className={styles.title} size='large' weight='bold' color='black'>
{course.courseName} ({course.department} {course.number})
<Link
span
url={course.url}
className={styles.uniqueId}
size='medium'
weight='semi_bold'
color='burnt_orange'
>
#{course.uniqueId}
</Link>
</Text>
</Card>
</Popup>
);
}

View File

@@ -159,12 +159,12 @@ export class CourseCatalogScraper {
.map(name => name.trim())
.filter(Boolean);
return names.map(name => {
const [lastName, rest] = name.split(',').map(s => s.trim());
return names.map(fullName => {
const [lastName, rest] = fullName.split(',').map(s => s.trim());
const [firstName, middleInitial] = rest.split(' ');
return {
name,
fullName,
firstName,
lastName,
middleInitial,