Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 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
2d2a84a
rebase to main
kexana May 7, 2025
db72583
nice and beutiful
kexana May 7, 2025
a97fa17
rebase with main
kexana May 7, 2025
17cb87c
removed the explicit null string checks, hopefully doesnt break, also…
boldizsarbenedek May 7, 2025
4dc5311
period filter
kexana May 7, 2025
95b9000
a bit polishing, touching on the period presenter since i thought its…
boldizsarbenedek May 7, 2025
401ce83
fixed some filters logic (level filter, period filter), added descrip…
boldizsarbenedek May 8, 2025
20c98a5
visually persistent filters
kexana May 8, 2025
a0925dd
check period filter
kexana May 8, 2025
882f7a1
good filters merge
kexana May 8, 2025
3518e20
now fixed
kexana May 8, 2025
1ae1a5b
once again
kexana May 8, 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
3 changes: 2 additions & 1 deletion my-app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Find my course</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Course Compass</title>
</head>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
Expand Down
Binary file modified my-app/src/assets/project_icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added my-app/src/assets/project_icon1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 31 additions & 3 deletions my-app/src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@ export const model = {
user: undefined,
//add searchChange: false, //this is for reworking the searchbar presenter, so that it triggers as a model,
//instead of passing searchcouses lambda function down into the searchbarview.
/* courses returned from SearchbarPresenter (search is applied on top of filteredCourses[]) to be shown in the ListView */
currentSearch: [],
/* current query text */
currentSearchText: "",
scrollPosition: 0,
/* list of all course objects downloaded from the Firebase realtime database and stored locally as JSON object in this array */
courses: [],
/* courses the user selected as their favourite */
favourites: [],
isReady: false,
filtersChange: false,
/* this is a boolean flag showing that filtering options in the UI have changed, triggering the FilterPresenter to recalculate the filteredCourses[] */
filtersChange: false,
/* this is a flag showing if the filteredCourses[] has changed (since FilterPresenter recalculated it), so now SearchBarPresenter needs to
recalculate currentSearch[] depending this updated list of courses */
filtersCalculated: false,
filteredCourses: [],
/* this is the array that FilterPresenter fills up with course objects, filtered from the model.courses[] */
filteredCourses: [],
/* JSON object containing all important parameters the FilterPresenter needs to calculate the filtered list of courses */
filterOptions: {
//apply-X-Filter boolean triggering flag wether corresponding filtering functions should run or not
//different arrays require different data, some uses string arrays, some boolean values, and so on
applyTranscriptFilter: true,
eligibility: "weak", //the possible values for the string are: "weak"/"moderate"/"strong"
applyLevelFilter: true,
Expand All @@ -31,7 +42,9 @@ export const model = {
"ITM/Learning in Engineering Sciences", "ITM/Industrial Economics and Management", "ITM/Energy Systems", "ITM/Integrated Product Development and Design", "ITM/SKD GRU",
"SCI/Mathematics", "SCI/Applied Physics", "SCI/Mechanics", "SCI/Aeronautical and Vehicle Engineering",
"ABE/Sustainability and Environmental Engineering", "ABE/Concrete Structures", "ABE/Structural Design & Bridges", "ABE/History of Science, Technology and Environment", ],
applyRemoveNullCourses: false
applyRemoveNullCourses: false,
period: [true, true, true, true],
applyPeriodFilter: true
},

setUser(user) {
Expand Down Expand Up @@ -150,6 +163,11 @@ export const model = {
this.setFiltersChange();
},

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

updateLevelFilter(level) {
this.filterOptions.level = level;
},
Expand All @@ -172,6 +190,13 @@ export const model = {
this.filterOptions.eligibility = eligibility;
},

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

updatePeriodFilter(period) {
this.filterOptions.period = period;
},

setApplyTranscriptFilter(transcriptFilterState) {
this.filterOptions.applyTranscriptFilter = transcriptFilterState;
Expand All @@ -191,6 +216,9 @@ export const model = {
setApplyDepartmentFilter(departmentFilterState) {
this.filterOptions.applyDepartmentFilter = departmentFilterState;
},
setApplyPeriodFilter(periodfilterState) {
this.filterOptions.applyPeriodFilter = periodfilterState;
},
async getAverageRating(courseCode) {
const reviews = await getReviewsForCourse(courseCode);
if (!reviews || reviews.length === 0) return null;
Expand Down
84 changes: 62 additions & 22 deletions my-app/src/presenters/FilterPresenter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { observer } from "mobx-react-lite";
import eligibility from "../scripts/eligibility_refined.js";
import { SearchbarPresenter } from './SearchbarPresenter.jsx';

/* FilterPresenter is responsible for applying the logic necessary to filter out the courses from the overall list */
const FilterPresenter = observer(({ model }) => {
/* global variable for the scope of this presenter, all the smaller functions depend on it instead of passing it back and forth as params */
var localFilteredCourses = []; //might need to declare out of scope. idk js


function applyTranscriptEligibility() {
if (localFilteredCourses.length == 0)
return;
/* this elias thing */

/* */
const eligibilitytype = model.filterOptions.eligibility;

let strongcourses = [];
Expand All @@ -25,8 +28,6 @@ const FilterPresenter = observer(({ model }) => {


localFilteredCourses.forEach(course => {
//console.log(storedFinishedCourses);
//console.log(course?.prerequisites);
if (storedFinishedCourses.includes(course?.code))
return;
if (course?.prerequisites && (course?.prerequisites !== "null"))
Expand Down Expand Up @@ -72,13 +73,51 @@ const FilterPresenter = observer(({ model }) => {
}
default:
{
console.log("Error: somehow we got into a state where model.eligibility is no \"strong\"/\"moderat\"/\"weak\".");
console.log("Error: somehow we got into a state where model.eligibility is no \"strong\"/\"moderate\"/\"weak\".");
localFilteredCourses = [];
break;
}
}


}

function updatePeriods(){

if (localFilteredCourses.length == 0)
return;

const periodArr = [...model.filterOptions.period]; //has 4 boolean values one for each period
// [true, false, false, false] means we are only looking for P1 courses.
let bestcourses = [];
let worstcourses = [];
bestcourses = localFilteredCourses.filter(function (course){
try {
if(course?.periods === undefined)
return false;
if((course?.periods?.P1 == true) && (periodArr[0] == true))
return true;
if((course?.periods?.P2 == true) && (periodArr[1] == true))
return true;
if((course?.periods?.P3 == true) && (periodArr[2] == true))
return true;
if((course?.periods?.P4 == true) && (periodArr[3] == true))
return true;
return false;
} catch (error) {
console.log("for some reason course?.periods is weird: ", course?.periods, error);
return false;
}

})

worstcourses = localFilteredCourses.filter(function (course){
return (course?.periods === undefined);
})

localFilteredCourses = [...bestcourses, ...worstcourses];


}

function updateCredits() {
Expand Down Expand Up @@ -117,7 +156,7 @@ const FilterPresenter = observer(({ model }) => {
});
worstCourses = localFilteredCourses.filter(function (course) {
try {
return ((course?.location === undefined) || (course?.location === "null"));
return (course?.location === undefined);
} catch (error) {
console.log("BIG ERROR", error);
return false;
Expand All @@ -140,8 +179,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/undefined)
//course?.language.swedish (true/false/undefined)

//console.log(data);

Expand All @@ -166,7 +205,7 @@ const FilterPresenter = observer(({ model }) => {
);
worstCourses = data.filter(function (course) {
try {
return ((course?.language === undefined) || course?.language?.english === "null");
return (course?.language === undefined);
} catch (error) {
console.log(course);
console.log("BIG ERROR");
Expand All @@ -191,7 +230,7 @@ const FilterPresenter = observer(({ model }) => {
);
worstCourses = data.filter(function (course) {
try {
return ((course?.language === undefined) || course?.language?.swedish === "null");
return (course?.language === undefined);
} catch (error) {
console.log(course);
console.log("BIG ERROR");
Expand Down Expand Up @@ -228,7 +267,7 @@ const FilterPresenter = observer(({ model }) => {
);
worstCourses = data.filter(function (course) {
try {
return ((course?.language === undefined) || course?.language?.english === "null");
return (course?.language === undefined);
} catch (error) {
console.log(course);
console.log("BIG ERROR");
Expand Down Expand Up @@ -287,7 +326,7 @@ const FilterPresenter = observer(({ model }) => {
});
worstCourses = localFilteredCourses.filter(function (course) {
try {
return ((course?.department === undefined) || (course?.deparment === "null"));
return (course?.department === undefined);
} catch (error) {
console.log("BIG ERROR", error);
return false;
Expand All @@ -301,44 +340,42 @@ const FilterPresenter = observer(({ model }) => {
function updateNoNullcourses(){
let local = [...localFilteredCourses];

console.log("miauuuuu:",local.length);

if(model.filterOptions.applyPeriodFilter){
local = local.filter(function(course){
return (course?.periods && (course?.periods !== "null"));
})
}
if(model.filterOptions.applyTranscriptFilter){
local = local.filter(function(course){
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?.academicLevel && (course?.academicLevel !== "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")));
})
}
console.log("miauuuuu:",local.length);
/*if(model.filterOptions.applyLocationFilter){
if(model.filterOptions.applyLocationFilter){
local = local.filter(function(course){
return ((course?.location) && (course?.location !== "null"));
})
}*/
console.log("miauuuuu:",local.length);
}
if(model.filterOptions.applyCreditsFilter){
local = local.filter(function(course){
return ((course?.credits) && (course?.credits !== "null"));
})
}
console.log("miauuuuu:",local.length);
if(model.filterOptions.applyDepartmentFilter){
local = local.filter(function(course){
return ((course?.department) && (course?.department !== "null"));
})
}
console.log("miauuuuu:",local.length);

localFilteredCourses = [...local];
}
Expand All @@ -353,6 +390,9 @@ const FilterPresenter = observer(({ model }) => {
if (model.filterOptions.applyRemoveNullCourses) {
updateNoNullcourses();
}
if(model.filterOptions.applyPeriodFilter){
updatePeriods();
}
if (model.filterOptions.applyLocationFilter) {
//after deo finishes locations, until then dont

Expand All @@ -379,7 +419,7 @@ const FilterPresenter = observer(({ model }) => {
model.filteredCourses = [...localFilteredCourses];
model.filtersChange = false;
model.setFiltersCalculated();
console.log("filtered objects number of elements: ", model.filteredCourses.length);
//console.log("filtered objects number of elements: ", model.filteredCourses.length);
}
}

Expand Down
Loading