Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shireen jake generic course #766

Merged
merged 10 commits into from
Nov 10, 2024
27 changes: 27 additions & 0 deletions packages/api/src/major/parsed.initial.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "Any Major",
"metadata": {
"verified": false,
"lastEdited": "4/14/2024"
},
"requirementSections": [
{
"type": "SECTION",
"title": "General Placeholders",
"requirements": [
{
"subject": "PLACEHOLDER",
"classId": 1000,
"description": "Elective",
"type": "COURSE"
},
{
"type": "COURSE",
"classId": 1000,
"subject": "PLACEHOLDER",
"description": "NU Path"
}
]
}
]
}
1 change: 1 addition & 0 deletions packages/common/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ export interface ScheduleCourse2<T> {
numCreditsMin: number;
numCreditsMax: number;
id: T;
generic?: boolean;
}

// LEGACY SCHEDULE. USED BY V1 OF THE APP.
Expand Down
143 changes: 143 additions & 0 deletions packages/frontend/components/Sidebar/GenericSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { ChevronDownIcon, ChevronUpIcon } from "@chakra-ui/icons";
import { Box, Flex, Spinner, Stack, Text } from "@chakra-ui/react";
import { useState } from "react";
import { ScheduleCourse2 } from "@graduate/common";
import { DraggableScheduleCourse } from "../ScheduleCourse";
import { SIDEBAR_DND_ID_PREFIX, GEN_PLACEHOLDER_MSG } from "../../utils";
import { HelperToolTip } from "../Help";

// Define the props interface for GenericSection
interface GenericSectionProps {
courseData: { [id: string]: ScheduleCourse2<null> };
dndIdPrefix: string;
loading?: boolean;
}

export const GENERIC_ELECTIVE: ScheduleCourse2<string> = {
name: "Elective",
classId: "Generic Class ",
subject: "",
numCreditsMax: 0,
numCreditsMin: 0,
id: `${SIDEBAR_DND_ID_PREFIX}-generic-elective`,
generic: true,
};

export const GENERIC_NUPATH: ScheduleCourse2<string> = {
name: "NUPath",
classId: "Generic Class",
subject: "",
numCreditsMax: 0,
numCreditsMin: 0,
id: `${SIDEBAR_DND_ID_PREFIX}-generic-nupath`,
generic: true,
};

const courses = [GENERIC_ELECTIVE, GENERIC_NUPATH];

const GenericSection: React.FC<GenericSectionProps> = ({
courseData,
loading,
}) => {
const [opened, setOpened] = useState(false);

return (
<Box
borderTopWidth="1px"
borderTopColor="neutral.200"
cursor="pointer"
userSelect="none"
>
<Flex
onClick={() => {
setOpened(!opened);
}}
direction="row"
justifyContent="space-between"
alignItems="flex-start"
color="dark.main"
fontWeight="bold"
py="md"
px="md"
margin="0"
backgroundColor="neutral.50"
transition="background-color 0.25s ease"
_hover={{
backgroundColor: "neutral.100",
}}
_active={{
backgroundColor: "neutral.200",
}}
display="flex"
position="sticky"
top="0px"
zIndex={1}
>
<Flex direction="row" height="100%" columnGap="sm">
<Box
bg="transparent"
borderColor="neutral.400"
borderWidth="1px"
width="18px"
height="18px"
display="flex"
alignItems="center"
justifyContent="center"
borderRadius="2xl"
mt="4xs"
p="xs"
position="relative"
opacity="0"
></Box>
<Flex direction="row" height="100%" alignItems="center" gap="1">
<Text color="primary.blue.dark.main" mt="0" fontSize="sm">
General Placeholders
</Text>
<HelperToolTip label={GEN_PLACEHOLDER_MSG} />
</Flex>
</Flex>
<Flex ml="xs" alignItems="center">
{opened ? (
<ChevronUpIcon boxSize="25px" color="primary.blue.dark.main" />
) : (
<ChevronDownIcon boxSize="25px" color="primary.blue.dark.main" />
)}
</Flex>
</Flex>
<Box
style={{ display: opened ? "" : "none" }}
backgroundColor="neutral.100"
borderTopWidth=".5px"
borderTopColor="neutral.200"
padding="10px 20px 15px 10px"
cursor="default"
>
{loading && (
<Flex alignItems="center">
<Spinner size="sm"></Spinner>
<Text marginLeft="xs">Loading...</Text>
</Flex>
)}
{opened && !loading && (
<Stack spacing={3}>
<Box pl="xs" pt="xs">
{Object.keys(courseData).length > 0 && (
<div>
{courses.map((course, index) => (
<DraggableScheduleCourse
key={index}
scheduleCourse={course}
isDisabled={false}
/>
))}
</div>
)}
</Box>
</Stack>
)}
</Box>
</Box>
);
};

export default GenericSection;
6 changes: 6 additions & 0 deletions packages/frontend/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import { useFetchCourses, useMajor } from "../../hooks";
import NUPathSection from "./NUPathSection";
import { NUPathEnum } from "@graduate/common";
import GenericSection from "./GenericSection";
import SidebarContainer from "./SidebarContainer";

export enum SidebarValidationStatus {
Expand Down Expand Up @@ -217,6 +218,11 @@ const Sidebar: React.FC<SidebarProps> = memo(
>
{courseData && (
<>
<GenericSection
courseData={courseData}
dndIdPrefix={`${SIDEBAR_DND_ID_PREFIX}-generic`}
loading={isCoursesLoading}
/>
<NUPathSection
coursesTaken={coursesTaken}
dndIdPrefix={`${SIDEBAR_DND_ID_PREFIX}-nupath`}
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const SEARCH_NEU_FETCH_COURSE_ERROR_MSG =
"Sorry, we can't load details for this course right now 😞. We rely on SearchNEU for our course details, and there may be an ongoing issue on their end. We recommend refreshing the page and trying again soon.";
export const BETA_MAJOR_TOOLTIP_MSG =
"Requirements for beta majors have not been validated and therefore may be inconsistent with your degree audit.";
export const GEN_PLACEHOLDER_MSG =
"General Placeholderse are generic courses that you can place in your plan if you do not know yet what to take but want the requirements to be fulfilled";

export const defaultGuestStudent: GetStudentResponse = {
uuid: undefined,
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/utils/plan/updatePlanOnDragEnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export const updatePlanOnDragEnd = (
draggedCourseDetails.subject,
newTerm
) &&
!isSameTerm
!isSameTerm &&
!draggedCourseDetails.generic
) {
toast.error(
`Oops, ${getCourseDisplayString(
Expand Down
Loading