Skip to content

Commit

Permalink
change popup to button for ap prereqs
Browse files Browse the repository at this point in the history
  • Loading branch information
Timofey Obraztsov committed Dec 8, 2023
1 parent efd77eb commit 39fa62e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 102 deletions.
2 changes: 1 addition & 1 deletion api/.env.local
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PRODUCTION_DOMAIN=http://localhost:5000
PRODUCTION_DOMAIN=http://localhost:5001
135 changes: 64 additions & 71 deletions site/src/component/PrereqTree/PrereqTree.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { FC } from 'react';
import './PrereqTree.scss';
import { Grid, Popup } from 'semantic-ui-react';
import React, { FC } from "react";
import "./PrereqTree.scss";
import { Grid, Popup } from "semantic-ui-react";

import { PrerequisiteJSONNode, PrerequisiteJSON, CourseGQLData, CourseLookup } from '../../types/types';
import { PrerequisiteJSONNode, PrerequisiteJSON, CourseGQLData, CourseLookup } from "../../types/types";

interface NodeProps {
node: string;
Expand All @@ -12,18 +12,27 @@ interface NodeProps {
}

const Node: FC<NodeProps> = (props) => {
console.log(props.label);
return (
<div style={{ padding: '1px 0' }} className={`node-container ${props.node}`} key={props.index}>
<div style={{ padding: "1px 0" }} className={`node-container ${props.node}`} key={props.index}>
<Popup
trigger={
<a href={'/course/' + props.label.replace(/\s+/g, '')} role='button' style={{ padding: '0.5rem' }} className={'node ui button'}>
{props.label}
</a>
!props.label.startsWith("AP ") ? (
<a href={"/course/" + props.label.replace(/\s+/g, "")} role="button" style={{ padding: "0.5rem" }} className={`node ui button`}>
{props.label}
</a>
) : (
<button style={{ padding: "0.5rem" }} className={`node ui button`}>{`${props.label}`}</button>
)
}
content={props.content} basic position='top center' wide='very' />
content={props.content}
basic
position="top center"
wide="very"
/>
</div>
);
}
};

interface TreeProps {
prerequisiteNames: CourseLookup;
Expand All @@ -34,94 +43,83 @@ interface TreeProps {

const Tree: FC<TreeProps> = (props) => {
let prerequisite = props.prerequisiteJSON;
let isValueNode = typeof prerequisite === 'string';
let isValueNode = typeof prerequisite === "string";

// if value is a string, render leaf node
if (isValueNode) {
let id = (prerequisite as string).replace(/\s+/g, '');
let id = (prerequisite as string).replace(/\s+/g, "");
let content = prerequisite;
if (props.prerequisiteNames.hasOwnProperty(id)) {
content = props.prerequisiteNames[id].title;
}
return (
<li key={props.index} className={'prerequisite-node'}>
<Node label={prerequisite as string} content={content as string} node={'prerequisite-node'} />
<li key={props.index} className={"prerequisite-node"}>
<Node label={prerequisite as string} content={content as string} node={"prerequisite-node"} />
</li>
)
);
}
// if value is an object, render the rest of the sub tree
else {
return (
<div style={{ margin: 'auto 0' }} className={'prerequisite-node'}>
<div style={{ display: 'inline-flex', flexDirection: 'row', padding: '0.5rem 0' }}>
<span style={{ margin: 'auto' }}>
<div className='prereq-branch'>
{prerequisite.hasOwnProperty('OR') ? 'one of' : 'all of'}
</div>
<div style={{ margin: "auto 0" }} className={"prerequisite-node"}>
<div style={{ display: "inline-flex", flexDirection: "row", padding: "0.5rem 0" }}>
<span style={{ margin: "auto" }}>
<div className="prereq-branch">{prerequisite.hasOwnProperty("OR") ? "one of" : "all of"}</div>
</span>
<div className='prereq-clump'>
<ul className='prereq-list'>
{(prerequisite as PrerequisiteJSON)[Object.keys(prerequisite)[0]].map(
(child, index) => (
<Tree key={`tree-${index}`} prerequisiteNames={props.prerequisiteNames} index={index} prerequisiteJSON={child} />
)
)}
<div className="prereq-clump">
<ul className="prereq-list">
{(prerequisite as PrerequisiteJSON)[Object.keys(prerequisite)[0]].map((child, index) => (
<Tree key={`tree-${index}`} prerequisiteNames={props.prerequisiteNames} index={index} prerequisiteJSON={child} />
))}
</ul>
</div>
</div>
</div>
)
);
}
}
};

interface PrereqProps extends CourseGQLData {
}
interface PrereqProps extends CourseGQLData {}

