Skip to content

Commit

Permalink
made icons appear for transcript-loaded courses explicitly listed as …
Browse files Browse the repository at this point in the history
…requirement for a major
  • Loading branch information
samuel-lao committed Nov 18, 2024
1 parent 1ad94a1 commit 956e721
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 64 deletions.
4 changes: 0 additions & 4 deletions frontend/degree-plan/components/Dock/Dock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,10 @@ interface DockProps {
}

const Dock = ({ user, login, logout, activeDegreeplanId }: DockProps) => {
// const [courseAdded, setCourseAdded] = React.useState(false);
const { searchPanelOpen, setSearchPanelOpen, setSearchRuleQuery, setSearchRuleId } = useContext(SearchPanelContext)
// const { createOrUpdate } = useSWRCrud<DockedCourse>(["DOCK", `/api/degree/docked`], { idKey: 'full_code' });
const { createOrUpdate } = useSWRCrud<DockedCourse>(`/api/degree/docked`, { idKey: 'full_code' });
const { data: dockedCourses = [], isLoading } = useSWR<DockedCourse[]>(user ? `/api/degree/docked` : null);

// console.log(dockedCourses)

// Returns a boolean that indiates whether this is the first render
const useIsMount = () => {
const isMountRef = React.useRef(true);
Expand Down
3 changes: 1 addition & 2 deletions frontend/degree-plan/components/FourYearPlan/Semester.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,7 @@ const FlexSemester = ({
const { createOrUpdate: addToDock } = useSWRCrud<DockedCourse>(`/api/degree/docked`, { idKey: 'full_code' });

// the fulfillments api uses the POST method for updates (it creates if it doesn't exist, and updates if it does)
const { createOrUpdate, remove } = useSWRCrud<Fulfillment[]>(
// ["SEM", `/api/degree/degreeplans/${activeDegreeplanId}/fulfillments`],
const { createOrUpdate, remove } = useSWRCrud<Fulfillment>(
`/api/degree/degreeplans/${activeDegreeplanId}/fulfillments`,
{
idKey: "full_code",
Expand Down
5 changes: 0 additions & 5 deletions frontend/degree-plan/components/FourYearPlan/Semesters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,6 @@ const Semesters = ({
: null
);
// semesters is state mostly derived from fulfillments
useEffect(() => {
console.log("SEM", {fulfillments})
console.log(isLoadingFulfillments)
}, [fulfillments, isLoadingFulfillments])


const getDefaultSemesters = React.useCallback(() => {
Expand Down Expand Up @@ -273,7 +269,6 @@ const Semesters = ({

/** Parse fulfillments and group them by semesters */
useEffect(() => {
console.log({ fulfillments })
if (!activeDegreeplan || !fulfillments || isLoadingFulfillments) return; // TODO: need more logic in this case
setSemesters((currentSemesters) => {
const semesters = {} as { [semester: string]: Fulfillment[] };
Expand Down
6 changes: 2 additions & 4 deletions frontend/degree-plan/components/Requirements/ReqPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import RuleComponent, { SkeletonRule } from './Rule';
import { Degree as DegreeType, DegreePlan, Fulfillment, Rule } from '@/types';
import styled from '@emotion/styled';
Expand Down Expand Up @@ -233,9 +233,7 @@ interface ReqPanelProps {
const ReqPanel = ({setModalKey, setModalObject, activeDegreeplan, isLoading}: ReqPanelProps) => {
const [editMode, setEditMode] = React.useState(false);
const { data: activeDegreeplanDetail = null, isLoading: isLoadingDegrees } = useSWR<DegreePlan>(activeDegreeplan ? `/api/degree/degreeplans/${activeDegreeplan.id}` : null);
const { data: fulfillments, isLoading: isLoadingFulfillments } = useSWR<Fulfillment[]>(activeDegreeplan ? `/api/degree/degreeplans/${activeDegreeplan.id}/fulfillments` : null, {

});
const { data: fulfillments, isLoading: isLoadingFulfillments } = useSWR<Fulfillment[]>(activeDegreeplan ? `/api/degree/degreeplans/${activeDegreeplan.id}/fulfillments` : null);

const rulesToFulfillments = useMemo(() => {
if (isLoadingFulfillments || !fulfillments) return {};
Expand Down
2 changes: 0 additions & 2 deletions frontend/degree-plan/hooks/swrcrud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ const getCsrf = (): string | boolean => {
* @returns JSON or undefined (see @param returnJson).
*/
export const baseFetcher = (init: RequestInit, returnJson: boolean = true) => async (resource: string, body?: any) => {
console.log("Something's happened")
console.log(resource)
const res = await fetch(resource, {
credentials: "include",
mode: "same-origin",
Expand Down
118 changes: 75 additions & 43 deletions frontend/degree-plan/pages/OnboardingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
UploadIcon,
ArrowLeftIcon,
ArrowRightIcon,
RulerSquareIcon,
} from "@radix-ui/react-icons";
import { set } from "lodash";
polyfillPromiseWithResolvers();
Expand Down Expand Up @@ -332,11 +333,13 @@ const OnboardingPage = ({
const [scrapedTransfer, setScrapedTransfer] = useState<string[]>([]);
const [currentPage, setCurrentPage] = useState<number>(0);

const [degreeID, setDegreeID] = useState<number | null>(null);
const [coursesToRules, setCoursesToRules] = useState<any>(null);

const { create: createDegreeplan } = useSWRCrud<DegreePlan>(
"/api/degree/degreeplans"
);

const [degreeID, setDegreeID] = useState<number | null>(null);

const { createOrUpdate, remove } = useSWRCrud<Fulfillment>(
`/api/degree/degreeplans/${degreeID}/fulfillments`,
Expand All @@ -349,14 +352,10 @@ const OnboardingPage = ({
// Workaround solution to only input courses once degree has been created and degreeID exists.
// Will likely change in the future!
useEffect(() => {
if (degreeID) {
console.log(degreeID)

if (degreeID && coursesToRules) {
for (let sem of scrapedCourses) {
console.log(sem)
let semCode = ""
if (sem.sem == "_TRAN") semCode = sem.sem

else {
semCode = sem.sem.match(/(\d+)/)[0];
if (sem.sem.includes("spring")) semCode += "A";
Expand All @@ -366,14 +365,22 @@ const OnboardingPage = ({

for (let course of sem.courses) {
let code = course.replace(" ", "-").toUpperCase();
createOrUpdate({ semester: semCode }, code);

// If rule exists for course code, add it. Else, add with no rule.
// TODO: Need support for more vague rules.
if (Object.keys(coursesToRules).includes(code)) {
let rule = coursesToRules[code];
createOrUpdate({ rules: [rule], semester: semCode }, code);
} else {
createOrUpdate({ semester: semCode }, code);
}
}
}

setShowOnboardingModal(false);
// location.reload();
}
}, [degreeID]);
}, [degreeID, coursesToRules]);

const complete =
startingYear !== null &&
Expand Down Expand Up @@ -423,8 +430,7 @@ const OnboardingPage = ({
label: createMajorLabel(degree),
}))
.sort((a, b) => a.label.localeCompare(b.label));

return majorOptions;
return majorOptions;
}

const majorOptionsCallback = React.useCallback(() => {
Expand All @@ -450,17 +456,49 @@ const OnboardingPage = ({
const updated = postFetcher(
`/api/degree/degreeplans/${res.id}/degrees`,
{ degree_ids: majors.map((m) => m.value.id) }
); // add degree
setActiveDegreeplan(res);
).then((res) => {
// Compile courses that are explicitly listed under a certain rule (Ex. CIS-1200)
let coursesToRules: any = {}

// Recursively find all courses explicitly listed and pairs each with their rule #
// TO DO: add support for things like WRIT 0000-5999 (given range of valid courses)
function findFinalRulesOrQJson(obj: any) {
// If q_json has type COURSE, add the single listed course to coursesToRules
if (obj?.q_json?.type === "COURSE") {
coursesToRules[obj.q_json.full_code] = obj.id;
}

// If q_json has type OR, add all listed courses to coursesToRules
else if (obj?.q_json?.type === "OR") {
for (let course of obj.q_json.clauses) {
if (course.type === "COURSE") {
coursesToRules[course.full_code] = obj.id;
}
}
}

// Else, loop through all rules
if (obj?.rules && obj?.rules.length != 0) {
for (let rule of obj.rules) {
findFinalRulesOrQJson(rule)
}
}
}

for (let degree of res.degrees) {
findFinalRulesOrQJson(degree)
}

setCoursesToRules(coursesToRules);
}); // add degree
setActiveDegreeplan(res);
setDegreeID(res.id);
}
});
};


// TRANSCRIPT PARSING

const total = useRef<any>({});

const addText = (items: (any)[], index: number) => {
Expand Down Expand Up @@ -515,22 +553,21 @@ const OnboardingPage = ({

const parseTranscript = (textResult: any) => {

let separatedCourses : any = [];
let separatedCourses: any = [];

let startYear : number = 0;
let tempSchools : any = [];
let detectedMajors : string[] = [];
let detectedConcentrations : string[] = [];
let startYear: number = 0;
let tempSchools: any = [];
let detectedMajors: string[] = [];
let detectedConcentrations: string[] = [];

for (let l in textResult) {
// SCRAPE SCHOOL
if (textResult[l].replaceAll(" ", "").includes("program:")) {
console.log(textResult[l])
let program = textResult[l].replace(/^.*?:\s*/, "");
// tempSchools = [];
if (program.includes("arts"))
tempSchools.push({ value: "BA", label: "Arts & Sciences" });

if (program.includes("school of engineering and applied science")) {
if (textResult[parseInt(l) + 1].includes("bachelor of science in engineering"))
tempSchools.push({ value: "BSE", label: "Engineering BSE" });
Expand All @@ -549,12 +586,12 @@ const OnboardingPage = ({

// SCRAPE MAJOR
if (textResult[l].includes("major")) {
detectedMajors.push(textResult[l].replace(/^.*?:\s*/, ""));
detectedMajors.push(textResult[l].replace(/^.*?:\s*/, ""));
}

// SCRAPE CONCENTRATION
if (textResult[l].includes("concentration")) {
detectedConcentrations.push(textResult[l].replace(/^.*?:\s*/, ""));
detectedConcentrations.push(textResult[l].replace(/^.*?:\s*/, ""));
}

// Regex gets an array for total institution values -> [Earned Hours, GPA Hours, Points, GPA]
Expand All @@ -563,8 +600,6 @@ const OnboardingPage = ({
if (totalNums) {
let credit_hours = totalNums[0];
let gpa = totalNums[3];
console.log(credit_hours);
console.log(gpa);
}
}

Expand All @@ -573,7 +608,6 @@ const OnboardingPage = ({
let totalNums = textResult[l].match(/\d+\.\d+/g);
if (totalNums) {
let transfer_hours = totalNums[0];
console.log(transfer_hours);
}
}

Expand All @@ -593,7 +627,6 @@ const OnboardingPage = ({
courses.push(courseMatch[0]);
} else if (line.includes("institution credit")) {
separatedCourses["_TRAN"] = courses;
console.log(courses);
break;
}
}
Expand All @@ -617,7 +650,6 @@ const OnboardingPage = ({
separatedCourses = Object.keys(separatedCourses).map(
(key) => [{ sem: key, courses: separatedCourses[key] }][0]
);
console.log(separatedCourses);

setScrapedCourses(separatedCourses);

Expand All @@ -642,23 +674,23 @@ const OnboardingPage = ({
let detectedMajorsOptions = [];

let possibleDegrees = getMajorOptions(degrees, tempSchools, startYear)
for (let i in detectedMajors) {
let m = detectedMajors[i] + (detectedConcentrations.length > parseInt(i) ? detectedConcentrations[i] : "")
if (!detectedMajors[i]?.includes("undeclared") && possibleDegrees) {
console.log(m)
let justMajorNames = possibleDegrees.reduce((acc: any, el: any) => {
acc.push(el.label);
return acc;
}, [])
let closestMajor = closest("computer science - no concen", justMajorNames)
console.log(closestMajor)
var majorOption = possibleDegrees.find(obj => {
return obj.label === closestMajor
})
if (majorOption) detectedMajorsOptions.push(majorOption)
}
for (let i in detectedMajors) {
let m = detectedMajors[i] + (detectedConcentrations.length > parseInt(i) ? detectedConcentrations[i] : "")
if (!detectedMajors[i]?.includes("undeclared") && possibleDegrees) {
// console.log(m)
let justMajorNames = possibleDegrees.reduce((acc: any, el: any) => {
acc.push(el.label);
return acc;
}, [])
let closestMajor = closest(m, justMajorNames)
// console.log(closestMajor)
var majorOption = possibleDegrees.find(obj => {
return obj.label === closestMajor
})
if (majorOption) detectedMajorsOptions.push(majorOption)
}
setMajors(detectedMajorsOptions)
}
setMajors(detectedMajorsOptions)
};

if (currentPage === 0)
Expand Down
5 changes: 1 addition & 4 deletions frontend/degree-plan/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ export default function Home() {
<SWRConfig
value={{
fetcher: (resource, init) =>
{
return fetch(resource, init).then((res) => res.json())
},
// fetch(resource, init).then((res) => res.json()),
fetch(resource, init).then((res) => res.json()),
provider: () => new Map(),
onError: (error, key) => {
// if (error.status !== 403 && error.status !== 404) {
Expand Down

0 comments on commit 956e721

Please sign in to comment.