Skip to content

Commit

Permalink
completed multi-layer prerequisite displaying
Browse files Browse the repository at this point in the history
  • Loading branch information
aeluro1 committed Apr 7, 2024
1 parent 1a71fd5 commit 042559d
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 175 deletions.
5 changes: 1 addition & 4 deletions src/components/ComparisonContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export default function ComparisonContainer({
const [editInfo, setEditInfo] = useState<EditInfo>(null);
const [editValue, setEditValue] = useState('');
const [paletteInfo, setPaletteInfo] = useState<string>();
const [scheduleSelected, setScheduleSelected] = useState(pinSelf);
const [invitationModalOpen, setInvitationModalOpen] = useState(false);
const [invitationModalEmail, setInvitationModalEmail] = useState('');

Expand Down Expand Up @@ -118,7 +117,7 @@ export default function ComparisonContainer({
if (Object.keys(newColorMap).length !== Object.keys(colorMap).length) {
patchSchedule({ colorMap: newColorMap });
}
}, [friends, currentVersion, colorMap, patchSchedule]);
}, [friends, currentVersion, colorMap, patchSchedule, allVersionNames]);

const handleEdit = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -248,8 +247,6 @@ export default function ComparisonContainer({

const handleToggleSchedule = useCallback(
(id: string) => {
console.log(selected);
console.log(id);
if (selected.includes(id)) {
setSelected(selected.filter((selectedId: string) => selectedId !== id));
handleCompareSchedules(
Expand Down
75 changes: 16 additions & 59 deletions src/components/Course/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import {
faAngleDown,
faAngleUp,
faShareAlt,
faPalette,
faPlus,
faTrash,
} from '@fortawesome/free-solid-svg-icons';
import _ from 'lodash';

import { classes, getContentClassName } from '../../utils/misc';
import Cancellable from '../../utils/cancellable';
Expand All @@ -22,6 +14,7 @@ import { ScheduleContext } from '../../contexts';
import { Course as CourseBean, Section } from '../../data/beans';
import { CourseGpa } from '../../types';
import { ErrorWithFields, softError } from '../../log';
import usePrereqControl from '../../hooks/usePrereqControl';

import './stylesheet.scss';

Expand All @@ -36,8 +29,6 @@ export default function Course({
courseId,
onAddCourse,
}: CourseProps): React.ReactElement | null {
const [expanded, setExpanded] = useState<boolean>(false);
const [prereqOpen, setPrereqOpen] = useState<boolean>(false);
const [paletteShown, setPaletteShown] = useState<boolean>(false);
const [gpaMap, setGpaMap] = useState<CourseGpa | null>(null);
const isSearching = Boolean(onAddCourse);
Expand All @@ -46,8 +37,12 @@ export default function Course({
{ patchSchedule },
] = useContext(ScheduleContext);

const course = oscar.findCourse(courseId);

const { prereqAction, prereqControl, expanded, prereqOpen } =
usePrereqControl(course?.id ?? '');

useEffect(() => {
const course = oscar.findCourse(courseId);
if (course == null) return;
if (isSearching) return;

Expand Down Expand Up @@ -79,9 +74,10 @@ export default function Course({
return (): void => {
loadOperation.cancel();
};
}, [isSearching, oscar, courseId]);
}, [isSearching, oscar, courseId, course]);

const handleRemoveCourse = useCallback(
// eslint-disable-next-line no-shadow
(course: CourseBean) => {
const newColorMap = { ...colorMap };
delete newColorMap[course.id];
Expand Down Expand Up @@ -110,31 +106,7 @@ export default function Course({
[excludedCrns, patchSchedule]
);

/**
* Returns whether all section prerequisites are equal
* @returns {boolean} whether section prerequisites are equal
*/
const allSectionPrereqsSame = useCallback((course: CourseBean): boolean => {
const basisPrereqs = course.sections?.[0]?.prereqs;
if (!basisPrereqs) {
return false;
}

for (let i = 1; i < course.sections.length; i++) {
if (!_.isEqual(basisPrereqs, course.sections[i]?.prereqs)) {
return false;
}
}
return true;
}, []);

const areSectionPrereqsDiff = useMemo(() => {
const course = oscar.findCourse(courseId);
return course ? !allSectionPrereqsSame(course) : false;
}, [courseId, allSectionPrereqsSame, oscar]);

const course = oscar.findCourse(courseId);
if (course == null) return null;
if (!course) return null;

const color = colorMap[course.id];
const contentClassName = color != null && getContentClassName(color);
Expand All @@ -158,23 +130,6 @@ export default function Course({
(instructor) => !excludedInstructors.includes(instructor)
);

const prereqControl = (
nextPrereqOpen: boolean,
nextExpanded: boolean
): void => {
setPrereqOpen(nextPrereqOpen);
setExpanded(nextExpanded);
};
const prereqAction = {
icon: faShareAlt,
styling: { transform: 'rotate(90deg)' },
onClick: (): void => {
prereqControl(true, !prereqOpen ? true : !expanded);
},
tooltip: 'View Prerequisites',
id: `${course.id}-prerequisites`,
};

const pinnedSections = course.sections.filter((section) =>
pinnedCrns.includes(section.crn)
);
Expand All @@ -183,6 +138,8 @@ export default function Course({
0
);

const areSectionPrereqsSame = course.prereqDepth === 0;

return (
<div
className={classes('Course', contentClassName, 'default', className)}
Expand All @@ -198,14 +155,14 @@ export default function Course({
isSearching
? [
{ icon: faPlus, onClick: onAddCourse },
...(areSectionPrereqsDiff ? [] : [prereqAction]),
...(areSectionPrereqsSame ? [prereqAction] : []),
]
: [
{
icon: expanded ? faAngleUp : faAngleDown,
onClick: (): void => prereqControl(false, !expanded),
},
...(areSectionPrereqsDiff ? [] : [prereqAction]),
...(areSectionPrereqsSame ? [prereqAction] : []),
{
icon: faPalette,
onClick: (): void => setPaletteShown(!paletteShown),
Expand Down Expand Up @@ -273,7 +230,7 @@ export default function Course({
? instructorGpa.toFixed(2)
: 'N/A'
}
areSectionPrereqsDiff={areSectionPrereqsDiff}
prereqDepth={course.prereqDepth}
/>
);
})}
Expand All @@ -296,7 +253,7 @@ export default function Course({
)}
</div>
)}
{expanded && prereqOpen && !areSectionPrereqsDiff && (
{expanded && prereqOpen && areSectionPrereqsSame && (
<Prerequisite
parent={course}
prereqs={course.sections?.[0]?.prereqs ?? []}
Expand Down
36 changes: 12 additions & 24 deletions src/components/Instructor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useCallback, useContext, useId, useState } from 'react';
import React, { useCallback, useContext, useId } from 'react';
import {
faAngleDown,
faAngleUp,
faBan,
faGraduationCap,
faShareAlt,
} from '@fortawesome/free-solid-svg-icons';

import { classes, simplifyName, unique } from '../../utils/misc';
import { Section as SectionBean } from '../../data/beans';
import { ActionRow, Prerequisite, Section } from '..';
import { ScheduleContext } from '../../contexts';
import usePrereqControl from '../../hooks/usePrereqControl';

import './stylesheet.scss';

Expand All @@ -20,7 +20,7 @@ export type InstructorProps = {
name: string;
sections: SectionBean[];
gpa: string;
areSectionPrereqsDiff: boolean;
prereqDepth: number;
};

export default function Instructor({
Expand All @@ -29,29 +29,13 @@ export default function Instructor({
name,
sections,
gpa,
areSectionPrereqsDiff,
prereqDepth,
}: InstructorProps): React.ReactElement {
const [{ pinnedCrns, excludedCrns }, { patchSchedule }] =
useContext(ScheduleContext);
const [expanded, setExpanded] = useState(true);
const [prereqOpen, setPrereqOpen] = useState<boolean>(false);

const prereqControl = (
nextPrereqOpen: boolean,
nextExpanded: boolean
): void => {
setPrereqOpen(nextPrereqOpen);
setExpanded(nextExpanded);
};
const prereqAction = {
icon: faShareAlt,
styling: { transform: 'rotate(90deg)' },
onClick: (): void => {
prereqControl(true, !prereqOpen ? true : !expanded);
},
tooltip: 'View Prerequisites',
id: `${name}-prerequisites`,
};
const { prereqAction, prereqControl, expanded, prereqOpen } =
usePrereqControl(name);

const includeSection = useCallback(
(section: SectionBean) => {
Expand Down Expand Up @@ -85,6 +69,9 @@ export default function Instructor({
);

const excludeTooltipId = useId();

const areProfPrereqsSame = prereqDepth === 1;

return (
<div
className={classes(
Expand All @@ -100,7 +87,7 @@ export default function Instructor({
icon: expanded ? faAngleUp : faAngleDown,
onClick: (): void => prereqControl(false, !expanded),
},
...(areSectionPrereqsDiff ? [prereqAction] : []),
...(areProfPrereqsSame ? [prereqAction] : []),
!['TBA', 'Not Assigned'].includes(name)
? {
icon: faGraduationCap,
Expand Down Expand Up @@ -135,6 +122,7 @@ export default function Instructor({
section={section}
color={color}
pinned={pinned}
prereqDepth={prereqDepth}
/>
);
})}
Expand All @@ -153,7 +141,7 @@ export default function Instructor({
)}
</div>
)}
{expanded && prereqOpen && areSectionPrereqsDiff && sections?.[0] && (
{expanded && prereqOpen && areProfPrereqsSame && sections?.[0] && (
<Prerequisite
parent={sections[0]}
prereqs={sections?.[0]?.prereqs ?? []}
Expand Down
Loading

0 comments on commit 042559d

Please sign in to comment.