diff --git a/src/components/planner/sidebar/CoursesController/ClassItem.tsx b/src/components/planner/sidebar/CoursesController/ClassItem.tsx
index 13769b51..b8bc0332 100644
--- a/src/components/planner/sidebar/CoursesController/ClassItem.tsx
+++ b/src/components/planner/sidebar/CoursesController/ClassItem.tsx
@@ -1,8 +1,8 @@
-import { useContext, useMemo } from 'react'
+import { useContext } from 'react'
import { ClassInfo } from '../../../../@types/index'
import { DropdownMenuCheckboxItem } from '../../../ui/dropdown-menu'
import { ExclamationTriangleIcon } from '@heroicons/react/20/solid'
-import { conflictsSeverity, schedulesConflict } from '../../../../utils'
+import { classesConflictSeverity } from '../../../../utils'
import MultipleOptionsContext from '../../../../contexts/MultipleOptionsContext'
import CourseContext from '../../../../contexts/CourseContext'
@@ -10,7 +10,6 @@ import CourseContext from '../../../../contexts/CourseContext'
type Props = {
course_id: number,
classInfo: ClassInfo
- conflict?: boolean
onSelect?: () => void
onMouseEnter?: () => void
onMouseLeave?: () => void
@@ -29,26 +28,26 @@ const ClassItem = ({ course_id, classInfo, onSelect, onMouseEnter, onMouseLeave
onSelect();
}
- const conflict: number = useMemo(() => {
- const classes: ClassInfo[] = []
+ const conflictSeverity = () => {
+ const chosenCourses = multipleOptions[selectedOption].course_options.filter(
+ (option) => option.course_id !== course_id
+ );
- for (const course_option of multipleOptions[selectedOption].course_options) {
- if (course_option.picked_class_id && course_option.course_id !== course_id) {
- const pickedCourse = pickedCourses.find(co => co.id === course_option.course_id);
- // retrieve class with the picked class id of the course option
- const pickedClass = pickedCourse.classes.find(c => c.id === course_option.picked_class_id);
+ const otherClasses = [];
+ chosenCourses.forEach((option) => {
+ const courseInfo = pickedCourses.find((course) => course.id === option.course_id);
+ const pickedClass = courseInfo.classes.find((classInfo) => classInfo.id === option.picked_class_id);
- classes.push(pickedClass);
- }
+ if (pickedClass) otherClasses.push(pickedClass);
+ });
+
+ let maxSeverity = 0;
+ for (const otherClass of otherClasses) {
+ maxSeverity = Math.max(maxSeverity, classesConflictSeverity(classInfo, otherClass));
}
- for (const pickedClass of classes)
- for (const slot1 of pickedClass.slots)
- for (const slot2 of classInfo.slots)
- if (schedulesConflict(slot1, slot2)) {
- return conflictsSeverity(slot1, slot2);
- }
- }, []);
+ return maxSeverity;
+ }
return (
(
{slot.lesson_type}
- {/* {convertWeekday(slot.day)} */}
- {/* {getLessonBoxTime(slot)} */}
{slot.location}
{slot.professors.map((professor) => professor.acronym).join(', ')}
@@ -72,7 +69,7 @@ const ClassItem = ({ course_id, classInfo, onSelect, onMouseEnter, onMouseLeave
))}
-
+ 0 ? 'block' : 'hidden'} ${conflictSeverity() == 2 ? 'text-red-600' : 'text-amber-500'}`} aria-hidden="true" />
)
}
diff --git a/src/components/planner/sidebar/CoursesController/ClassSelectorDropdownController.tsx b/src/components/planner/sidebar/CoursesController/ClassSelectorDropdownController.tsx
index a5d42203..bf064d62 100644
--- a/src/components/planner/sidebar/CoursesController/ClassSelectorDropdownController.tsx
+++ b/src/components/planner/sidebar/CoursesController/ClassSelectorDropdownController.tsx
@@ -4,7 +4,7 @@ import { ClassInfo, CourseInfo, CourseOption, ProfessorInfo } from "../../../../
import StorageAPI from "../../../../api/storage";
import CourseContext from "../../../../contexts/CourseContext";
import MultipleOptionsContext from "../../../../contexts/MultipleOptionsContext";
-import { getAllPickedSlots, schedulesConflict, teacherIdsFromCourseInfo, uniqueTeachersFromCourseInfo } from "../../../../utils";
+import { teacherIdsFromCourseInfo, uniqueTeachersFromCourseInfo } from "../../../../utils";
import { Desert } from "../../../svgs";
import { DropdownMenuGroup, DropdownMenuItem, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger } from "../../../ui/dropdown-menu";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../ui/tabs";
@@ -157,13 +157,6 @@ const ClassSelectorDropdownController = ({
setMultipleOptions(newMultipleOptions)
}
- // Checks if any of the selected classes have time conflicts with the classInfo
- // This is used to display a warning icon in each class of the dropdown in case of conflicts
- const timesCollideWithSelected = (classInfo: ClassInfo) => {
- const pickedSlots = getAllPickedSlots(pickedCourses, multipleOptions[selectedOption])
- return pickedSlots.some((slot) => classInfo.slots.some((currentSlot) => schedulesConflict(slot, currentSlot)))
- }
-
return <>
{course.classes === null ? (
@@ -226,7 +219,6 @@ const ClassSelectorDropdownController = ({
key={`schedule-${classInfo.name}`}
course_id={course.id}
classInfo={classInfo}
- conflict={timesCollideWithSelected(classInfo)}
onSelect={() => {
setSelectedClassId(classInfo.id)
setPreview(null)
@@ -260,7 +252,6 @@ const ClassSelectorDropdownController = ({
key={`schedule-${classInfo.name}`}
course_id={course.id}
classInfo={classInfo}
- conflict={timesCollideWithSelected(classInfo)}
onSelect={() => {
setSelectedClassId(classInfo.id)
setPreview(null)
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 9a26ab6f..af71ab82 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,6 +1,6 @@
import config from '../config/prod.json'
import dev_config from '../config/local.json'
-import { CourseInfo, CourseOption, SlotInfo, MultipleOptions, Option, PickedCourses, ProfessorInfo } from '../@types'
+import { CourseInfo, CourseOption, SlotInfo, MultipleOptions, Option, PickedCourses, ProfessorInfo, ClassInfo } from '../@types'
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
import Plausible from 'plausible-tracker'
@@ -77,6 +77,20 @@ const conflictsSeverity = (first: SlotInfo, second: SlotInfo): number => {
return (isMandatory(first) && isMandatory(second)) ? 2 : 1;
}
+const classesConflictSeverity = (first: ClassInfo, second: ClassInfo): number => {
+ let maxSeverity = 0;
+
+ for (const slot of first.slots) {
+ for (const otherSlot of second.slots) {
+ if (schedulesConflict(slot, otherSlot)) {
+ maxSeverity = Math.max(maxSeverity, conflictsSeverity(slot, otherSlot));
+ }
+ }
+ }
+
+ return maxSeverity;
+}
+
const schedulesConflict = (first: SlotInfo, second: SlotInfo) => {
if (first.day !== second.day) return false
@@ -395,5 +409,6 @@ export {
uniqueTeachersFromCourseInfo,
teacherIdsFromCourseInfo,
scrollToTop,
+ classesConflictSeverity,
plausible
}