From 297601e715ff589ee862ca673e8273223b7d27f0 Mon Sep 17 00:00:00 2001 From: knownotunknown <78577376+knownotunknown@users.noreply.github.com> Date: Sun, 18 Feb 2024 16:28:29 -0600 Subject: [PATCH] Grid works cleanly with up to two course conflicts. Prob needs refactoring --- .../components/CalendarGrid.stories.tsx | 118 ++++++++++++++---- .../CalendarCourseCell/CalendarCourseCell.tsx | 4 +- .../common/CalendarGrid/CalendarGrid.tsx | 95 +++++++++++--- src/views/hooks/useFlattenedCourseSchedule.ts | 3 + 4 files changed, 174 insertions(+), 46 deletions(-) diff --git a/src/stories/components/CalendarGrid.stories.tsx b/src/stories/components/CalendarGrid.stories.tsx index 7a6d3da2..de7e17f8 100644 --- a/src/stories/components/CalendarGrid.stories.tsx +++ b/src/stories/components/CalendarGrid.stories.tsx @@ -18,33 +18,97 @@ const meta = { export default meta; const testData: CalendarGridCourse[] = [ - { - calendarGridPoint: { - dayIndex: 4, - startIndex: 10, - endIndex: 11, - }, - componentProps: { - courseDeptAndInstr: 'Course 1', - timeAndLocation: '9:00 AM - 10:00 AM, Room 101', - status: Status.OPEN, - colors: getCourseColors('emerald', 500), - }, - }, - { - calendarGridPoint: { - dayIndex: 1, - startIndex: 10, - endIndex: 12, - }, - componentProps: { - courseDeptAndInstr: 'Course 2', - timeAndLocation: '10:00 AM - 11:00 AM, Room 102', - status: Status.CLOSED, - colors: getCourseColors('emerald', 500), - }, - }, - // add more data as needed + { + calendarGridPoint: { + dayIndex: 4, + startIndex: 10, + endIndex: 11, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 2, + startIndex: 5, + endIndex: 6, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 2', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 4, + startIndex: 10, + endIndex: 11, + }, + componentProps: { + courseDeptAndInstr: 'Course 1', + timeAndLocation: '9:00 AM - 10:00 AM, Room 101', + status: Status.OPEN, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 2', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 3', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, + { + calendarGridPoint: { + dayIndex: 1, + startIndex: 10, + endIndex: 12, + }, + componentProps: { + courseDeptAndInstr: 'Course 4', + timeAndLocation: '10:00 AM - 11:00 AM, Room 102', + status: Status.CLOSED, + colors: getCourseColors('emerald', 500), + }, + }, ]; type Story = StoryObj; diff --git a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx b/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx index 0e15e6e6..71a7c0e7 100644 --- a/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx +++ b/src/views/components/common/CalendarCourseCell/CalendarCourseCell.tsx @@ -36,12 +36,12 @@ const CalendarCourseCell: React.FC = ({ return (
-
+
!['S', 'SU'].includes(key)); const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); const grid = []; @@ -37,14 +36,13 @@ interface Props { * @param props */ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren): JSX.Element { - const [iterator, setIterator] = useState(0); const [grid, setGrid] = useState([]); const calendarRef = useRef(null); // Create a ref for the calendar grid const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key)); const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8); - const saveAsPNG = () => { + /* const saveAsPNG = () => { htmlToImage .toPng(calendarRef.current, { backgroundColor: 'white', @@ -75,7 +73,7 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { console.error('oops, something went wrong!', error); }); - }; + }; */ useEffect(() => { const newGrid = []; @@ -84,7 +82,7 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren @@ -104,28 +102,30 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren; */ /* let completeGridCell = shouldRenderChild ? : ; */ - row.push(); + row.push(); } newGrid.push(row); } - }; + setGrid(newGrid); + }, []); return (
-
+
{/* Displaying the rest of the calendar */}
{/* Displaying day labels */} -
+
{daysOfWeek.map(day => (
- {day} + {day}
))} - {grid.map((row, rowIndex) => (row))} - {courseCells.map((block: CalendarGridCourse) => ( -
row)} + {accountForCourseConflicts(courseCells)} + {/* courseCells.map((block: CalendarGridCourse) => ( +
-
- ))} +
+ )) */}
@@ -148,6 +148,67 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren { + 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) { + console.log('Found overlapping element'); + // Adjust columnIndex to not overlap with the otherCell + if (otherCell.gridColumnStart && otherCell.gridColumnStart >= columnIndex) { + columnIndex = otherCell.gridColumnStart + 1; + console.log(columnIndex); + } + cell.totalColumns += 1; + } + } + } + cell.gridColumnStart = columnIndex; + cell.gridColumnEnd = columnIndex + 1; + }); + }); + + return courseCells.map(block => ( +
+ +
+ )); +} /*
@@ -160,4 +221,4 @@ export default CalendarGrid; PNG Save as .PNG -
*/ \ No newline at end of file +
*/ diff --git a/src/views/hooks/useFlattenedCourseSchedule.ts b/src/views/hooks/useFlattenedCourseSchedule.ts index da1a3bb3..e279783f 100644 --- a/src/views/hooks/useFlattenedCourseSchedule.ts +++ b/src/views/hooks/useFlattenedCourseSchedule.ts @@ -21,6 +21,9 @@ interface CalendarGridPoint { export interface CalendarGridCourse { calendarGridPoint: CalendarGridPoint; componentProps: CalendarCourseCellProps; + gridColumnStart?: number; + gridColumnEnd?: number; + totalColumns?: number; } const convertMinutesToIndex = (minutes: number): number => Math.floor(minutes - 420 / 30);