Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
da166c7
applied filters into the search function using flags in the model, wi…
boldizsarbenedek Apr 16, 2025
190a822
wrote departments filter option
boldizsarbenedek Apr 16, 2025
c61814b
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
a865fa4
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
7ca07a1
added check to make sure to not recommend courses the client has take…
boldizsarbenedek Apr 16, 2025
df2872b
initial state good
kexana Apr 16, 2025
000d882
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
41c4cfe
commit?
boldizsarbenedek Apr 16, 2025
d8f1543
departments go to model
kexana Apr 16, 2025
b162882
trying to add filtering out courses with NULL fields as an implementa…
boldizsarbenedek Apr 16, 2025
1ca3881
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
170e1b4
merging into brain?
boldizsarbenedek Apr 16, 2025
c33ceb3
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
9d9bf3e
merging/
boldizsarbenedek Apr 16, 2025
855f4ab
some ?. properties check, because skill issue
boldizsarbenedek Apr 16, 2025
fce40c0
Merge branch 'main' of github.com:InferenceKTH/Find-My-Next-Course in…
boldizsarbenedek Apr 16, 2025
fb0554b
more course?. things
boldizsarbenedek Apr 16, 2025
05f9fd2
finished the noNull feature, essentially fixed typos
boldizsarbenedek Apr 16, 2025
f1ac1bf
null course checkbox
kexana Apr 16, 2025
917184e
null check linked
kexana Apr 16, 2025
b41e5a8
Null field toggle works
kexana Apr 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions my-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions my-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"preview": "vite preview"
},
"dependencies": {

"@dagrejs/dagre": "^1.1.4",
"@headlessui/react": "^2.2.1",
"@heroicons/react": "^2.2.0",
"@dagrejs/dagre": "^1.1.4",
"@react-buddy/ide-toolbox": "^2.4.0",
"@tailwindcss/vite": "^4.0.17",
"@xyflow/react": "^12.5.5",
"autoprefixer": "^10.4.21",
Expand All @@ -28,8 +28,7 @@
"react-infinite-scroll-component": "^6.1.0",
"react-router-dom": "^7.4.0",
"reactflow": "^11.11.4",
"tailwindcss": "^4.0.17",
"@react-buddy/ide-toolbox": "^2.4.0"
"tailwindcss": "^4.0.17"
},
"devDependencies": {
"@eslint/js": "^9.21.0",
Expand Down
6 changes: 5 additions & 1 deletion my-app/src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ export const model = {
this.filtersCalculated = true;
},

setApplyRemoveNullCourses() {
this.filterOptions.applyRemoveNullCourses = !this.filterOptions.applyRemoveNullCourses;
this.setFiltersChange();
},

updateLevelFilter(level) {
this.filterOptions.level = level;
},
Expand All @@ -149,7 +154,6 @@ export const model = {
},

updateDepartmentFilter(department) {
console.log(department);
this.filterOptions.department = department;
},

Expand Down
28 changes: 14 additions & 14 deletions my-app/src/presenters/FilterPresenter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const FilterPresenter = observer(({ model }) => {
//console.log(course?.prerequisites);
if (storedFinishedCourses.includes(course?.code))
return;
if (course?.prerequisites && (course.prerequisites !== "null"))
if (course?.prerequisites && (course?.prerequisites !== "null"))
var resultEligibility = eligibility(storedFinishedCourses, course?.prerequisites);
else { // {strong: , zero: , moderate: , weak: }
zerocourses.push(course);
Expand Down Expand Up @@ -89,9 +89,9 @@ const FilterPresenter = observer(({ model }) => {

localFilteredCourses = localFilteredCourses.filter(function (course) {
try {
return ((course.credits >= min) && (course.credits <= max));
return ((course?.credits >= min) && (course?.credits <= max));
} catch (error) {
console.log("for some reason course.credits is: ", course?.credits, error);
console.log("for some reason course?.credits is: ", course?.credits, error);
return false;
}

Expand All @@ -108,9 +108,9 @@ const FilterPresenter = observer(({ model }) => {

bestCourses = localFilteredCourses.filter(function (course) {
try {
return (locations.includes(course.location));
return (locations.includes(course?.location));
} catch (error) {
console.log("for some reason course.location is: ", course?.location, error);
console.log("for some reason course?.location is: ", course?.location, error);
return false;
}

Expand Down Expand Up @@ -140,8 +140,8 @@ const FilterPresenter = observer(({ model }) => {
let worstCourses = [];

//in the database a course can have
//course.language.english (true/false/"null")
//course.language.swedish (true/false/"null")
//course?.language.english (true/false/"null")
//course?.language.swedish (true/false/"null")

//console.log(data);

Expand Down Expand Up @@ -278,9 +278,9 @@ const FilterPresenter = observer(({ model }) => {

bestCourses = localFilteredCourses.filter(function (course) {
try {
return (deparments.includes(course.deparment));
return (deparments.includes(course?.deparment));
} catch (error) {
console.log("for some reason course.department is: ", course?.department, error);
console.log("for some reason course?.department is: ", course?.department, error);
return false;
}

Expand All @@ -305,19 +305,19 @@ const FilterPresenter = observer(({ model }) => {

if(model.filterOptions.applyTranscriptFilter){
local = local.filter(function(course){
return (course?.prerequisites && (course.prerequisites !== "null"));
return (course?.prerequisites && (course?.prerequisites !== "null"));
})
}
console.log("miauuuuu:",local.length);
if(model.filterOptions.applyLevelFilter){
local = local.filter(function(course){
return (course?.prerequisites && (course.prerequisites !== "null"));
return (course?.prerequisites && (course?.prerequisites !== "null"));
})
}
console.log("miauuuuu:",local.length);
if(model.filterOptions.applyLanguageFilter){
local = local.filter(function(course){
return ((course?.language) && (course?.language?.swedish !== "null" && course?.language?.english !== "null"));
return ((course?.language) && ((course?.language?.swedish !== "null") && (course?.language?.english !== "null")));
})
}
console.log("miauuuuu:",local.length);
Expand All @@ -329,13 +329,13 @@ const FilterPresenter = observer(({ model }) => {
console.log("miauuuuu:",local.length);
if(model.filterOptions.applyCreditsFilter){
local = local.filter(function(course){
return ((course?.credit) && (course?.credit !== "null"));
return ((course?.credits) && (course?.credits !== "null"));
})
}
console.log("miauuuuu:",local.length);
if(model.filterOptions.applyDepartmentFilter){
local = local.filter(function(course){
return ((course?.deparment) && (course?.department !== "null"));
return ((course?.department) && (course?.department !== "null"));
})
}
console.log("miauuuuu:",local.length);
Expand Down
16 changes: 9 additions & 7 deletions my-app/src/presenters/PrerequisitePresenter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const PrerequisitePresenter = observer((props) => {
const nodeWidth = 172;
const nodeHeight = 36;

loadTree(props.selectedCourse.code);
loadTree(props.selectedCourse?.code);
console.log(initialNodes);

const getLayoutedElements = (nodes, edges, direction = 'LR') => {
Expand Down Expand Up @@ -133,7 +133,7 @@ export const PrerequisitePresenter = observer((props) => {
node["style"]["zIndex"] = 0;
setLabel(node["id"], "More Info...");
}
} else if (node["data"]["label"] !== "One of these" && node["data"]["label"] !== "No Prerequisites" && node["id"] !== props.selectedCourse.code) {
} else if (node["data"]["label"] !== "One of these" && node["data"]["label"] !== "No Prerequisites" && node["id"] !== props.selectedCourse?.code) {
// ADD FUNCTIONALITY FOR CLICKING COURSE CODE NODE (Tu eres muy retrasado y gordo)! :)
// ONCLICK HERE
}
Expand Down Expand Up @@ -266,7 +266,7 @@ export const PrerequisitePresenter = observer((props) => {
}

function generateTree(courses_taken, prereqs) {
prereq_convert(courses_taken, prereqs, null, props.selectedCourse.code);
prereq_convert(courses_taken, prereqs, null, props.selectedCourse?.code);
let key = Object.keys(prereqs);
return prereqs[key];

Expand All @@ -275,15 +275,17 @@ export const PrerequisitePresenter = observer((props) => {

function loadTree(courses_taken) {

console.log(JSON.stringify(props.selectedCourse.prerequisites, null, 4));
if (props.selectedCourse.prerequisites === "null" || props.selectedCourse.prerequisites.length == 0) {
console.log(JSON.stringify(props.selectedCourse?.prerequisites, null, 4));
if(props.selectedCourse?.prerequisites === undefined || props.selectedCourse?.code === undefined)
console.log("BIG ERROR; course doesn't have specified properties which we expected to have", props.selectedCourse);
if (props.selectedCourse?.prerequisites === "null" || props.selectedCourse?.prerequisites.length == 0) {
let display_node = createNode("No Prerequisites", "No Prerequisites", "default");
display_node.style["pointerEvents"] = "none";
display_node["className"] = 'no-handles';
initialNodes.push(display_node);
} else {
let root = createNode(props.selectedCourse.code, props.selectedCourse.code, "input");
let copy = JSON.parse(JSON.stringify(props.selectedCourse.prerequisites));
let root = createNode(props.selectedCourse?.code, props.selectedCourse?.code, "input");
let copy = JSON.parse(JSON.stringify(props.selectedCourse?.prerequisites));
let eligible = generateTree(JSON.parse(localStorage.getItem("completedCourses")), copy);
if (eligible) {
root["style"]["backgroundColor"] = "lightgreen";
Expand Down
5 changes: 4 additions & 1 deletion my-app/src/presenters/SidebarPresenter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,15 @@ const SidebarPresenter = observer(({ model }) => {
model.setFiltersChange();
}


function setApplyRemoveNullCourses(){
model.setApplyRemoveNullCourses();
}

return (
<SidebarView HandleFilterChange={HandleFilterChange}
HandleFilterEnable={HandleFilterEnable}
reApplyFilter={reApplyFilter}
toggleRemoveNull={setApplyRemoveNullCourses}
/>
);
});
Expand Down
11 changes: 11 additions & 0 deletions my-app/src/views/Components/SideBarComponents/ToolTip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";

const ToolTip = ({ text = "This is a tooltip description." }) => {
return (
<div className="absolute left-full ml-2 top-1/2 -translate-y-1/2 bg-gray-800 text-white text-xs rounded px-2 py-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200 z-10 whitespace-nowrap shadow-lg">
{text}
</div>
);
};

export default ToolTip;
36 changes: 36 additions & 0 deletions my-app/src/views/Components/SideBarComponents/ToolTipIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react";
import ToolTip from "./ToolTip";

const ToolTipIcon = ({ text = "This is a tooltip description." }) => {
return (
<div className="relative inline-block">
{/* Wrapper around just the icon for hover targeting */}
<div className="group relative inline-block">
{/* Question Mark Icon */}
<div className="p-1 rounded-lg">
<svg
className="w-5 h-5 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
{/* Circle */}
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="2" />
{/* Question mark path */}
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M12 8c0-1.105.895-2 2-2s2 .895 2 2c0 .828-.495 1.545-1.2 1.846C13.895 10.37 13 11.253 13 12.5m0 3h.01"
/>
</svg>
</div>

<ToolTip/>
</div>
</div>
);
};

export default ToolTipIcon;
6 changes: 3 additions & 3 deletions my-app/src/views/Components/SideBarComponents/UploadField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import FilterEnableCheckbox from "./FilterEnableCheckbox";
//import * as scraper from '../../../../src/scripts/transcript-scraper/transcript-scraper.js';
import { useState } from "react";
import ButtonGroupField from './ButtonGroupField';
import ToolTip from './ToolTip';
import ToolTipIcon from './ToolTipIcon';

export default function UploadField(props) {

Expand Down Expand Up @@ -55,9 +57,7 @@ export default function UploadField(props) {
</div>
<div className="mb-2 text-white flex justify-between">
<div className="flex items-center text-wrap max-w-70">
<p className='text-sm opacity-50'>
Describe how the Transcript upload works
</p>
<ToolTipIcon/>
</div>
<div className='pt-2'>

Expand Down
15 changes: 15 additions & 0 deletions my-app/src/views/SidebarView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ function SidebarView(props) {
]
}
/>
<div className='mr-3'>
<input
id="excludeNullCheckbox"
type="checkbox"
onChange={props.toggleRemoveNull}
className="w-4 h-4 pt-4 text-purple-600 bg-gray-100 border-gray-300 rounded-sm accent-violet-600"
/>
<label
htmlFor="excludeNullCheckbox"
className="ml-2 text-sm font-medium text-gray-300 cursor-pointer"
>
Exclude unidentified field courses
</label>

</div>
</div>

</div>
Expand Down
Loading