diff --git a/README.md b/README.md index ea37e1e09..0810536e8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ GraduateNU aims to empower Northeastern students to customize their plan of stud 5. Then run the new version of the application by running `yarn dev` at the root of the project. This starts up a NestJS server + a NextJS frontend + a Proxy. The proxy listens on port [3002](http://localhost:3002/), forwards /api requests to the NestJS server running on port 3001, and all other requests to the frontend running on port 3000. +5a. For Windows machines, run `yarn concurrently "yarn workspaces foreach --parallel --verbose --interlaced run dev" "yarn dev:proxy"` instead of `yarn dev` + 6. Visit [http://localhost:3002](http://localhost:3002/) to view the app. To run the two separately, visit the frontend and api packages(sub directories of the monorepo). diff --git a/packages/common/src/major2-validation.ts b/packages/common/src/major2-validation.ts index f632d9db9..ec79abb82 100644 --- a/packages/common/src/major2-validation.ts +++ b/packages/common/src/major2-validation.ts @@ -66,6 +66,7 @@ type CourseError = { type: typeof MajorValidationErrorType.Course; requiredCourse: string; }; + export const CourseError = (c: IRequiredCourse): CourseError => ({ type: MajorValidationErrorType.Course, requiredCourse: courseToString(c), diff --git a/packages/common/src/test.js b/packages/common/src/test.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 4cbee12fa..79d200119 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -181,7 +181,6 @@ export type Requirement2 = | ICourseRange2 | IRequiredCourse | Section; - /** * Represents a requirement where X number of credits need to be completed from * a list of courses. diff --git a/packages/frontend/components/AddCourseModal/AddCourseModal.tsx b/packages/frontend/components/AddCourseModal/AddCourseModal.tsx index bf748519a..df7859e93 100644 --- a/packages/frontend/components/AddCourseModal/AddCourseModal.tsx +++ b/packages/frontend/components/AddCourseModal/AddCourseModal.tsx @@ -13,7 +13,7 @@ import { Text, VStack, } from "@chakra-ui/react"; -import { NUPathEnum, ScheduleCourse2 } from "@graduate/common"; +import { NUPathEnum, ScheduleCourse2, SeasonEnum } from "@graduate/common"; import { useState } from "react"; import { useSearchCourses } from "../../hooks"; import { @@ -33,6 +33,7 @@ import { SecondaryButton } from "../Button"; interface AddCourseModalProps { isOpen: boolean; catalogYear?: number; + season: SeasonEnum; addTo: string; /** Function to close the modal UX, returned from the useDisclosure chakra hook */ closeModalDisplay: () => void; @@ -50,6 +51,7 @@ interface AddCourseModalProps { export const AddCourseModal: React.FC = ({ isOpen, catalogYear, + season, addTo, closeModalDisplay, isCourseAlreadyAdded, @@ -227,6 +229,8 @@ export const AddCourseModal: React.FC = ({ (course) => ( = ({ } return ( - + {nuPaths.map((nuPath) => ( ; + year: number | undefined; + season: SeasonEnum; addSelectedCourse: (course: ScheduleCourse2) => Promise; isResultAlreadySelected: boolean; isResultAlreadyAdded: boolean; @@ -17,6 +20,8 @@ interface SearchResultProps { export const SearchResult: React.FC = ({ course, + year, + season, addSelectedCourse, isResultAlreadySelected, isResultAlreadyAdded, @@ -48,6 +53,26 @@ export const SearchResult: React.FC = ({ {course.name} + + + } + color="primary.blue.light.main" + border={0} + colorScheme="primary.blue.light.main" + isRound + size="sm" + pr={1} + isLoading={isSelectingAnotherCourse} + isDisabled={isResultAlreadyAdded || isResultAlreadySelected} + alignSelf="center" + /> + = ({ = ({ ))} void; + year: number; } export const TransferCourses: React.FC = ({ isExpanded, toggleExpanded, + year, }) => { const { student, isLoading, mutateStudent } = useStudentWithPlans(); const router = useRouter(); @@ -86,11 +88,13 @@ export const TransferCourses: React.FC = ({ isExpanded={isExpanded} toggleExpanded={toggleExpanded} totalTransferCredits={totalTransferCredits} + year={year} /> {isExpanded && ( )} @@ -102,11 +106,13 @@ interface TransferCoursesBodyProps { updateTransferCourses: ( updateTransferCourses: ScheduleCourse2[] ) => void; + year: number; } const TransferCoursesBody: React.FC = ({ transferCourses, updateTransferCourses, + year, }) => { const { isOpen, onOpen, onClose } = useDisclosure(); @@ -145,6 +151,9 @@ const TransferCoursesBody: React.FC = ({ ))} { return
; }; + +export function getSearchLink( + catalogYear: number, + szn: SeasonEnum, + course: ScheduleCourse2 +): string { + let sznInt = -1; + switch (szn) { + case SeasonEnum.FL: + sznInt = 1; + break; + case SeasonEnum.SP: + sznInt = 3; + break; + case SeasonEnum.S1: + sznInt = 4; + break; + case SeasonEnum.SM: + sznInt = 5; + break; + case SeasonEnum.S2: + sznInt = 6; + break; + default: + sznInt = 1; + } + return `https://searchneu.com/NEU/${catalogYear}${sznInt}${0}/search/${ + course.name + }`; +} diff --git a/packages/frontend/components/Sidebar/NUPathSection.tsx b/packages/frontend/components/Sidebar/NUPathSection.tsx index 019015369..1d1e05c76 100644 --- a/packages/frontend/components/Sidebar/NUPathSection.tsx +++ b/packages/frontend/components/Sidebar/NUPathSection.tsx @@ -62,6 +62,11 @@ const NUPathSection: React.FC = ({ if (loading) { validationStatus = SidebarValidationStatus.Loading; + } else if ( + Object.keys(nupathMap).length > 0 && + Object.keys(nupathMap).length < 13 + ) { + validationStatus = SidebarValidationStatus.InProgress; } else if (Object.keys(nupathMap).length === 13 && wiCount >= 2) { // Sidebar is complete if all 13 nupaths have been fulfilled (including 2 writing intensives) validationStatus = SidebarValidationStatus.Complete; @@ -105,11 +110,15 @@ const NUPathSection: React.FC = ({ ? green : validationStatus === SidebarValidationStatus.Error ? grey + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : "transparent" } borderColor={ validationStatus === SidebarValidationStatus.Complete ? green + : validationStatus === SidebarValidationStatus.InProgress + ? "orange" : grey } color={ @@ -130,7 +139,7 @@ const NUPathSection: React.FC = ({ p="xs" > {/* - The following three icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). + The following four icons appear and disappear based on opacity to allow for transitions (if they're conditionally rendered, then transitions can't occur). */} = ({ transition="opacity 0.25s ease" transitionDelay="0.1s" /> + + ... + NUpath Requirements diff --git a/packages/frontend/components/Sidebar/SandboxArea.tsx b/packages/frontend/components/Sidebar/SandboxArea.tsx new file mode 100644 index 000000000..9f7fdcaab --- /dev/null +++ b/packages/frontend/components/Sidebar/SandboxArea.tsx @@ -0,0 +1,100 @@ +import { + Box, + VStack, + Flex, + Image, + Text, + Textarea, + TextareaProps, +} from "@chakra-ui/react"; +import { forwardRef, useEffect, useState } from "react"; +import ResizeTextarea from "react-textarea-autosize"; +import { toast } from "react-toastify"; + +const AutoResizeTextarea = forwardRef( + (props, ref) => { + return ( +