diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e640a5306..379813352 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -9,6 +9,7 @@ import Landing from "@/app/Landing"; import Plan from "@/app/Plan"; import Schedule from "@/app/Schedule"; import Schedules from "@/app/Schedules"; +import Compare from "@/app/Schedules/Compare"; import AccountProvider from "@/components/AccountProvider"; import Layout from "@/components/Layout"; @@ -42,6 +43,10 @@ const router = createBrowserRouter([ element: , path: "schedules/:scheduleId", }, + { + element: , + path: "schedules/compare/:leftScheduleId?/:rightScheduleId?", + }, ], }, { diff --git a/frontend/src/app/Schedule/Calendar/Week/Day/index.tsx b/frontend/src/app/Schedule/Calendar/Week/Day/index.tsx index 96815d6e9..2e3c60e27 100644 --- a/frontend/src/app/Schedule/Calendar/Week/Day/index.tsx +++ b/frontend/src/app/Schedule/Calendar/Week/Day/index.tsx @@ -2,7 +2,7 @@ import classNames from "classnames"; import { getColor } from "@/lib/section"; -import { IDay } from "../../semester"; +import { IDay } from "../../calendar"; import styles from "./Day.module.scss"; const parseTime = (time: string) => { diff --git a/frontend/src/app/Schedule/Calendar/Week/index.tsx b/frontend/src/app/Schedule/Calendar/Week/index.tsx index e0a7ec3f6..3a5a3e437 100644 --- a/frontend/src/app/Schedule/Calendar/Week/index.tsx +++ b/frontend/src/app/Schedule/Calendar/Week/index.tsx @@ -2,7 +2,7 @@ import classNames from "classnames"; import { ArrowDown } from "iconoir-react"; import moment from "moment"; -import { IDay } from "../semester"; +import { IDay } from "../calendar"; import Day from "./Day"; import styles from "./Week.module.scss"; diff --git a/frontend/src/app/Schedule/Calendar/calendar.ts b/frontend/src/app/Schedule/Calendar/calendar.ts new file mode 100644 index 000000000..4fbd305c6 --- /dev/null +++ b/frontend/src/app/Schedule/Calendar/calendar.ts @@ -0,0 +1,16 @@ +export interface IEvent { + subject: string; + number: string; + active?: boolean; + startTime: string; + endTime: string; + startDate: string; + endDate: string; + days?: boolean[]; + date?: string; +} + +export interface IDay { + date: moment.Moment; + events: IEvent[]; +} diff --git a/frontend/src/app/Schedule/Calendar/index.tsx b/frontend/src/app/Schedule/Calendar/index.tsx index 7d89fec3c..444fa04f9 100644 --- a/frontend/src/app/Schedule/Calendar/index.tsx +++ b/frontend/src/app/Schedule/Calendar/index.tsx @@ -4,9 +4,9 @@ import moment from "moment"; import { ISection } from "@/lib/api"; -import styles from "./Semester.module.scss"; +import styles from "./Calendar.module.scss"; import Week from "./Week"; -import { IDay } from "./semester"; +import { IDay, IEvent } from "./calendar"; interface CalendarProps { selectedSections: ISection[]; @@ -17,12 +17,6 @@ export default function Calendar({ selectedSections, currentSection, }: CalendarProps) { - const sections = useMemo( - () => - currentSection ? [...selectedSections, currentSection] : selectedSections, - [selectedSections, currentSection] - ); - const [first] = useState(() => moment("2024-01-01")); const [last] = useState(() => moment("2024-05-31")); @@ -38,6 +32,56 @@ export default function Calendar({ return stop; }); + const events = useMemo( + () => + (currentSection + ? [...selectedSections, currentSection] + : selectedSections + ).reduce((events, section) => { + const { + startDate, + endDate, + meetings, + exams, + course: { subject, number }, + ccn, + } = section; + + for (const exam of exams) { + const { date, startTime, endTime } = exam; + + events.push({ + date, + subject: subject, + number: number, + active: currentSection?.ccn === ccn, + startTime, + endTime, + startDate, + endDate, + }); + } + + for (const meeting of meetings) { + const { days, startTime, endTime } = meeting; + + events.push({ + startDate, + endDate, + subject: subject, + number: number, + active: currentSection?.ccn === ccn, + days, + startTime, + endTime, + }); + } + + return events; + }, [] as IEvent[]), + [selectedSections, currentSection] + ); + const weeks = useMemo(() => { const weeks: IDay[][] = []; @@ -49,20 +93,14 @@ export default function Calendar({ for (let i = 0; i < 7; i++) { const day = { date: moment(current), - events: sections + events: events .filter( - ({ startDate, endDate, meetings }) => + ({ startDate, endDate, date, days }) => current.isSameOrAfter(startDate) && current.isSameOrBefore(endDate) && - meetings[0]?.days[current.day()] - ) - .sort((a, b) => - a.meetings[0].startTime.localeCompare(b.meetings[0].startTime) + (moment(date).isSame(current, "day") || days?.[current.day()]) ) - .map((section) => ({ - ...section, - active: section.ccn === currentSection?.ccn, - })), + .sort((a, b) => a.startTime.localeCompare(b.startTime)), }; week.push(day); @@ -74,7 +112,7 @@ export default function Calendar({ } return weeks; - }, [sections, currentSection, start, stop]); + }, [events, start, stop]); return (
diff --git a/frontend/src/app/Schedule/Calendar/semester.ts b/frontend/src/app/Schedule/Calendar/semester.ts deleted file mode 100644 index d156625d5..000000000 --- a/frontend/src/app/Schedule/Calendar/semester.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ISection } from "@/lib/api"; - -interface IEvent extends ISection { - active?: boolean; -} - -export interface IDay { - date: moment.Moment; - events: IEvent[]; -} diff --git a/frontend/src/app/Schedule/index.tsx b/frontend/src/app/Schedule/index.tsx index b66d2375f..4bb9f3340 100644 --- a/frontend/src/app/Schedule/index.tsx +++ b/frontend/src/app/Schedule/index.tsx @@ -1,17 +1,23 @@ import { useCallback, useRef, useState } from "react"; import { useApolloClient } from "@apollo/client"; -import { ArrowLeft, ShareIos } from "iconoir-react"; +import { + ArrowLeft, + Copy, + EditPencil, + ShareIos, + ViewColumns2, +} from "iconoir-react"; import Button from "@/components/Button"; import IconButton from "@/components/IconButton"; import MenuItem from "@/components/MenuItem"; +import Week from "@/components/Week"; import { GET_CLASS, IClass, ICourse, ISection } from "@/lib/api"; import { getY } from "@/lib/schedule"; import Calendar from "./Calendar"; import Map from "./Map"; -import Week from "./Schedule"; import styles from "./Schedule.module.scss"; import SideBar from "./SideBar"; @@ -28,6 +34,8 @@ export default function Schedule() { const [selectedSections, setSelectedSections] = useState([]); const [currentSection, setCurrentSection] = useState(null); + console.log(JSON.stringify(selectedSections)); + const handleSectionSelect = useCallback( (section: ISection) => { // Clear the current section @@ -177,6 +185,9 @@ export default function Schedule() {

Untitled Spring 2024 schedule

+ + +
@@ -190,6 +201,14 @@ export default function Schedule() { Map
+ +