diff --git a/src/stories/components/CalendarSchedules.stories.tsx b/src/stories/components/CalendarSchedules.stories.tsx
new file mode 100644
index 00000000..8928875e
--- /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 00000000..80eb5871
--- /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 00000000..5f15f451
--- /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 (
+
+ );
+}
diff --git a/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx b/src/views/components/common/ScheduleListItem/ScheduleListItem.tsx
new file mode 100644
index 00000000..f8f31a15
--- /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 (
+
+ );
+}