Skip to content

Commit

Permalink
fix: course conflicts when times are same
Browse files Browse the repository at this point in the history
  • Loading branch information
jsun969 committed Sep 25, 2024
1 parent 195ef94 commit 086c0e7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 29 deletions.
36 changes: 24 additions & 12 deletions src/components/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -26,7 +26,13 @@ const useDraggingCourse = create<DraggingCourseState>()((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();
Expand Down Expand Up @@ -57,7 +63,7 @@ const CourseCard = ({ course }: { course: WeekCourse }) => {
isDragging ? 'opacity-30' : 'opacity-75',
)}
>
<div className="text-2xs">{course.time.start}</div>
<div className="text-2xs">{time.start}</div>
<div className="font-bold">
[{course.classType}] {course.name.subject} {course.name.code} -{' '}
{course.name.title}
Expand Down Expand Up @@ -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 (
<div className="absolute left-10 top-10 z-0 grid grid-cols-5 grid-rows-[repeat(28,_minmax(0,_1fr))]">
{courses.map((dayCourses, i) =>
dayCourses.map((course, j) => (
{day.map((times, i) =>
times.map((time, j) => (
<div
className="p-[1px]"
key={course.id + course.classTypeId + j}
className="flex gap-[1px] p-[1px]"
key={`${i}${j}`}
style={{
gridColumnStart: i + 1,
gridRowStart: getGridRow(course.time.start),
gridRowEnd: getGridRow(course.time.end),
height: calcHoursDuration(course.time) * 6 + 'rem',
gridRowStart: getGridRow(time.time.start),
gridRowEnd: getGridRow(time.time.end),
height: calcHoursDuration(time.time) * 6 + 'rem',
zIndex: 10 - j, // TODO: Remove zIndex after implementing course conflicts #5
}}
>
<CourseCard course={course} />
{time.courses.map((course) => (
<CourseCard
key={course.id + course.classTypeId}
course={course}
time={time.time}
/>
))}
</div>
)),
)}
Expand Down
38 changes: 23 additions & 15 deletions src/helpers/calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
});

Expand Down
5 changes: 3 additions & 2 deletions src/types/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ export type WeekCourse = {
classTypeId: string;
classType: string;
location: string;
time: DateTimeRange;
classNumber: string;
};
export type WeekCourses = Array<Array<WeekCourse>>;
export type WeekCourses = Array<
Array<{ time: DateTimeRange; courses: Array<WeekCourse> }>
>;

export type OtherWeekCourseTime = {
classes: Array<{ number: string; location: string }>;
Expand Down

0 comments on commit 086c0e7

Please sign in to comment.