Made CourseCells and CalendarGridCells more responsive. CourseCells now rendering onto grid. Still, need to make course cells more responsive, and add edge cases

This commit is contained in:
knownotunknown
2024-02-18 14:10:13 -06:00
parent a1a0f00514
commit b0a95a6153
6 changed files with 125 additions and 82 deletions

View File

@@ -1,8 +1,8 @@
import { Meta, StoryObj } from '@storybook/react';
import CalendarGrid from 'src/views/components/common/CalendarGrid/CalendarGrid';
import { getCourseColors } from 'src/shared/util/colors';
import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule';
import { Status } from 'src/shared/types/Course';
import CalendarGrid from '@views/components/common/CalendarGrid/CalendarGrid';
import { getCourseColors } from '@shared/util/colors';
import { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule';
import { Status } from '@shared/types/Course';
const meta = {
title: 'Components/Common/CalendarGrid',
@@ -20,9 +20,9 @@ export default meta;
const testData: CalendarGridCourse[] = [
{
calendarGridPoint: {
dayIndex: 0,
startIndex: 4,
endIndex: 6,
dayIndex: 4,
startIndex: 10,
endIndex: 11,
},
componentProps: {
courseDeptAndInstr: 'Course 1',
@@ -33,9 +33,9 @@ const testData: CalendarGridCourse[] = [
},
{
calendarGridPoint: {
dayIndex: 4,
dayIndex: 1,
startIndex: 10,
endIndex: 20,
endIndex: 12,
},
componentProps: {
courseDeptAndInstr: 'Course 2',

View File

@@ -36,7 +36,7 @@ const CalendarCourseCell: React.FC<CalendarCourseCellProps> = ({
return (
<div
className={clsx('w-full flex justify-center rounded p-2', fontColor, className)}
className={clsx('h-full w-full flex justify-center rounded p-2', fontColor, className)}
style={{
backgroundColor: colors.primaryColor,
}}

View File

@@ -14,8 +14,9 @@
.calendarGrid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(13, 1fr);
position:absolute;
grid-template-rows: repeat(26, 1fr);
width: 100%;
height: 100%;
}
.calendarRow {
@@ -27,7 +28,7 @@
flex-direction: column;
gap: 10px;
position: relative; // Ensuring that child elements can be positioned in relation to this.
min-width: 500px;
min-width: 800px;
min-height: 500px;
}
@@ -56,7 +57,7 @@
justify-content: space-between;
align-items: flex-start;
flex: 1 0 0;
border-radius: var(--border-radius-none, 0px);
border-radius: 0px;
}
.timeBlock {
@@ -128,3 +129,12 @@
width: 1px;
background-color: grey;
}
.dot {
height: 75%; /* 75% of the container's height */
width: 75%; /* 75% of the container's width */
background-color: #000000; /* Color of the dot */
border-radius: 50%; /* Rounds the corners into a circle */
top: 12.5%; /* Centers the dot vertically */
left: 12.5%; /* Centers the dot horizontally */
}

View File

@@ -1,16 +1,16 @@
import React, { useState, useRef } from 'react';
import html2canvas from 'html2canvas';
import React, { useState, useRef, useEffect } from 'react';
// import html2canvas from 'html2canvas';
import { DAY_MAP } from 'src/shared/types/CourseMeeting';
import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule';
import calIcon from 'src/assets/icons/cal.svg';
/* import calIcon from 'src/assets/icons/cal.svg';
import pngIcon from 'src/assets/icons/png.svg';
*/
import CalendarCell from '../CalendarGridCell/CalendarGridCell';
import CalendarCourseCell from '../CalendarCourseCell/CalendarCourseCell';
import styles from './CalendarGrid.module.scss';
import calIcon from 'src/assets/icons/cal.svg';
import pngIcon from 'src/assets/icons/png.svg';
const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key));
/* const daysOfWeek = Object.keys(DAY_MAP).filter(key => !['S', 'SU'].includes(key));
const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8);
const grid = [];
for (let i = 0; i < 13; i++) {
@@ -25,7 +25,7 @@ for (let i = 0; i < 13; i++) {
);
row.push(Array.from({ length: 5 }, (_, j) => <CalendarCell key={j} />));
grid.push(row);
}
} */
interface Props {
courseCells: CalendarGridCourse[];
@@ -38,8 +38,12 @@ interface Props {
*/
function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren<Props>): JSX.Element {
const [iterator, setIterator] = useState<number>(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 = () => {
if (calendarRef.current) {
html2canvas(calendarRef.current).then(canvas => {
@@ -52,65 +56,88 @@ function CalendarGrid({ courseCells, saturdayClass }: React.PropsWithChildren<Pr
}
};
useEffect(() => {
const newGrid = [];
for (let i = 0; i < 13; i++) {
const row = [];
let hour = hoursOfDay[i];
let styleProp = {
gridColumn: '1',
gridRow: `${(2 * i) + 2}`,
};
row.push(
<div key={hour} className={styles.timeBlock} style={styleProp}>
<div className={styles.timeLabelContainer}>
<p>{(hour % 12 === 0 ? 12 : hour % 12) + (hour < 12 ? ' AM' : ' PM')}</p>
</div>
</div>
);
for (let k = 0; k < 5; k++) {
// let shouldRender = false;
styleProp = {
gridColumn: `${k + 2}`,
gridRow: `${2 * i + 2} / ${2 * i + 4}`,
};
/* let shouldRenderChild = courseCells[iterator]?.calendarGridPoint &&
k === courseCells[iterator].calendarGridPoint.dayIndex && i === courseCells[iterator].calendarGridPoint.startIndex;
let childElement = <div className={styles.dot}/>; */
/* let completeGridCell = shouldRenderChild ? <CalendarCell key={k} children={childElement}/>
: <CalendarCell key={k} />; */
row.push(<CalendarCell key={k} styleProp={styleProp}/>);
}
newGrid.push(row);
}
setGrid(newGrid);
}, []);
return (
<div className={styles.calendar}>
<div className={styles.dayLabelContainer}/>
{/* Displaying the rest of the calendar */}
<div ref={calendarRef} className={styles.timeAndGrid}>
{/* <div className={styles.timeColumn}>
<div className={styles.timeBlock}></div>
{hoursOfDay.map((hour) => (
<div key={hour} className={styles.timeBlock}>
<div className={styles.timeLabelContainer}>
<p>{hour % 12 === 0 ? 12 : hour % 12} {hour < 12 ? 'AM' : 'PM'}</p>
</div>
</div>
))}
</div> */}
<div className={styles.calendarGrid} id='grid1'>
<div className={styles.timeAndGrid}>
<div className={styles.calendarGrid}>
{/* Displaying day labels */}
<div className={styles.timeBlock}/>
{daysOfWeek.map((day, x) => (
<div key={`${day}`} className={styles.day}>
{daysOfWeek.map(day => (
<div key={day} className={styles.day}>
{day}
</div>
))}
{grid.map((row, y) => (
<div key={`${row}`}>
{row.map((cell, x) => {
const shouldRenderChild = courseCells[iterator].calendarGridPoint && x === courseCells[iterator].calendarGridPoint.dayIndex && y === courseCells[iterator].calendarGridPoint.startIndex;
if (shouldRenderChild) {
setIterator((iterator) => iterator + 1);
}
return (
<div key={`${cell}`}>
{cell}
{shouldRenderChild && <CalendarCourseCell
courseDeptAndInstr={courseCells[iterator].componentProps.courseDeptAndInstr}
status={courseCells[iterator].componentProps.status}
colors={courseCells[iterator].componentProps.colors} />}
</div>
);
})}
{grid.map((row, rowIndex) => (row))}
{courseCells.map((block: CalendarGridCourse) => (
<div
key={`${block}`}
style={{
gridColumn: `${block.calendarGridPoint.dayIndex + 1}`,
gridRow: `${block.calendarGridPoint.startIndex + 1} / ${block.calendarGridPoint.endIndex + 1}`,
}}
>
<CalendarCourseCell
courseDeptAndInstr={block.componentProps.courseDeptAndInstr}
timeAndLocation={block.componentProps.timeAndLocation}
status={block.componentProps.status}
colors={block.componentProps.colors}
/>
</div>
))}
</div>
</div>
<div className={styles.buttonContainer}>
<div className={styles.divider} /> {/* First divider */}
<button className={styles.calendarButton}>
<img src={calIcon} className={styles.buttonIcon} alt='CAL' />
Save as .CAL
</button>
<div className={styles.divider} /> {/* Second divider */}
<button onClick={saveAsPNG} className={styles.calendarButton}>
<img src={pngIcon} className={styles.buttonIcon} alt='PNG' />
Save as .PNG
</button>
</div>
</div>
);
}
export default CalendarGrid;
/* <div className={styles.buttonContainer}>
<div className={styles.divider} />
<button className={styles.calendarButton}>
<img src={calIcon} className={styles.buttonIcon} alt='CAL' />
Save as .CAL
</button>
<div className={styles.divider} />
<button onClick={saveAsPNG} className={styles.calendarButton}>
<img src={pngIcon} className={styles.buttonIcon} alt='PNG' />
Save as .PNG
</button>
</div> */

View File

@@ -1,7 +1,7 @@
.calendarCell {
display: flex;
width: 213.8px;
height: 44.769px;
width: 100%;
height: 100%;
min-width: 45px;
min-height: 40px;
flex-direction: column;
@@ -11,8 +11,8 @@
}
.hourLine {
width: 213.8px;
width: 100%;
height: 1px;
border-radius: var(--border-radius-none, 0px);
border-radius: 0px;
background: rgba(218, 220, 224, 0.25);
}

View File

@@ -1,14 +1,20 @@
import React from 'react';
import styles from './CalendarGridCell.module.scss';
interface Props {
styleProp: any;
}
/**
* Component representing each 1 hour time block of a calendar
* @param props
*/
const CalendarCell: React.FC = props => (
<div className={styles.calendarCell}>
function CalendarCell({ styleProp }: Props): JSX.Element {
return (
<div className={styles.calendarCell} style={styleProp}>
<div className={styles.hourLine} />
</div>
);
}
export default CalendarCell;