Skip to content

Commit a045323

Browse files
Responsive filtering quality of life improvements (#124)
* applied filters into the search function using flags in the model, will have to refine more in the filters, but this is great for the demo * wrote departments filter option * added check to make sure to not recommend courses the client has taken before * initial state good * departments go to model * trying to add filtering out courses with NULL fields as an implementable filter option, merging with main start as per teams request * merging into brain? * some ?. properties check, because skill issue * more course?. things * finished the noNull feature, essentially fixed typos * null course checkbox * null check linked * Null field toggle works * nice and beutiful * removed the explicit null string checks, hopefully doesnt break, also wrote logic for Period filtering * period filter * a bit polishing, touching on the period presenter since i thought its broken, but it was the database dropping all course.period data >:( * fixed some filters logic (level filter, period filter), added descriptions to most filters tooltips, fixed About us button, touched Tab title to current working title, fixed some other things * visually persistent filters * now fixed * once again * unlocking departments and locations * wip * filters enabled by clicking on them * My side merge with Dean's side * departments half functional * rebase to main * rebase to main --------- Co-authored-by: benedekboldizsar <bb.boldizsarbenedek@gmail.com>
1 parent a1fc345 commit a045323

15 files changed

Lines changed: 259 additions & 219 deletions

my-app/src/assets/upload.gif

58.8 KB
Loading

my-app/src/model.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const model = {
1717
departments : [],
1818
locations: [],
1919
avgRatings: [],
20+
/* courses the user selected as their favourite */
2021
favourites: [],
2122
searchHistory:[],
2223
isReady: false,
@@ -31,18 +32,19 @@ export const model = {
3132
filterOptions: {
3233
//apply-X-Filter boolean triggering flag wether corresponding filtering functions should run or not
3334
//different arrays require different data, some uses string arrays, some boolean values, and so on
34-
applyTranscriptFilter: true,
35+
applyTranscriptFilter: false,
3536
eligibility: "weak", //the possible values for the string are: "weak"/"moderate"/"strong"
3637
applyLevelFilter: true,
3738
level: ["PREPARATORY", "BASIC", "ADVANCED", "RESEARCH"], //the possible values for the array are: "PREPARATORY", "BASIC", "ADVANCED", "RESEARCH"
38-
applyLanguageFilter: true,
39+
applyLanguageFilter: false,
3940
language: "none", //the possible values for the string are: "none"/"english"/"swedish"/"both"
40-
applyLocationFilter:true,
41+
applyLocationFilter:false,
4142
location: [], //the possible values for the array are: 'KTH Campus', 'KTH Kista', 'AlbaNova', 'KTH Flemingsberg', 'KTH Solna', 'KTH Södertälje', 'Handelshögskolan', 'KI Solna', 'Stockholms universitet', 'KONSTFACK'
4243
applyCreditsFilter:true,
4344
creditMin: 0,
4445
creditMax: 45,
45-
applyDepartmentFilter: true,
46+
applyDepartmentFilter: false,
47+
department: [],
4648
applyRemoveNullCourses: false,
4749
period: [true, true, true, true],
4850
applyPeriodFilter: true
@@ -209,6 +211,7 @@ export const model = {
209211

210212
updateLevelFilter(level) {
211213
this.filterOptions.level = level;
214+
console.log(level);
212215
},
213216

214217
updateDepartmentFilter(department) {
@@ -258,6 +261,29 @@ export const model = {
258261
setApplyPeriodFilter(periodfilterState) {
259262
this.filterOptions.applyPeriodFilter = periodfilterState;
260263
},
264+
//for better display we would like the departments in a structured format based on school
265+
formatDepartments() {
266+
const grouped = this.departments?.reduce((acc, item) => {
267+
const [school, department] = item.split("/");
268+
if (!acc[school]) {
269+
acc[school] = [];
270+
}
271+
acc[school].push(department?.trim());
272+
return acc;
273+
}, {});
274+
const sortedGrouped = Object.keys(grouped)
275+
.sort()
276+
.reduce((acc, key) => {
277+
acc[key] = grouped[key].sort();
278+
return acc;
279+
}, {});
280+
const fields = Object.entries(sortedGrouped).map(([school, departments], index) => ({
281+
id: index + 1,
282+
label: school,
283+
subItems: departments,
284+
}));
285+
return fields;
286+
},
261287
async getAverageRating(courseCode) {
262288
const reviews = await getReviewsForCourse(courseCode);
263289
if (!reviews || reviews.length === 0) return null;

my-app/src/pages/App.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ function App({ model }) {
1616

1717
return (
1818
/* The sidebar styling(under the menu)*/
19-
<div className=" flex h-screen w-screen bg-[#6246a8] ">
19+
<div className=" flex h-screen w-screen bg-gradient-to-t from-[#4f3646] to-[#6747c0] overflow-hidden">
2020
{ /* If sidebar is open, set length to 400px, else it should not be visible */}
21-
<div className={`${sidebarIsOpen ? 'w-[400px]' : ''}`}>
21+
<div className={`${sidebarIsOpen ? 'w-[400px] min-w-[300px]' : 'w-[50px]'}`}>
2222
<Menu
23-
width={400}
24-
isOpen={model.sidebarIsOpen}
23+
width={window.innerWidth<700?'100%':Math.max(window.innerWidth * 0.26, 300)}
24+
isOpen={sidebarIsOpen}
2525
onStateChange={(state) => setSidebarIsOpen(state.isOpen)}
26-
className="bg-gradient-to-t from-[#6246a8] to-[#6747c0] z-0 h-screen"
26+
className="bg-gradient-to-t from-[#4f3646] to-[#6747c0] z-0 "
2727
noOverlay
2828
styles={{
2929
bmMenuWrap: {
@@ -32,7 +32,7 @@ function App({ model }) {
3232
bmBurgerButton: {
3333
position: 'absolute',
3434
top: '20px',
35-
left: '20px',
35+
left: '8px',
3636
width: '36px',
3737
height: '30px',
3838
zIndex: '20'

my-app/src/presenters/FilterPresenter.jsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ const FilterPresenter = observer(({ model }) => {
147147

148148
bestCourses = localFilteredCourses.filter(function (course) {
149149
try {
150-
return (locations.includes(course?.location));
150+
return (locations.includes(course?.location.toUpperCase()));
151151
} catch (error) {
152-
console.log("for some reason course?.location is: ", course?.location, error);
152+
console.log("for some reason course?.location is: ", course, error);
153153
return false;
154154
}
155155

@@ -394,10 +394,7 @@ const FilterPresenter = observer(({ model }) => {
394394
updatePeriods();
395395
}
396396
if (model.filterOptions.applyLocationFilter) {
397-
//after deo finishes locations, until then dont
398-
399-
//console.log("going to apply location on:",localFilteredCourses.length);
400-
//updateLocations();
397+
updateLocations();
401398
}
402399
if (model.filterOptions.applyLevelFilter) {
403400
updateLevels();
@@ -412,8 +409,7 @@ const FilterPresenter = observer(({ model }) => {
412409
applyTranscriptEligibility();
413410
}
414411
if (model.filterOptions.applyDepartments) {
415-
//console.log("going to apply location on:",localFilteredCourses.length);
416-
//updateDepartments();
412+
updateDepartments();
417413
}
418414

419415
model.filteredCourses = [...localFilteredCourses];

my-app/src/presenters/PrerequisitePresenter.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ export const PrerequisitePresenter = observer((props) => {
462462
let key = Object.keys(prereqs);
463463
if (prereqs[key] === true) {
464464
return true;
465-
} else {
465+
}
466+
else {
466467
return false;
467468
}
468469

my-app/src/presenters/SidebarPresenter.jsx

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ const SidebarPresenter = observer(({ model }) => {
77

88
useEffect(() => {
99
model.setFiltersChange();
10-
})
10+
});
1111

1212
let currentLanguageSet = model.filterOptions.language;
1313
let currentLevelSet = model.filterOptions.level;
1414
let currentPeriodSet = model.filterOptions.period;
15-
let currentDepartmentSet = [
16-
"EECS/Computational Science and Technology", "EECS/Theoretical Computer Science", "EECS/Electric Power and Energy Systems", "EECS/Network and Systems Engineering",
17-
"ITM/Learning in Engineering Sciences", "ITM/Industrial Economics and Management", "ITM/Energy Systems", "ITM/Integrated Product Development and Design", "ITM/SKD GRU",
18-
"SCI/Mathematics", "SCI/Applied Physics", "SCI/Mechanics", "SCI/Aeronautical and Vehicle Engineering",
19-
"ABE/Sustainability and Environmental Engineering", "ABE/Concrete Structures", "ABE/Structural Design & Bridges", "ABE/History of Science, Technology and Environment",
20-
]
15+
let currentDepartmentSet = model.filterOptions.department;
16+
let currentLocationSet = model.filterOptions.location
2117

2218
function handleLanguageFilterChange(param) {
2319
if (param === "English") {
@@ -58,26 +54,11 @@ const SidebarPresenter = observer(({ model }) => {
5854
model.updateLanguageFilter(currentLanguageSet);
5955
}
6056
function handleLevelFilterChange(param) {
61-
let properParam;
62-
switch (param) {
63-
case "Preparatory":
64-
properParam = "PREPARATORY";
65-
break;
66-
case "Basic":
67-
properParam = "BASIC";
68-
break;
69-
case "Advanced":
70-
properParam = "ADVANCED";
71-
break;
72-
case "Research":
73-
properParam = "RESEARCH";
74-
break;
75-
}
7657

77-
if (!currentLevelSet.includes(properParam)) {
78-
currentLevelSet.push(properParam);
58+
if (!currentLevelSet.includes(param)) {
59+
currentLevelSet.push(param);
7960
} else {
80-
const index = currentLevelSet.indexOf(properParam);
61+
const index = currentLevelSet.indexOf(param);
8162
if (index > -1) {
8263
currentLevelSet.splice(index, 1);
8364
}
@@ -104,6 +85,19 @@ const SidebarPresenter = observer(({ model }) => {
10485
model.setFiltersChange();
10586
}
10687

88+
function handleLocationFilterChange(param) {
89+
if (currentLocationSet.includes(param)) {
90+
const index = currentLocationSet.indexOf(param);
91+
if (index > -1) {
92+
currentLocationSet.splice(index, 1);
93+
}
94+
} else {
95+
currentLocationSet.push(param);
96+
}
97+
model.updateLocationFilter(currentLocationSet);
98+
model.setFiltersChange();
99+
}
100+
107101
/*HandleFilterChange param is structured as such
108102
[
109103
type of the field: (toggle, slider, dropdown, buttongroup)
@@ -120,7 +114,7 @@ const SidebarPresenter = observer(({ model }) => {
120114
handleLevelFilterChange(param[2]);
121115
break;
122116
case "location":
123-
console.log("location filter set to: " + param[2]);
117+
handleLocationFilterChange(param[2]);
124118
break;
125119
case "credits":
126120
model.updateCreditsFilter(param[2]);
@@ -130,6 +124,7 @@ const SidebarPresenter = observer(({ model }) => {
130124
break;
131125
case "department":
132126
handleDepartmentFilterChange(param[2]);
127+
console.log(param[2]);
133128
break;
134129
case "period":
135130
handlePeriodFilterChange(param[2]);
@@ -194,20 +189,30 @@ const SidebarPresenter = observer(({ model }) => {
194189
HandleFilterEnable={HandleFilterEnable}
195190
reApplyFilter={reApplyFilter}
196191
toggleRemoveNull={setApplyRemoveNullCourses}
192+
197193
initialApplyTranscriptFilter={model.filterOptions.applyTranscriptFilter}
198-
initialTranscriptElegiblityValue = {model.filterOptions.eligibility}
194+
initialTranscriptElegiblityValue={model.filterOptions.eligibility}
195+
199196
initialLanguageFilterOptions={currentLanguageSet}
200197
initialLanguageFilterEnable={model.filterOptions.applyLanguageFilter}
198+
201199
initialLevelFilterOptions={currentLevelSet}
202200
initialLevelFilterEnable={model.filterOptions.applyLevelFilter}
201+
203202
initialPeriodFilterOptions={currentPeriodSet}
204203
initialPeriodFilterEnable={model.filterOptions.applyPeriodFilter}
204+
205205
initialDepartmentFilterOptions={currentDepartmentSet}
206206
initialDepartmentFilterEnable={model.filterOptions.applyDepartmentFilter}
207-
initialLocationFilterOptions={[]}
207+
DepartmentFilterField = {model.formatDepartments()}
208+
209+
initialLocationFilterOptions={currentLocationSet}
208210
initialLocationFilterEnable={model.filterOptions.applyLocationFilter}
211+
LocationFilterField = {model.locations}
212+
209213
initialCreditsFilterOptions={[model.filterOptions.creditMin, model.filterOptions.creditMax]}
210214
initialCreditsFilterEnable={model.filterOptions.applyCreditsFilter}
215+
211216
initialApplyNullFilterEnable={model.filterOptions.applyRemoveNullCourses }
212217
/>
213218
);

0 commit comments

Comments
 (0)