Skip to content

Commit

Permalink
feat: add Calendar schedules component (clicking on storybook not wor…
Browse files Browse the repository at this point in the history
…king)
  • Loading branch information
caseycharleston authored and doprz committed Mar 6, 2024
1 parent 5be7973 commit d1a336e
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 0 deletions.
142 changes: 142 additions & 0 deletions src/stories/components/CalendarSchedules.stories.tsx
Original file line number Diff line number Diff line change
@@ -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) => (
<div>
<CalendarSchedules {...args} />
</div>
),
} satisfies Meta<typeof CalendarSchedules>;

export default meta;
type Story = StoryObj<typeof meta>;

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,
},
};
36 changes: 36 additions & 0 deletions src/stories/components/ScheduleListItem.stories.tsx
Original file line number Diff line number Diff line change
@@ -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) => <ScheduleListItem {...args} />;

Default.args = {
name: 'My Schedule',
active: true,
};

export const Active = (args) => <ScheduleListItem {...args} />;

Active.args = {
name: 'My Schedule',
active: true,
};

export const Inactive = (args) => <ScheduleListItem {...args} />;

Inactive.args = {
name: 'My Schedule',
active: false,
};
Original file line number Diff line number Diff line change
@@ -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) => (
<div onClick={() => setActiveScheduleIndex(index)}>
<ScheduleListItem
active={index === activeScheduleIndex}
name={schedule.name}
/>
</div>
));

return (
<div style={{ ...props.style }} className='items-center'>
<div className='m0 m-b-2 w-full flex justify-between'>
<Text variant='h3'>MY SCHEDULES</Text>
<div className='cursor-pointer items-center justify-center btn-transition -ml-1.5 hover:text-zinc-400'>
<Text variant='h3'>
<AddSchedule />
</Text>
</div>
</div>

<List gap={10} draggableElements={scheduleComponents} itemHeight={30} listHeight={0} listWidth={240} />
</div>
);
}
44 changes: 44 additions & 0 deletions src/views/components/common/ScheduleListItem/ScheduleListItem.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div style={{ ...props.style }} className='items-center'>
<li
className='text-ut-burntorange w-100% flex cursor-pointer items-center self-stretch justify-left'
>
<div className='group flex justify-center'>
<DropdownDrag className='h-6 w-6 cursor-move text-zinc-300 btn-transition -ml-1.5 hover:text-zinc-400' />
<div className='inline-flex items-center justify-center gap-1.5'>
<div className='h-5.5 w-5.5 flex items-center justify-center border-2px border-current rounded-full btn-transition group-active:scale-95'>
<div
className={clsx(
'bg-current h-3 w-3 rounded-full transition tansform scale-100 ease-out-expo duration-250',
{
'scale-0! opacity-0 ease-in-out! duration-200!': !props.active
}
)}
/>
</div>
<Text variant='p'>{props.name}</Text>
</div>
</div>
</li>
</div>
);
}

0 comments on commit d1a336e

Please sign in to comment.