From 0f730d6c50462c9f7d0428ebb379742305212ef6 Mon Sep 17 00:00:00 2001 From: doprz <52579214+doprz@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:04:00 -0600 Subject: [PATCH] feat: bottom bar for the calendar page (#91) --- .../components/CalendarBottomBar.stories.tsx | 101 ++++++++++++++++++ .../CalendarBottomBar/CalendarBottomBar.tsx | 44 ++++++++ .../CalendarCourseCell/CalendarCourseCell.tsx | 24 +++-- .../common/CalendarGrid/CalendarGrid.tsx | 27 ++--- 4 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 src/stories/components/CalendarBottomBar.stories.tsx create mode 100644 src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx diff --git a/src/stories/components/CalendarBottomBar.stories.tsx b/src/stories/components/CalendarBottomBar.stories.tsx new file mode 100644 index 00000000..a1f1c5c7 --- /dev/null +++ b/src/stories/components/CalendarBottomBar.stories.tsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { Meta, StoryObj } from '@storybook/react'; +import { Course, Status } from '@shared/types/Course'; +import Instructor from '@shared/types/Instructor'; +import { CalendarBottomBar } from '@views/components/common/CalendarBottomBar/CalendarBottomBar'; +import { getCourseColors } from '../../shared/util/colors'; + +const exampleGovCourse: Course = new Course({ + courseName: 'Nope', + creditHours: 3, + department: 'GOV', + description: ['nah', 'aint typing this', 'corndog'], + flags: ['no flag for you >:)'], + fullName: 'GOV 312L Something something', + instructionMode: 'Online', + instructors: [ + new Instructor({ + firstName: 'Bevo', + lastName: 'Barrymore', + fullName: 'Bevo Barrymore', + }), + ], + isReserved: false, + number: '312L', + schedule: { + meetings: [], + }, + semester: { + code: '12345', + season: 'Spring', + year: 2024, + }, + status: Status.OPEN, + uniqueId: 12345, + url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', +}); + +const examplePsyCourse: Course = new Course({ + courseName: 'Nope Again', + creditHours: 3, + department: 'PSY', + description: ['nah', 'aint typing this', 'corndog'], + flags: ['no flag for you >:)'], + fullName: 'PSY 317L Yada yada', + instructionMode: 'Online', + instructors: [ + new Instructor({ + firstName: 'Bevo', + lastName: 'Etz', + fullName: 'Bevo Etz', + }), + ], + isReserved: false, + number: '317L', + schedule: { + meetings: [], + }, + semester: { + code: '12346', + season: 'Spring', + year: 2024, + }, + status: Status.CLOSED, + uniqueId: 12346, + url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', +}); + +const meta = { + title: 'Components/Common/CalendarBottomBar', + component: CalendarBottomBar, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], + argTypes: {}, +} satisfies Meta; +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + courses: [ + { + colors: getCourseColors('pink', 200), + courseDeptAndInstr: `${exampleGovCourse.department} ${exampleGovCourse.number} – ${exampleGovCourse.instructors[0].lastName}`, + status: exampleGovCourse.status, + }, + { + colors: getCourseColors('slate', 500), + courseDeptAndInstr: `${examplePsyCourse.department} ${examplePsyCourse.number} – ${examplePsyCourse.instructors[0].lastName}`, + status: examplePsyCourse.status, + }, + ], + }, + render: props => ( +
+ +
+ ), +}; diff --git a/src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx b/src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx new file mode 100644 index 00000000..5b99ab8d --- /dev/null +++ b/src/views/components/common/CalendarBottomBar/CalendarBottomBar.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import clsx from 'clsx'; +import Text from '../Text/Text'; +import CalendarCourseBlock, { CalendarCourseCellProps } from '../CalendarCourseCell/CalendarCourseCell'; +import { Button } from '../Button/Button'; +import ImageIcon from '~icons/material-symbols/image'; +import CalendarMonthIcon from '~icons/material-symbols/calendar-month'; + +type CalendarBottomBarProps = { + courses: CalendarCourseCellProps[]; +}; + +/** + * + */ +export const CalendarBottomBar = ({ courses }: CalendarBottomBarProps): JSX.Element => { + if (courses.length === -1) console.log('foo'); // dumb line to make eslint happy + return ( +
+
+ Async. and Other: +
+ {courses.map(course => ( + + ))} +
+
+
+ + +
+
+ ); +}; diff --git a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx b/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx index 044b4ffb..384c2d44 100644 --- a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx +++ b/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx @@ -7,17 +7,21 @@ import WaitlistIcon from '~icons/material-symbols/timelapse'; import CancelledIcon from '~icons/material-symbols/warning'; import Text from '../Text/Text'; -export interface CalendarCourseBlockProps { - /** The Course that the meeting is for. */ - course: Course; - /* index into course meeting array to display */ - meetingIdx?: number; - /** The background color for the course. */ - color: string; +export interface CalendarCourseCellProps { + courseDeptAndInstr: string; + timeAndLocation?: string; + status: Status; + colors: CourseColors; + className?: string; } -const CalendarCourseCell: React.FC = ({ course, meetingIdx }: CalendarCourseCellProps) => { - let meeting: CourseMeeting | null = meetingIdx !== undefined ? course.schedule.meetings[meetingIdx] : null; +const CalendarCourseCell: React.FC = ({ + courseDeptAndInstr, + timeAndLocation, + status, + colors, + className, +}: CalendarCourseCellProps) => { let rightIcon: React.ReactNode | null = null; if (status === Status.WAITLISTED) { rightIcon = ; @@ -32,7 +36,7 @@ const CalendarCourseCell: React.FC = ({ course, meeting return (
!['S', 'SU'].includes(key)); const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); @@ -34,12 +34,12 @@ interface Props { * Grid of CalendarGridCell components forming the user's course schedule calendar view * @param props */ -function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren ): JSX.Element { +function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren): JSX.Element { const calendarRef = useRef(null); // Create a ref for the calendar grid const saveAsPNG = () => { if (calendarRef.current) { - html2canvas(calendarRef.current).then((canvas) => { + html2canvas(calendarRef.current).then(canvas => { // Create an a element to trigger download const a = document.createElement('a'); a.href = canvas.toDataURL('image/png'); @@ -85,19 +85,22 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren - +
- ))} + ))}
-
{/* First divider */} +
{/* First divider */} -
{/* Second divider */} +
{/* Second divider */}