fix: Calendar View/Scaling Issues (#144)

* fix: calendar looks normal now; scaling

* fix: array indexing

* chore: eslint

* chore: lint

* feat: team Links and scrolling
This commit is contained in:
Lukas Zenick
2024-03-11 23:34:38 -05:00
committed by GitHub
parent 591687eee8
commit 4c61ebd3fc
5 changed files with 123 additions and 30 deletions

View File

@@ -0,0 +1,8 @@
.scrollableSchedules {
overflow-y: auto; /* Enables vertical scrolling */
}
.scrollableLimit {
overflow-y: auto; /* Enables vertical scrolling */
max-height: 35vh; /* Adjusts based on your needs and testing */
}

View File

@@ -4,46 +4,82 @@ import CalendarGrid from '@views/components/calendar/CalendarGrid/CalendarGrid';
import CalendarHeader from '@views/components/calendar/CalendarHeader/CalenderHeader'; import CalendarHeader from '@views/components/calendar/CalendarHeader/CalenderHeader';
import { CalendarSchedules } from '@views/components/calendar/CalendarSchedules/CalendarSchedules'; import { CalendarSchedules } from '@views/components/calendar/CalendarSchedules/CalendarSchedules';
import ImportantLinks from '@views/components/calendar/ImportantLinks'; import ImportantLinks from '@views/components/calendar/ImportantLinks';
import TeamLinks from '@views/components/calendar/TeamLinks';
import Divider from '@views/components/common/Divider/Divider';
import CourseCatalogInjectedPopup from '@views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup'; import CourseCatalogInjectedPopup from '@views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup';
import { useFlattenedCourseSchedule } from '@views/hooks/useFlattenedCourseSchedule'; import { useFlattenedCourseSchedule } from '@views/hooks/useFlattenedCourseSchedule';
import React, { useRef } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { ExampleCourse } from 'src/stories/components/PopupCourseBlock.stories';
import styles from './Calendar.module.scss';
/** /**
* A reusable chip component that follows the design system of the extension. * A reusable chip component that follows the design system of the extension.
* @returns * @returns
*/ */
export default function Calendar(): JSX.Element { export default function Calendar(): JSX.Element {
const calendarRef = useRef(null); const calendarRef = useRef<HTMLDivElement>(null);
const { courseCells, activeSchedule } = useFlattenedCourseSchedule(); const { courseCells, activeSchedule } = useFlattenedCourseSchedule();
const [course, setCourse] = React.useState<Course | null>(null); const [course, setCourse] = useState<Course | null>(null);
const [sidebarWidth, setSidebarWidth] = useState('20%');
const [scale, setScale] = useState(1);
useEffect(() => {
const adjustLayout = () => {
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
const desiredCalendarHeight = 760;
const minSidebarWidthPixels = 230;
const scale = Math.min(1, windowHeight / desiredCalendarHeight);
const sidebarWidthPixels = Math.max(
windowWidth * scale - windowWidth + minSidebarWidthPixels,
minSidebarWidthPixels
);
const newSidebarWidth = `${(sidebarWidthPixels / windowWidth) * 100}%`;
setScale(scale);
setSidebarWidth(newSidebarWidth);
};
adjustLayout();
window.addEventListener('resize', adjustLayout);
return () => window.removeEventListener('resize', adjustLayout);
}, []);
const calendarContainerStyle = {
transform: `scale(${scale})`,
transformOrigin: 'top left',
marginTop: '-20px',
};
return ( return (
<div className='flex flex-col'> <div className='h-screen flex flex-col' style={{ width: 'calc(100% - 1rem)' }}>
<CalendarHeader <div className='pl-5'>
// TODO: implement props <CalendarHeader />
// totalHours={activeSchedule.hours} </div>
// scheduleName={activeSchedule.name} <div className={`flex flex-grow flex-row overflow-hidden pl-4 ${styles.scrollableSchedules}`}>
// totalCourses={activeSchedule?.courses.length} <div className='sidebar-style' style={{ width: sidebarWidth, padding: '10px 15px 5px 5px' }}>
/> <div className={`mb-4 ${styles.scrollableLimit}`}>
<div className='h-screen w-full flex flex-col md:flex-row'>
<div className='min-h-[30%] flex flex-col items-start gap-2.5 p-5 pl-7'>
<div className='min-h-[30%]'>
<CalendarSchedules /> <CalendarSchedules />
</div> </div>
<Divider orientation='horizontal' size='100%' />
<div className='mt-4'>
<ImportantLinks /> <ImportantLinks />
</div> </div>
<div className='flex flex-grow flex-col gap-4 overflow-hidden pr-12'> <Divider orientation='horizontal' size='100%' />
<div ref={calendarRef} className='flex-grow overflow-auto'> <div className='mt-4'>
<TeamLinks />
</div>
</div>
<div className='flex flex-grow flex-col' style={calendarContainerStyle} ref={calendarRef}>
<div className='flex-grow overflow-auto'>
<CalendarGrid courseCells={courseCells} setCourse={setCourse} /> <CalendarGrid courseCells={courseCells} setCourse={setCourse} />
</div> </div>
<div>
<CalendarBottomBar calendarRef={calendarRef} /> <CalendarBottomBar calendarRef={calendarRef} />
</div> </div>
</div> </div>
</div>
{/* TODO: Doesn't work when exampleCourse is replaced with an actual course through setCourse.
Check CalendarGrid.tsx and AccountForCourseConflicts for an example */}
{course ? ( {course ? (
<CourseCatalogInjectedPopup <CourseCatalogInjectedPopup
course={course} course={course}

View File

@@ -4,7 +4,7 @@ import { getCourseColors } from '@shared/util/colors';
import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell'; import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell/CalendarCourseCell';
import CalendarCell from '@views/components/calendar/CalendarGridCell/CalendarGridCell'; import CalendarCell from '@views/components/calendar/CalendarGridCell/CalendarGridCell';
import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule'; import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule';
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import styles from './CalendarGrid.module.scss'; import styles from './CalendarGrid.module.scss';
@@ -26,12 +26,10 @@ export default function CalendarGrid({
saturdayClass, saturdayClass,
setCourse, setCourse,
}: React.PropsWithChildren<Props>): JSX.Element { }: React.PropsWithChildren<Props>): JSX.Element {
// const [grid, setGrid] = useState([]); const [grid, setGrid] = useState([]);
// const calendarRef = useRef(null); // Create a ref for the calendar grid
const grid = [];
// Run once to create the grid on initial render
useEffect(() => { useEffect(() => {
const newGrid = [];
for (let i = 0; i < 13; i++) { for (let i = 0; i < 13; i++) {
const row = []; const row = [];
let hour = hoursOfDay[i]; let hour = hoursOfDay[i];
@@ -53,9 +51,10 @@ export default function CalendarGrid({
}; };
row.push(<CalendarCell key={k} styleProp={styleProp} />); row.push(<CalendarCell key={k} styleProp={styleProp} />);
} }
grid.push(row); newGrid.push(row);
} }
}); setGrid(newGrid);
}, []);
return ( return (
<div className={styles.calendarGrid}> <div className={styles.calendarGrid}>

View File

@@ -28,7 +28,7 @@ const handleOpenOptions = async (): Promise<void> => {
*/ */
export default function CalendarHeader(): JSX.Element { export default function CalendarHeader(): JSX.Element {
return ( return (
<div className='min-h-79px min-w-672px w-full flex px-0 py-15'> <div className='min-h-79px min-w-672px w-full flex px-0 py-5'>
<div className='flex flex-row gap-20'> <div className='flex flex-row gap-20'>
<div className='flex gap-10'> <div className='flex gap-10'>
<div className='flex gap-1'> <div className='flex gap-1'>

View File

@@ -0,0 +1,50 @@
import Text from '@views/components/common/Text/Text';
import clsx from 'clsx';
import React from 'react';
import OutwardArrowIcon from '~icons/material-symbols/arrow-outward';
type Props = {
className?: string;
};
/**
* The "From The Team" section of the calendar website
* @returns
*/
export default function TeamLinks({ className }: Props): JSX.Element {
return (
<article className={clsx(className, 'flex flex-col gap-2')}>
<Text variant='h3'>From The Team</Text>
<a
href='options.html'
className='flex items-center gap-0.5 text-ut-burntorange'
target='_blank'
rel='noreferrer'
>
<Text variant='p'>Credits Meet the team!</Text>
<OutwardArrowIcon className='h-3 w-3' />
</a>
{/* TODO: ADD THE LINK HERE */}
<a
href='application-link'
className='flex items-center gap-0.5 text-ut-burntorange'
target='_blank'
rel='noreferrer'
>
<Text variant='p'>Apply to Longhorn Developers</Text>
<OutwardArrowIcon className='h-3 w-3' />
</a>
{/* TODO: ADD THE LINK HERE */}
<a
href='beta_tester-link'
className='flex items-center gap-0.5 text-ut-burntorange'
target='_blank'
rel='noreferrer'
>
<Text variant='p'>Become a Beta Tester</Text>
<OutwardArrowIcon className='h-3 w-3' />
</a>
</article>
);
}