diff --git a/src/shared/types/Course.ts b/src/shared/types/Course.ts index 62b42bfa..492f5cf4 100644 --- a/src/shared/types/Course.ts +++ b/src/shared/types/Course.ts @@ -1,3 +1,4 @@ +import { type CourseColors, getCourseColors } from '@shared/util/colors'; import type { Serialized } from 'chrome-extension-toolkit'; import type { CourseMeeting } from './CourseMeeting'; @@ -75,6 +76,8 @@ export class Course { semester: Semester; /** Unix timestamp of when the course was last scraped */ scrapedAt: number; + /** The colors of the course when displayed */ + colors: CourseColors; constructor(course: Serialized) { Object.assign(this, course); @@ -83,6 +86,7 @@ export class Course { if (!course.scrapedAt) { this.scrapedAt = Date.now(); } + this.colors = course.colors ? structuredClone(course.colors) : getCourseColors('emerald', 500); } /** diff --git a/src/stories/components/ConflictsWithWarning.stories.tsx b/src/stories/components/ConflictsWithWarning.stories.tsx index f7543e1c..9fb0f780 100644 --- a/src/stories/components/ConflictsWithWarning.stories.tsx +++ b/src/stories/components/ConflictsWithWarning.stories.tsx @@ -1,6 +1,7 @@ import { Course, Status } from '@shared/types/Course'; import { CourseMeeting } from '@shared/types/CourseMeeting'; import Instructor from '@shared/types/Instructor'; +import { getCourseColors } from '@shared/util/colors'; import type { Meta, StoryObj } from '@storybook/react'; import ConflictsWithWarning from '@views/components/common/ConflictsWithWarning/ConflictsWithWarning'; @@ -45,6 +46,7 @@ export const ExampleCourse: Course = new Course({ uniqueId: 12345, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', scrapedAt: Date.now(), + colors: getCourseColors('blue', 500), }); export const ExampleCourse2: Course = new Course({ courseName: 'PRINCIPLES OF COMPUTER SYSTEMS', @@ -92,6 +94,7 @@ export const ExampleCourse2: Course = new Course({ uniqueId: 67890, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', scrapedAt: Date.now(), + colors: getCourseColors('yellow', 500), }); const meta = { diff --git a/src/stories/components/List.stories.tsx b/src/stories/components/List.stories.tsx index f92c341b..c140b300 100644 --- a/src/stories/components/List.stories.tsx +++ b/src/stories/components/List.stories.tsx @@ -2,7 +2,6 @@ import type { DraggableProvidedDragHandleProps } from '@hello-pangea/dnd'; import { Course, Status } from '@shared/types/Course'; import { CourseMeeting } from '@shared/types/CourseMeeting'; import Instructor from '@shared/types/Instructor'; -import type { CourseColors } from '@shared/util/colors'; import { tailwindColorways } from '@shared/util/storybook'; import type { Meta, StoryObj } from '@storybook/react'; import List from '@views/components/common/List/List'; @@ -63,6 +62,7 @@ const generateCourses = (count: number): Course[] => { status: Status.WAITLISTED, uniqueId: 12345 + i, // Make uniqueId different for each course url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + colors: tailwindColorways[i], }); courses.push(course); @@ -72,10 +72,9 @@ const generateCourses = (count: number): Course[] => { }; const exampleCourses = generateCourses(numberOfCourses); -const generateCourseBlocks = ( - { course, colors }: { course: Course; colors: CourseColors }, - dragHandleProps: DraggableProvidedDragHandleProps -) => ; +const generateCourseBlocks = (course: Course, dragHandleProps: DraggableProvidedDragHandleProps) => ( + +); const meta = { title: 'Components/Common/List', @@ -94,9 +93,9 @@ type Story = StoryObj; export const Default: Story = { args: { - draggables: exampleCourses.map((course, i) => ({ course, colors: tailwindColorways[i] })), + draggables: exampleCourses, children: generateCourseBlocks, - itemKey: (item: { course: Course }) => item.course.uniqueId, + itemKey: (item: Course) => item.uniqueId, gap: 12, }, render: args => ( diff --git a/src/stories/components/PopupCourseBlock.stories.tsx b/src/stories/components/PopupCourseBlock.stories.tsx index 5a8e1a0c..0cc207e5 100644 --- a/src/stories/components/PopupCourseBlock.stories.tsx +++ b/src/stories/components/PopupCourseBlock.stories.tsx @@ -54,6 +54,7 @@ export const ExampleCourse: Course = new Course({ status: Status.WAITLISTED, uniqueId: 12345, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + colors: getCourseColors('cyan', 500), }); // More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export diff --git a/src/stories/components/calendar/CalendarBottomBar.stories.tsx b/src/stories/components/calendar/CalendarBottomBar.stories.tsx index 37770636..fc93943c 100644 --- a/src/stories/components/calendar/CalendarBottomBar.stories.tsx +++ b/src/stories/components/calendar/CalendarBottomBar.stories.tsx @@ -34,6 +34,7 @@ const exampleGovCourse: Course = new Course({ status: Status.OPEN, uniqueId: 12345, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + colors: getCourseColors('red', 500), }); const examplePsyCourse: Course = new Course({ @@ -65,6 +66,7 @@ const examplePsyCourse: Course = new Course({ status: Status.CLOSED, uniqueId: 12346, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + colors: getCourseColors('blue', 500), }); const meta = { diff --git a/src/stories/components/calendar/CalendarCourse.stories.tsx b/src/stories/components/calendar/CalendarCourse.stories.tsx index 519b76ae..173ca8c2 100644 --- a/src/stories/components/calendar/CalendarCourse.stories.tsx +++ b/src/stories/components/calendar/CalendarCourse.stories.tsx @@ -2,6 +2,7 @@ import { Course, Status } from '@shared/types/Course'; import { CourseMeeting, DAY_MAP } from '@shared/types/CourseMeeting'; import { CourseSchedule } from '@shared/types/CourseSchedule'; import Instructor from '@shared/types/Instructor'; +import { getCourseColors } from '@shared/util/colors'; import type { Meta, StoryObj } from '@storybook/react'; import CalendarCourse from '@views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting'; @@ -15,7 +16,6 @@ const meta = { argTypes: { course: { control: 'object' }, meetingIdx: { control: 'number' }, - color: { control: 'color' }, rightIcon: { control: 'object' }, }, } satisfies Meta; @@ -56,8 +56,8 @@ export const Default: Story = { season: 'Spring', }, scrapedAt: Date.now(), + colors: getCourseColors('emerald', 500), }), meetingIdx: 0, - color: 'red', }, }; diff --git a/src/stories/injected/mocked.ts b/src/stories/injected/mocked.ts index 4b0641c4..8fd95263 100644 --- a/src/stories/injected/mocked.ts +++ b/src/stories/injected/mocked.ts @@ -2,6 +2,7 @@ import { Course, Status } from '@shared/types/Course'; import { CourseMeeting, DAY_MAP } from '@shared/types/CourseMeeting'; import Instructor from '@shared/types/Instructor'; import { UserSchedule } from '@shared/types/UserSchedule'; +import { getCourseColors } from '@shared/util/colors'; export const exampleCourse: Course = new Course({ courseName: 'ELEMS OF COMPTRS/PROGRAMMNG-WB', @@ -51,6 +52,7 @@ export const exampleCourse: Course = new Course({ status: Status.OPEN, uniqueId: 12345, url: 'https://utdirect.utexas.edu/apps/registrar/course_schedule/20242/12345/', + colors: getCourseColors('blue', 500), }); export const exampleSchedule: UserSchedule = new UserSchedule({ @@ -104,6 +106,7 @@ export const bevoCourse: Course = new Course({ season: 'Spring', }, scrapedAt: Date.now(), + colors: getCourseColors('green', 500), }); export const bevoSchedule: UserSchedule = new UserSchedule({ @@ -158,6 +161,7 @@ export const mikeScottCS314Course: Course = new Course({ season: 'Spring', }, scrapedAt: Date.now(), + colors: getCourseColors('orange', 500), }); export const mikeScottCS314Schedule: UserSchedule = new UserSchedule({ diff --git a/src/views/components/PopupMain.tsx b/src/views/components/PopupMain.tsx index 91e7d831..009b0107 100644 --- a/src/views/components/PopupMain.tsx +++ b/src/views/components/PopupMain.tsx @@ -1,6 +1,5 @@ import { background } from '@shared/messages'; import { UserScheduleStore } from '@shared/storage/UserScheduleStore'; -import { tailwindColorways } from '@shared/util/storybook'; import Divider from '@views/components/common/Divider/Divider'; import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot'; import List from '@views/components/common/List/List'; @@ -86,22 +85,19 @@ export default function PopupMain(): JSX.Element {
{activeSchedule?.courses?.length > 0 && ( ({ - course, - colors: tailwindColorways[i], - }))} + draggables={activeSchedule.courses} onReordered={reordered => { - activeSchedule.courses = reordered.map(c => c.course); + activeSchedule.courses = reordered; replaceSchedule(getActiveSchedule(), activeSchedule); }} - itemKey={e => e.course.uniqueId} + itemKey={e => e.uniqueId} gap={10} > - {({ course, colors }, handleProps) => ( + {(course, handleProps) => ( )} diff --git a/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx b/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx index 710a49e0..0e4393f6 100644 --- a/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx +++ b/src/views/components/calendar/CalendarCourseBlock/CalendarCourseMeeting.tsx @@ -12,8 +12,6 @@ export interface CalendarCourseMeetingProps { course: Course; /* index into course meeting array to display */ meetingIdx?: number; - /** The background color for the course. */ - color: string; /** The icon to display on the right side of the course. This is optional. */ rightIcon?: React.ReactNode; } @@ -22,12 +20,11 @@ export interface CalendarCourseMeetingProps { * `CalendarCourseMeeting` is a functional component that displays a course meeting. * * @example - * } /> + * } /> */ export default function CalendarCourseMeeting({ course, meetingIdx, - color, rightIcon, }: CalendarCourseMeetingProps): JSX.Element { let meeting: CourseMeeting | null = meetingIdx !== undefined ? course.schedule.meetings[meetingIdx] : null; diff --git a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx index 319a1b2d..313fa46f 100644 --- a/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx +++ b/src/views/components/calendar/CalendarGrid/CalendarGrid.tsx @@ -1,5 +1,4 @@ import type { Course } from '@shared/types/Course'; -import { getCourseColors } from '@shared/util/colors'; import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import Text from '@views/components/common/Text/Text'; import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; @@ -120,11 +119,8 @@ function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseC }); }); - // Part of TODO: block.course is definitely a course object - // console.log(courseCells); - return courseCells.map((block, i) => { - const { courseDeptAndInstr, timeAndLocation, status, colors } = courseCells[i].componentProps; + const { courseDeptAndInstr, timeAndLocation, status } = courseCells[i].componentProps; return (
setCourse(block.course)} />
diff --git a/src/views/lib/CourseCatalogScraper.ts b/src/views/lib/CourseCatalogScraper.ts index 6965dab5..abc417be 100644 --- a/src/views/lib/CourseCatalogScraper.ts +++ b/src/views/lib/CourseCatalogScraper.ts @@ -2,6 +2,7 @@ import type { InstructionMode, ScrapedRow, Semester, StatusType } from '@shared/ import { Course, Status } from '@shared/types/Course'; import { CourseSchedule } from '@shared/types/CourseSchedule'; import Instructor from '@shared/types/Instructor'; +import { getCourseColors } from '@shared/util/colors'; import type { SiteSupportType } from '@views/lib/getSiteSupport'; /** @@ -93,6 +94,7 @@ export class CourseCatalogScraper { description: this.getDescription(document), semester: this.getSemester(), scrapedAt: Date.now(), + colors: getCourseColors('emerald', 500), }); courses.push({ element: row,