From 086c0e79dd82b11f1c01441f66c171b6a2566856 Mon Sep 17 00:00:00 2001 From: jsun969 Date: Wed, 25 Sep 2024 15:45:01 +0930 Subject: [PATCH] fix: course conflicts when times are same --- src/components/Calendar.tsx | 36 +++++++++++++++++++++++------------ src/helpers/calendar.ts | 38 ++++++++++++++++++++++--------------- src/types/course.ts | 5 +++-- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/components/Calendar.tsx b/src/components/Calendar.tsx index 29cf146..ee859c2 100644 --- a/src/components/Calendar.tsx +++ b/src/components/Calendar.tsx @@ -8,7 +8,7 @@ import { YEAR } from '../constants/year'; import { useCourseColor, useEnrolledCourse } from '../data/enrolled-courses'; import { useCalendar, useOtherWeekCourseTimes } from '../helpers/calendar'; import type dayjs from '../lib/dayjs'; -import type { WeekCourse } from '../types/course'; +import type { DateTimeRange, WeekCourse, WeekCourses } from '../types/course'; import { timeToDayjs } from '../utils/date'; import { useDrag, useDrop } from '../utils/dnd'; import { calcHoursDuration } from '../utils/hours-duration'; @@ -26,7 +26,13 @@ const useDraggingCourse = create()((set) => ({ stop: () => set({ isDragging: false, course: null }), })); -const CourseCard = ({ course }: { course: WeekCourse }) => { +const CourseCard = ({ + course, + time, +}: { + course: WeekCourse; + time: DateTimeRange; +}) => { const color = useCourseColor(course.id); const draggingCourse = useDraggingCourse(); @@ -57,7 +63,7 @@ const CourseCard = ({ course }: { course: WeekCourse }) => { isDragging ? 'opacity-30' : 'opacity-75', )} > -
{course.time.start}
+
{time.start}
[{course.classType}] {course.name.subject} {course.name.code} -{' '} {course.name.title} @@ -170,23 +176,29 @@ const getGridRow = (time: string) => { const t = timeToDayjs(time); return t.hour() * 2 + (t.minute() >= 30 ? 1 : 0) - 13; }; -const CalendarCourses = ({ courses }: { courses: WeekCourse[][] }) => { +const CalendarCourses = ({ courses: day }: { courses: WeekCourses }) => { return (
- {courses.map((dayCourses, i) => - dayCourses.map((course, j) => ( + {day.map((times, i) => + times.map((time, j) => (
- + {time.courses.map((course) => ( + + ))}
)), )} diff --git a/src/helpers/calendar.ts b/src/helpers/calendar.ts index 5a37752..b94645e 100644 --- a/src/helpers/calendar.ts +++ b/src/helpers/calendar.ts @@ -75,39 +75,47 @@ export const getWeekCourses = ( cl.meetings.forEach((m) => { const isMeetingInWeek = checkDateRangeInWeek(weekStart, m.date); if (!isMeetingInWeek) return; - const course: WeekCourse = { + const course = courses[WEEK_DAYS.indexOf(m.day)]; + const newCourse: WeekCourse = { id: c.id, name: c.name, classTypeId: cl.typeId, classType: cl.type, location: m.location, - time: m.time, classNumber: cl.classNumber, }; - courses[WEEK_DAYS.indexOf(m.day)].push(course); + const existingTime = course.find( + (t) => t.time.start === m.time.start && t.time.end === m.time.end, + ); + if (existingTime) { + existingTime.courses.push(newCourse); + return; + } + const newTime = m.time; + course.push({ time: newTime, courses: [newCourse] }); }); }); }); // TODO: Remove this sorting after implementing course conflicts #5 courses.forEach((dayCourses) => { - // Sort by start time - dayCourses.sort((a, b) => { - const aStart = timeToDayjs(a.time.start); - const bStart = timeToDayjs(b.time.start); - if (aStart.isBefore(bStart)) return -1; - if (aStart.isAfter(bStart)) return 1; - return 0; - }); - // Sort by duration (shortest first) + // Sort by duration (shortest first) and start time (latest first) dayCourses.sort((a, b) => { const aStart = timeToDayjs(a.time.start); const aEnd = timeToDayjs(a.time.end); const bStart = timeToDayjs(b.time.start); const bEnd = timeToDayjs(b.time.end); - const aDuration = aStart.diff(aEnd, 'minute'); - const bDuration = bStart.diff(bEnd, 'minute'); - return bDuration - aDuration; + + const aDuration = aEnd.diff(aStart, 'minute'); + const bDuration = bEnd.diff(bStart, 'minute'); + + if (aDuration === bDuration) { + if (aStart.isBefore(bStart)) return 1; + if (aStart.isAfter(bStart)) return -1; + return 0; + } + + return aDuration - bDuration; }); }); diff --git a/src/types/course.ts b/src/types/course.ts index 5f639cc..fd3d608 100644 --- a/src/types/course.ts +++ b/src/types/course.ts @@ -52,10 +52,11 @@ export type WeekCourse = { classTypeId: string; classType: string; location: string; - time: DateTimeRange; classNumber: string; }; -export type WeekCourses = Array>; +export type WeekCourses = Array< + Array<{ time: DateTimeRange; courses: Array }> +>; export type OtherWeekCourseTime = { classes: Array<{ number: string; location: string }>;