Skip to content

Commit

Permalink
setCourse and calendar header need work
Browse files Browse the repository at this point in the history
  • Loading branch information
knownotunknown committed Feb 24, 2024
1 parent f61ae9c commit d14a31c
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 71 deletions.
2 changes: 1 addition & 1 deletion src/pages/background/lib/createSchedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default async function createSchedule(scheduleName: string): Promise<stri
schedules.push({
name: scheduleName,
courses: [],
hours: 0
hours: 0,
});

await UserScheduleStore.set('schedules', schedules);
Expand Down
8 changes: 4 additions & 4 deletions src/stories/components/calendar/CalendarGrid.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const exampleSchedule = new UserSchedule({
hours: 3,
} as Serialized<UserSchedule>);

export const exampleCalendarGridCourses: CalendarGridCourse[] = [
/* export const exampleCalendarGridCourses: CalendarGridCourse[] = [
{
calendarGridPoint: {
dayIndex: 4,
Expand Down Expand Up @@ -166,13 +166,13 @@ export const exampleCalendarGridCourses: CalendarGridCourse[] = [
colors: getCourseColors('emerald', 500),
},
},
];
]; */

type Story = StoryObj<typeof meta>;

export const Default: Story = {
/* export const Default: Story = {
args: {
saturdayClass: true,
courseCells: exampleCalendarGridCourses,
},
};
}; */
14 changes: 9 additions & 5 deletions src/views/components/PopupMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import List from './common/List/List'; // Ensure this path is correctly pointing
import useSchedules from '../hooks/useSchedules';
import { handleOpenCalendar } from './injected/CourseCatalogInjectedPopup/HeadingAndActions';
import { openTabFromContentScript } from '../lib/openNewTabFromContentScript';
import { act } from 'react-dom/test-utils';


/**
Expand All @@ -26,8 +27,11 @@ export const handleOpenOptions = async () => { // Not sure if it's bad practice
* Chrome extension main popup (when you click extension icon)
*/
export default function PopupMain() {
const [activeSchedule] = useSchedules();

const [activeSchedule, schedules] = useSchedules();
const coursesLength = activeSchedule ? activeSchedule.courses.length : 0;
if (!activeSchedule) {
return;
}

const draggableElements = activeSchedule?.courses.map((course, i) => (
<PopupCourseBlock
Expand Down Expand Up @@ -62,10 +66,10 @@ export default function PopupMain() {
</div>
<Divider color="#E2E8F0" type="solid" style={{ margin: '1rem 0' }} />
<div className="mb-4 rounded-lg bg-white p-2 text-left shadow-inner" style={{ backgroundColor: 'white', border: '1px solid #FBD38D', borderRadius: '0.5rem' }}>
<Text as="div" variant="h2-course" style={{ color: '#DD6B20', fontSize: '1.2rem' }}>MAIN SCHEDULE:</Text>
<Text as="div" variant="h2-course" style={{ color: '#DD6B20', fontSize: '1.2rem' }}>{`${activeSchedule.name}`}:</Text>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'start', color: '#333f48' }}>
<Text as="div" variant="h1" style={{ fontSize: '1.2rem', fontWeight: 'bold', marginRight: '0.5rem' }}>22 HOURS</Text>
<Text as="div" variant="h2-course" style={{ fontSize: '1.2rem' }}>8 Courses</Text>
<Text as="div" variant="h1" style={{ fontSize: '1.2rem', fontWeight: 'bold', marginRight: '0.5rem' }}>{`${activeSchedule.hours} HOURS`}</Text>
<Text as="div" variant="h2-course" style={{ fontSize: '1.2rem' }}>{`${coursesLength} HOURS`}</Text>
</div>
</div>
{/* Integrate the List component here */}
Expand Down
22 changes: 13 additions & 9 deletions src/views/components/calendar/Calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { Course } from 'src/shared/types/Course';
import { exampleCourse } from 'src/stories/components/PopupCourseBlock.stories';
import CalendarHeader from 'src/views/components/calendar/CalendarHeader/CalenderHeader';
import { useFlattenedCourseSchedule } from 'src/views/hooks/useFlattenedCourseSchedule';
import { UserSchedule } from 'src/shared/types/UserSchedule';
import CourseCatalogInjectedPopup from '../../injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup';
import { CalendarBottomBar } from '../CalendarBottomBar/CalendarBottomBar';
import CalendarGrid from '../CalendarGrid/CalendarGrid';
import { CalendarSchedules } from '../CalendarSchedules/CalendarSchedules';
import ImportantLinks from '../ImportantLinks';


export const flags = ['WR', 'QR', 'GC', 'CD', 'E', 'II'];

interface Props {
Expand All @@ -20,29 +22,31 @@ interface Props {
* @returns
*/
export function Calendar(): JSX.Element {
const courseCells = useFlattenedCourseSchedule();
const [showPopup, setShowPopup] = React.useState<boolean>(false);
console.log(courseCells);
const { courseCells, activeSchedule } = useFlattenedCourseSchedule();
const [course, setCourse] = React.useState<Course | null>(null);

return (
<>
<CalendarHeader />
<div className = 'flex flex-col'>
<CalendarHeader totalHours={activeSchedule.hours} scheduleName={activeSchedule.name} totalCourses={activeSchedule?.courses.length}/>
<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 />
</div>
<ImportantLinks />
</div>
<div className='flex flex-grow flex-col gap-4 overflow-hidden'>
<div className='flex flex-grow flex-col gap-4 overflow-hidden pr-12'>
<div className='flex-grow overflow-auto'>
<CalendarGrid courseCells = {courseCells} setShowPopup={setShowPopup}/>
<CalendarGrid courseCells = {courseCells} setCourse={setCourse}/>
</div>
<div>
<CalendarBottomBar />
</div>
</div>
</div>
{showPopup ? <CourseCatalogInjectedPopup course = {exampleCourse } onClose={() => setShowPopup(false)}/> : null}
</>
{/* TODO: Doesn't work when exampleCourse is replaced with an actual course through setCourse.
Check CalendarGrid.tsx and AccountForCourseConflicts for an example */}
{course ? <CourseCatalogInjectedPopup course = {exampleCourse} activeSchedule = {activeSchedule} onClose={() => setCourse(null)}/> : null}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface CalendarCourseCellProps {
status: Status;
colors: CourseColors;
className?: string;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
onClick?: React.MouseEventHandler<HTMLDivElement>;
}

const CalendarCourseCell: React.FC<CalendarCourseCellProps> = ({
Expand All @@ -38,10 +38,11 @@ const CalendarCourseCell: React.FC<CalendarCourseCellProps> = ({

return (
<div
className={clsx('h-full w-full flex justify-center rounded p-2 overflow-x-hidden', fontColor, className)}
className={clsx('h-full w-full flex justify-center rounded p-2 overflow-x-hidden cursor-default hover:cursor-pointer', fontColor, className)}
style={{
backgroundColor: colors.primaryColor,
}}
onClick={onClick}
>
<div className='flex flex-1 flex-col gap-1'>
<Text
Expand Down
22 changes: 12 additions & 10 deletions src/views/components/calendar/CalendarGrid/CalendarGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,30 @@ import { CalendarGridCourse } from 'src/views/hooks/useFlattenedCourseSchedule';
/* import calIcon from 'src/assets/icons/cal.svg';
import pngIcon from 'src/assets/icons/png.svg';
*/
import { Course } from 'src/shared/types/Course';
import { getCourseColors } from 'src/shared/util/colors';
import CalendarCell from '../CalendarGridCell/CalendarGridCell';
import CalendarCourseCell from '../CalendarCourseCell/CalendarCourseCell';
import styles from './CalendarGrid.module.scss';


interface Props {
courseCells?: CalendarGridCourse[];
saturdayClass?: boolean;
setShowPopup: React.Dispatch<React.SetStateAction<boolean>>;
setCourse: React.Dispatch<React.SetStateAction<Course | null>>;
}

/**
* Grid of CalendarGridCell components forming the user's course schedule calendar view
* @param props
*/
function CalendarGrid({ courseCells, saturdayClass, setShowPopup }: React.PropsWithChildren<Props>): JSX.Element {
function CalendarGrid({ courseCells, saturdayClass, setCourse }: React.PropsWithChildren<Props>): JSX.Element {
// 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);
console.log(courseCells);

/* const saveAsPNG = () => {
htmlToImage
.toPng(calendarRef.current, {
Expand Down Expand Up @@ -85,7 +87,6 @@ function CalendarGrid({ courseCells, saturdayClass, setShowPopup }: React.PropsW
}
grid.push(row);
}
// setGrid(newGrid);


return (
Expand All @@ -98,7 +99,7 @@ function CalendarGrid({ courseCells, saturdayClass, setShowPopup }: React.PropsW
</div>
))}
{grid.map((row, rowIndex) => row)}
{courseCells ? <AccountForCourseConflicts courseCells={courseCells} setShowPopup={setShowPopup}/> : null}
{courseCells ? <AccountForCourseConflicts courseCells={courseCells} setCourse={setCourse}/> : null}
</div>
);
}
Expand All @@ -107,10 +108,10 @@ export default CalendarGrid;

interface AccountForCourseConflictsProps {
courseCells: CalendarGridCourse[];
setShowPopup: React.Dispatch<React.SetStateAction<boolean>>;
setCourse: React.Dispatch<React.SetStateAction<Course | null>>;
}

function AccountForCourseConflicts({ courseCells, setShowPopup }: AccountForCourseConflictsProps): JSX.Element[] {
function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseConflictsProps): JSX.Element[] {
// Groups by dayIndex to identify overlaps
const days = courseCells.reduce((acc, cell: CalendarGridCourse) => {
const { dayIndex } = cell.calendarGridPoint;
Expand All @@ -136,11 +137,9 @@ function AccountForCourseConflicts({ courseCells, setShowPopup }: AccountForCour
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;
}
Expand All @@ -151,6 +150,9 @@ function AccountForCourseConflicts({ courseCells, setShowPopup }: AccountForCour
});
});

// Part of TODO: block.course is definitely a course object
console.log(courseCells);

return courseCells.map(block => (
<div
key={`${block}`}
Expand All @@ -167,7 +169,7 @@ function AccountForCourseConflicts({ courseCells, setShowPopup }: AccountForCour
timeAndLocation={block.componentProps.timeAndLocation}
status={block.componentProps.status}
colors={getCourseColors('emerald', 500) /* block.componentProps.colors */}
onClick={() => setShowPopup(true)}
onClick={() => setCourse(block.course)}
/>
</div>
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import ScheduleTotalHoursAndCourses from '../../common/ScheduleTotalHoursAndCour
import Text from '../../common/Text/Text';
import { handleOpenOptions } from '../../PopupMain';

const CalendarHeader = () => (
<div className='min-h-79px min-w-672px flex px-0 py-15'>
const CalendarHeader = ( { totalHours, totalCourses, scheduleName } ) => (
<div className='min-h-79px min-w-672px w-full flex px-0 py-15'>
<div className='flex flex-row gap-20'>
<div className='flex gap-10'>
<div className='flex gap-1'>
Expand All @@ -32,7 +32,7 @@ const CalendarHeader = () => (
</div>
</div>
<div className='flex flex-col'>
<ScheduleTotalHoursAndCourses scheduleName='SCHEDULE' totalHours={22} totalCourses={8} />
<ScheduleTotalHoursAndCourses scheduleName={scheduleName} totalHours={totalHours} totalCourses={totalCourses} />
DATA UPDATED ON: 12:00 AM 02/01/2024
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { UserSchedule } from '@shared/types/UserSchedule';
import React, { useState } from 'react';

import React, { useState, useEffect } from 'react';
import useSchedules from 'src/views/hooks/useSchedules';
import createSchedule from 'src/pages/background/lib/createSchedule';
import AddSchedule from '~icons/material-symbols/add';

import List from '../../common/List/List';
import ScheduleListItem from '../../common/ScheduleListItem/ScheduleListItem';
import Text from '../../common/Text/Text';
import switchSchedule from 'src/pages/background/lib/switchSchedule';

export type Props = {
style?: React.CSSProperties;
Expand All @@ -14,12 +15,42 @@ export type Props = {
};

export function CalendarSchedules(props: Props) {
const [activeScheduleIndex, setActiveScheduleIndex] = useState(props.dummyActiveIndex || 0);
const [schedules, setSchedules] = useState(props.dummySchedules || []);
const [activeScheduleIndex, setActiveScheduleIndex] = useState(0);
const [newSchedule, setNewSchedule] = useState('');
const [activeSchedule, schedules] = useSchedules();

useEffect(() => {
const index = schedules.findIndex(schedule => schedule.name === activeSchedule.name);
if (index !== -1) {
setActiveScheduleIndex(index);
}
}, [activeSchedule, schedules]);

const handleKeyDown = (event) => {
if (event.code === 'Enter') {
createSchedule(newSchedule);
setNewSchedule('');
}
};

const scheduleComponents = schedules.map((schedule, index) => (
<ScheduleListItem active={index === activeScheduleIndex} name={schedule.name} />
));
const handleScheduleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setNewSchedule(e.target.value);
};

const selectItem = (index: number) => {
setActiveScheduleIndex(index);
switchSchedule(schedules[index].name);
};

const scheduleComponents = schedules.map((schedule, index) => {
return (
<ScheduleListItem
active={index === activeScheduleIndex}
name={schedule.name}
onClick={() => selectItem(index)}
/>
);
});

return (
<div style={{ ...props.style }} className='items-center'>
Expand All @@ -31,8 +62,11 @@ export function CalendarSchedules(props: Props) {
</Text>
</div>
</div>

<List gap={10} draggableElements={scheduleComponents} itemHeight={30} listHeight={30} listWidth={240} />
<div className="flex flex-col space-y-2.5">
<List gap={10} draggableElements={scheduleComponents} itemHeight={30} listHeight={30} listWidth={240} />
<input type="text" placeholder='Enter new schedule' value={newSchedule}
onChange={handleScheduleInputChange} onKeyDown={handleKeyDown}/>
</div>
</div>
);
}
11 changes: 7 additions & 4 deletions src/views/components/common/List/List.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd';
import React, { ReactElement, useCallback, useState } from 'react';
import React, { ReactElement, useCallback, useState, useEffect } from 'react';
import { areEqual } from 'react-window';

/*
Expand Down Expand Up @@ -84,7 +84,11 @@ const Row: React.FC<RowProps> = React.memo(({ data: { items, gap }, index, style
*/
const List: React.FC<ListProps> = ({ draggableElements, itemHeight, listHeight, listWidth, gap = 12 }: ListProps) => {
const [items, setItems] = useState(() => initial(draggableElements));


useEffect(() => {
setItems(initial(draggableElements));
}, [draggableElements]);

const onDragEnd = useCallback(
result => {
if (!result.destination) {
Expand Down Expand Up @@ -113,8 +117,7 @@ const List: React.FC<ListProps> = ({ draggableElements, itemHeight, listHeight,
const transform = style?.transform;

if (snapshot.isDragging && transform) {
console.log(transform);
let [, _x, y] = transform.match(/translate\(([-\d]+)px, ([-\d]+)px\)/) || [];
let [, , y] = transform.match(/translate\(([-\d]+)px, ([-\d]+)px\)/) || [];

style.transform = `translate3d(0px, ${y}px, 0px)`; // Apply constrained y value
}
Expand Down
Loading

0 comments on commit d14a31c

Please sign in to comment.