From d1a336e903f09b04b89f11ba7ede2f7d26e0ac3c Mon Sep 17 00:00:00 2001 From: Casey Charleston Date: Sat, 17 Feb 2024 14:40:20 -0600 Subject: [PATCH] feat: add Calendar schedules component (clicking on storybook not working) --- .../components/CalendarSchedules.stories.tsx | 142 ++++++++++++++++++ .../components/ScheduleListItem.stories.tsx | 36 +++++ .../CalendarSchedules/CalendarSchedules.tsx | 41 +++++ .../ScheduleListItem/ScheduleListItem.tsx | 44 ++++++ 4 files changed, 263 insertions(+) create mode 100644 src/stories/components/CalendarSchedules.stories.tsx create mode 100644 src/stories/components/ScheduleListItem.stories.tsx create mode 100644 src/views/components/common/CalendarSchedules/CalendarSchedules.tsx create mode 100644 src/views/components/common/ScheduleListItem/ScheduleListItem.tsx diff --git a/src/stories/components/CalendarSchedules.stories.tsx b/src/stories/components/CalendarSchedules.stories.tsx new file mode 100644 index 000000000..8928875e2 --- /dev/null +++ b/src/stories/components/CalendarSchedules.stories.tsx @@ -0,0 +1,142 @@ +import { Course, Status } from '@shared/types/Course'; +import { UserSchedule } from '@shared/types/UserSchedule'; +import type { Meta, StoryObj } from '@storybook/react'; +import React from 'react'; +import { CourseMeeting, DAY_MAP } from 'src/shared/types/CourseMeeting'; +import { CourseSchedule } from 'src/shared/types/CourseSchedule'; +import Instructor from 'src/shared/types/Instructor'; +import { CalendarSchedules } from 'src/views/components/common/CalendarSchedules/CalendarSchedules'; + +const meta = { + title: 'Components/Common/CalendarSchedules', + component: CalendarSchedules, + parameters: { + layout: 'centered', + tags: ['autodocs'], + }, + argTypes: { + dummySchedules: { control: 'object' }, + dummyActiveIndex: { control: 'number' }, + }, + render: (args: any) => ( +
+ +
+ ), +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const schedules = [ + new UserSchedule({ + courses: [ + new Course({ + uniqueId: 123, + number: '311C', + fullName: "311C - Bevo's Default Course", + courseName: "Bevo's Default Course", + department: 'BVO', + creditHours: 3, + status: Status.WAITLISTED, + instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })], + isReserved: false, + url: '', + flags: [], + schedule: new CourseSchedule({ + meetings: [ + new CourseMeeting({ + days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F], + startTime: 480, + endTime: 570, + location: { + building: 'UTC', + room: '123', + }, + }), + ], + }), + instructionMode: 'In Person', + semester: { + year: 2024, + season: 'Fall', + }, + }), + ], + name: 'Main Schedule', + }), + new UserSchedule({ + courses: [ + new Course({ + uniqueId: 123, + number: '311C', + fullName: "311C - Bevo's Default Course", + courseName: "Bevo's Default Course", + department: 'BVO', + creditHours: 3, + status: Status.WAITLISTED, + instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })], + isReserved: false, + url: '', + flags: [], + schedule: new CourseSchedule({ + meetings: [ + new CourseMeeting({ + days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F], + startTime: 480, + endTime: 570, + location: { + building: 'UTC', + room: '123', + }, + }), + ], + }), + instructionMode: 'In Person', + semester: { + year: 2024, + season: 'Spring', + }, + }), + new Course({ + uniqueId: 123, + number: '311C', + fullName: "311C - Bevo's Default Course", + courseName: "Bevo's Default Course", + department: 'BVO', + creditHours: 3, + status: Status.WAITLISTED, + instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })], + isReserved: false, + url: '', + flags: [], + schedule: new CourseSchedule({ + meetings: [ + new CourseMeeting({ + days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F], + startTime: 480, + endTime: 570, + location: { + building: 'UTC', + room: '123', + }, + }), + ], + }), + instructionMode: 'In Person', + semester: { + year: 2024, + season: 'Fall', + }, + }), + ], + name: 'Backup #3', + }), +]; + +export const Default: Story = { + args: { + dummySchedules: schedules, + dummyActiveIndex: 0, + }, +}; diff --git a/src/stories/components/ScheduleListItem.stories.tsx b/src/stories/components/ScheduleListItem.stories.tsx new file mode 100644 index 000000000..80eb5871e --- /dev/null +++ b/src/stories/components/ScheduleListItem.stories.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import ScheduleListItem from 'src/views/components/common/ScheduleListItem/ScheduleListItem'; + +export default { + title: 'Components/Common/ScheduleListItem', + component: ScheduleListItem, + parameters: { + layout: 'centered', + tags: ['autodocs'], + }, + argTypes: { + active: { control: 'boolean' }, + name: { control: 'text' }, + }, +}; + +export const Default = (args) => ; + +Default.args = { + name: 'My Schedule', + active: true, +}; + +export const Active = (args) => ; + +Active.args = { + name: 'My Schedule', + active: true, +}; + +export const Inactive = (args) => ; + +Inactive.args = { + name: 'My Schedule', + active: false, +}; diff --git a/src/views/components/common/CalendarSchedules/CalendarSchedules.tsx b/src/views/components/common/CalendarSchedules/CalendarSchedules.tsx new file mode 100644 index 000000000..5f15f451e --- /dev/null +++ b/src/views/components/common/CalendarSchedules/CalendarSchedules.tsx @@ -0,0 +1,41 @@ +import { UserSchedule } from '@shared/types/UserSchedule'; +import React, { useEffect, useState } from 'react'; +import AddSchedule from '~icons/material-symbols/add'; +import List from '../List/List'; +import ScheduleListItem from '../ScheduleListItem/ScheduleListItem'; +import Text from '../Text/Text'; + +export type Props = { + style?: React.CSSProperties; + dummySchedules?: UserSchedule[]; + dummyActiveIndex?: number; +}; + +export function CalendarSchedules(props: Props) { + const [activeScheduleIndex, setActiveScheduleIndex] = useState(props.dummyActiveIndex || 0); + const [schedules, setSchedules] = useState(props.dummySchedules || []); + + let scheduleComponents = schedules.map((schedule, index) => ( +
setActiveScheduleIndex(index)}> + +
+ )); + + return ( +
+
+ MY SCHEDULES +
+ + + +
+
+ + +
+ ); +} diff --git a/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx b/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx new file mode 100644 index 000000000..f8f31a158 --- /dev/null +++ b/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx @@ -0,0 +1,44 @@ +import clsx from 'clsx'; +import React from 'react'; +import DropdownDrag from '~icons/material-symbols/drag-indicator'; +import Text from '../Text/Text'; + + +export type Props = { + style?: React.CSSProperties; + active?: boolean; + name: string; +}; + + + +/** + * This is a reusable dropdown component that can be used to toggle the visiblity of information + */ +export default function ScheduleListItem(props: Props) { + + return ( +
+
  • +
    + +
    +
    +
    +
    + {props.name} +
    +
    +
  • +
    + ); +}