const PrereqTree: FC<PrereqProps> = (props) => {
let hasPrereqs = props.prerequisite_tree !== '';
let hasPrereqs = props.prerequisite_tree !== "";
let hasDependencies = Object.keys(props.prerequisite_for).length !== 0;

if (props.id === undefined) return <></>;
else if (!hasPrereqs && !hasDependencies)
return (
<div className='missing-tree'>
<p>
No Dependencies or Prerequisites!
</p>
<div className="missing-tree">
<p>No Dependencies or Prerequisites!</p>
</div>
);
return (
<div>
<Grid.Row className='prereq'>
<Grid.Row className="prereq">
<div
style={{
display: 'inline-flex',
flexDirection: 'row',
width: 'fit-content',
justifyContent: 'center',
margin: 'auto'
display: "inline-flex",
flexDirection: "row",
width: "fit-content",
justifyContent: "center",
margin: "auto",
}}
>
{/* Display dependencies */}
{hasDependencies && (
<>
<ul style={{ padding: '0', display: 'flex' }}>
<div className='dependency-list-branch'>
{Object.values(props.prerequisite_for).map(
(dependency, index) => (
<li key={`dependency-node-${index}`} className={'dependency-node'}>
<Node label={dependency.department + ' ' + dependency.number} content={dependency.title} node={'dependency-node'} />
</li>
)
)}
<ul style={{ padding: "0", display: "flex" }}>
<div className="dependency-list-branch">
{Object.values(props.prerequisite_for).map((dependency, index) => (
<li key={`dependency-node-${index}`} className={"dependency-node"}>
<Node label={dependency.department + " " + dependency.number} content={dependency.title} node={"dependency-node"} />
</li>
))}
</div>
</ul>

<div style={{ display: 'inline-flex', flexDirection: 'row', marginLeft: '0.5rem' }}>
<span style={{ margin: 'auto 1rem' }}>
<div className='dependency-needs dependency-branch'>
needs
</div>
<div style={{ display: "inline-flex", flexDirection: "row", marginLeft: "0.5rem" }}>
<span style={{ margin: "auto 1rem" }}>
<div className="dependency-needs dependency-branch">needs</div>
</span>
</div>
</>
Expand All @@ -134,16 +132,12 @@ const PrereqTree: FC<PrereqProps> = (props) => {
</div>} */}

{/* Display the class id */}
<Node label={props.id} content={props.title} node={'course-node'} />
<Node label={props.id} content={props.title} node={"course-node"} />

{/* Spawns the root of the prerequisite tree */}
{hasPrereqs && (
<div style={{ display: 'flex' }}>
<Tree
prerequisiteNames={props.prerequisite_list}
prerequisiteJSON={JSON.parse(props.prerequisite_tree)}
/>

<div style={{ display: "flex" }}>
<Tree prerequisiteNames={props.prerequisite_list} prerequisiteJSON={JSON.parse(props.prerequisite_tree)} />
</div>
)}

Expand All @@ -152,14 +146,13 @@ const PrereqTree: FC<PrereqProps> = (props) => {
No Prerequisites!
</p>
</div>} */}

</div>
{props.prerequisite_text !== '' && (
{props.prerequisite_text !== "" && (
<div
style={{
padding: '1em',
backgroundColor: '#f5f5f5',
marginTop: '2em',
padding: "1em",
backgroundColor: "#f5f5f5",
marginTop: "2em",
}}
>
<p>
Expand All @@ -171,6 +164,6 @@ const PrereqTree: FC<PrereqProps> = (props) => {
</Grid.Row>
</div>
);
}
};

export default PrereqTree;
export default PrereqTree;
51 changes: 25 additions & 26 deletions site/src/hooks/professorData.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { gql, useQuery } from '@apollo/client';
import { ProfessorGQLData, SubCourse, CourseLookup } from '../types/types';
import { gql, useQuery } from "@apollo/client";
import { ProfessorGQLData, SubCourse, CourseLookup } from "../types/types";

interface ProfessorGQLResponse {
instructor: Omit<ProfessorGQLData, 'course_history'> & {
course_history: SubCourse[];
}
instructor: Omit<ProfessorGQLData, "course_history"> & {
course_history: SubCourse[];
};
}

// given a course id, get the gql equivalent
function useProfessorGQL(professorID: string | undefined) {
const query = gql`
const query = gql`
query {
instructor(ucinetid:"${professorID}"){
name
Expand All @@ -27,26 +27,25 @@ function useProfessorGQL(professorID: string | undefined) {
}
}
}`;
const { loading, error, data } = useQuery<ProfessorGQLResponse>(query);
if (loading || error) {
return { loading, error, professor: null };
}
else {
if (!professorID || !data?.instructor) {
return { loading, error, professor: null };
}
let courseHistoryLookup: CourseLookup = {};
// maps course's id to course basic details
data!.instructor.course_history.forEach(course => {
if (course) {
courseHistoryLookup[course.id] = course;
}
})
// create copy to override fields with lookups
let professor = { ...data!.instructor } as unknown as ProfessorGQLData;
professor.course_history = courseHistoryLookup;
return { loading, error, professor: professor };
const { loading, error, data } = useQuery<ProfessorGQLResponse>(query);
if (loading || error) {
return { loading, error, professor: null };
} else {
if (!professorID || !data?.instructor) {
return { loading, error, professor: null };
}
let courseHistoryLookup: CourseLookup = {};
// maps course's id to course basic details
data!.instructor.course_history.forEach((course) => {
if (course) {
courseHistoryLookup[course.id] = course;
}
});
// create copy to override fields with lookups
let professor = { ...data!.instructor } as unknown as ProfessorGQLData;
professor.course_history = courseHistoryLookup;
return { loading, error, professor: professor };
}
}

export { useProfessorGQL }
export { useProfessorGQL };
8 changes: 4 additions & 4 deletions site/src/setupProxy.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const { createProxyMiddleware } = require('http-proxy-middleware');
const { createProxyMiddleware } = require("http-proxy-middleware");

module.exports = function(app) {
module.exports = function (app) {
app.use(
'/api',
"/api",
createProxyMiddleware({
target: 'http://localhost:5000',
target: "http://localhost:5001",
changeOrigin: true,
})
);
Expand Down

0 comments on commit 39fa62e

Please sign in to comment.