import type { Course } from '@shared/types/Course'; import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import Text from '@views/components/common/Text/Text'; import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; import React from 'react'; import CalendarCell from '../CalendarGridCell/CalendarGridCell'; const daysOfWeek = ['MON', 'TUE', 'WED', 'THU', 'FRI']; const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); interface Props { courseCells?: CalendarGridCourse[]; saturdayClass?: boolean; setCourse: React.Dispatch>; } function CalendarHour({ hour }: { hour: number }) { return (
{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}
); } function makeGridRow(row: number, cols: number): JSX.Element { const hour = hoursOfDay[row]; return ( <>
{[...Array(cols).keys()].map(col => ( ))} ); } // TODO: add Saturday class support /** * Grid of CalendarGridCell components forming the user's course schedule calendar view * @param props */ export default function CalendarGrid({ courseCells, saturdayClass, // TODO: implement/move away from props setCourse, }: React.PropsWithChildren): JSX.Element { return (
{/* Displaying day labels */}
{daysOfWeek.map(day => (
{day}
))} {[...Array(13).keys()].map(i => makeGridRow(i, 5))} {Array(6) .fill(1) .map(() => (
))} {courseCells ? : null}
); } interface AccountForCourseConflictsProps { courseCells: CalendarGridCourse[]; setCourse: React.Dispatch>; } // TODO: Possibly refactor to be more concise function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseConflictsProps): JSX.Element[] { // Groups by dayIndex to identify overlaps const days = courseCells.reduce((acc, cell: CalendarGridCourse) => { const { dayIndex } = cell.calendarGridPoint; if (!acc[dayIndex]) { acc[dayIndex] = []; } acc[dayIndex].push(cell); return acc; }, {}); // Check for overlaps within each day and adjust gridColumnIndex and totalColumns Object.values(days).forEach((dayCells: CalendarGridCourse[]) => { // Sort by start time to ensure proper columnIndex assignment dayCells.sort((a, b) => a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex); dayCells.forEach((cell, _, arr) => { let columnIndex = 1; cell.totalColumns = 1; // Check for overlaps and adjust columnIndex as needed for (let otherCell of arr) { if (otherCell !== cell) { const isOverlapping = otherCell.calendarGridPoint.startIndex < cell.calendarGridPoint.endIndex && otherCell.calendarGridPoint.endIndex > cell.calendarGridPoint.startIndex; if (isOverlapping) { // Adjust columnIndex to not overlap with the otherCell if (otherCell.gridColumnStart && otherCell.gridColumnStart >= columnIndex) { columnIndex = otherCell.gridColumnStart + 1; } cell.totalColumns += 1; } } } cell.gridColumnStart = columnIndex; cell.gridColumnEnd = columnIndex + 1; }); }); return courseCells.map((block, i) => { const { courseDeptAndInstr, timeAndLocation, status } = courseCells[i].componentProps; return (
setCourse(block.course)} />
); }); }