Skip to content

Commit 335641e

Browse files
authored
Fixes and sorting (#94)
* fixed summation after long fight with git :! * sorting kinda works - some problems exist * fixed search + filter interaction * sorting is better now / Metallic Materials are the only issue * asc/desc have correct icon now --------- Co-authored-by: Kacper Lisik <lisik@kth.se>
1 parent 35a0c52 commit 335641e

File tree

2 files changed

+58
-42
lines changed

2 files changed

+58
-42
lines changed

my-app/src/presenters/ListViewPresenter.jsx

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,35 @@ const ListViewPresenter = observer(({ model }) => {
7676

7777
const [isPopupOpen, setIsPopupOpen] = useState(false);
7878
const [selectedCourse, setSelectedCourse] = useState(null);
79+
const [sortBy, setSortBy] = useState('relevance');
80+
const [sortDirection, setSortDirection] = useState('desc');
81+
const [sortedCourses, setSortedCourses] = useState([]);
82+
83+
const sortCourses = (courses, sortType) => {
84+
if (!courses) return [];
85+
86+
const sortedCourses = [...courses];
87+
const direction = sortDirection === 'asc' ? 1 : -1;
88+
89+
switch (sortType) {
90+
case 'name':
91+
return sortedCourses.sort((a, b) =>
92+
direction * a.name.localeCompare(b.name));
93+
case 'credits':
94+
return sortedCourses.sort((a, b) =>
95+
direction * (parseFloat(a.credits) - parseFloat(b.credits)));
96+
case 'relevance':
97+
return direction === -1 ? sortedCourses : sortedCourses.reverse();
98+
default:
99+
return direction === 1 ? sortedCourses : sortedCourses.reverse();
100+
}
101+
};
102+
103+
useEffect(() => {
104+
const sorted = sortCourses(model.currentSearch, sortBy);
105+
setSortedCourses(sorted);
106+
}, [model.currentSearch, sortBy, sortDirection]);
107+
79108
const preP = <PrerequisitePresenter
80109
model={model}
81110
isPopupOpen={isPopupOpen}
@@ -98,9 +127,9 @@ const ListViewPresenter = observer(({ model }) => {
98127

99128

100129
return <ListView
101-
courses={model.courses}
102-
searchResults={model.currentSearch}
103-
currentSearchLenght={model.currentSearch.length}
130+
// courses={model.courses}
131+
// searchResults={model.currentSearch}
132+
// currentSearchLenght={model.currentSearch.length}
104133

105134
favouriteCourses={model.favourites}
106135
addFavourite={addFavourite}
@@ -117,6 +146,12 @@ const ListViewPresenter = observer(({ model }) => {
117146
scrollContainerRef={scrollContainerRef}
118147
persistantScrolling={persistantScrolling}
119148

149+
sortedCourses={sortedCourses}
150+
sortBy={sortBy}
151+
setSortBy={setSortBy}
152+
sortDirection={sortDirection}
153+
setSortDirection={setSortDirection}
154+
currentSearchLenght={sortedCourses.length}
120155
/>;
121156
});
122157

my-app/src/views/ListView.jsx

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import 'ldrs/react/Quantum.css';
44
import InfiniteScroll from 'react-infinite-scroll-component';
55

66
function ListView(props) {
7-
const coursesToDisplay = props.searchResults;
87
const [displayedCourses, setDisplayedCourses] = useState([]);
98
const [hasMore, setHasMore] = useState(true);
109
const [readMore, setReadMore] = useState({});
@@ -26,46 +25,30 @@ function ListView(props) {
2625
props.addFavourite(course);
2726
}
2827
};
29-
30-
const sortCourses = (courses, sortType) => {
31-
const sortedCourses = [...courses];
32-
const direction = sortDirection === 'asc' ? 1 : -1;
33-
34-
switch (sortType) {
35-
case 'name':
36-
return sortedCourses.sort((a, b) =>
37-
direction * a.name.localeCompare(b.name));
38-
case 'credits':
39-
return sortedCourses.sort((a, b) =>
40-
direction * (parseFloat(a.credits) - parseFloat(b.credits)));
41-
case 'relevance':
42-
default:
43-
return direction === 1 ? courses : [...courses].reverse();
44-
}
45-
};
4628

4729
useEffect(() => {
4830
setIsLoading(true);
49-
const sortedCourses = sortCourses(coursesToDisplay, sortBy);
50-
const initialCourses = sortedCourses.slice(0, 10);
31+
const initialCourses = props.sortedCourses.slice(0, 10);
5132
setDisplayedCourses(initialCourses);
52-
setHasMore(sortedCourses.length > 10);
33+
setHasMore(props.sortedCourses.length > 10);
5334
setIsLoading(false);
54-
}, [props.courses, props.searchResults, sortBy, sortDirection]);
35+
}, [props.sortedCourses]);
5536

5637
const fetchMoreCourses = useCallback(() => {
5738
if (!hasMore) return;
5839

59-
// Get the next batch of unsorted courses
60-
const nextItems = coursesToDisplay.slice(displayedCourses.length, displayedCourses.length + 50);
61-
62-
// Sort the combined courses (existing + new) to maintain consistency
63-
const allCourses = [...displayedCourses, ...nextItems];
64-
const sortedCourses = sortCourses(allCourses, sortBy);
40+
const nextItems = props.sortedCourses.slice(
41+
displayedCourses.length,
42+
displayedCourses.length + 50
43+
);
6544

66-
setDisplayedCourses(sortedCourses);
67-
setHasMore(displayedCourses.length + nextItems.length < coursesToDisplay.length);
68-
}, [displayedCourses.length, coursesToDisplay, hasMore, sortBy, sortDirection]);
45+
if (nextItems.length > 0) {
46+
setDisplayedCourses(prev => [...prev, ...nextItems]);
47+
setHasMore(displayedCourses.length + nextItems.length < props.sortedCourses.length);
48+
} else {
49+
setHasMore(false);
50+
}
51+
}, [displayedCourses.length, props.sortedCourses, hasMore]);
6952

7053
const [isRestoringScroll, setIsRestoringScroll] = useState(false);
7154
useEffect(() => {
@@ -82,7 +65,7 @@ function ListView(props) {
8265
}
8366
}, [props.targetScroll]);
8467

85-
if (!props.courses) {
68+
if (!props.sortedCourses) {
8669
return (
8770
<div className="relative bg-white text-black p-2 flex flex-col gap-5 h-screen">
8871
<div className="text-white p-4 text-center">
@@ -111,10 +94,8 @@ function ListView(props) {
11194

11295
<div className="flex items-center gap-2">
11396
<select
114-
value={sortBy}
115-
onChange={(e) => {
116-
setSortBy(e.target.value);
117-
}}
97+
value={props.sortBy}
98+
onChange={(e) => props.setSortBy(e.target.value)}
11899
className="bg-white border-2 border-[#000061] text-[#000061] font-semibold py-2 px-4 rounded-lg cursor-pointer hover:bg-blue-50 transition-colors duration-200"
119100
>
120101
<option value="relevance">Sort by Relevance</option>
@@ -123,11 +104,11 @@ function ListView(props) {
123104
</select>
124105

125106
<button
126-
onClick={() => setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc')}
107+
onClick={() => props.setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc')}
127108
className="bg-white border-2 border-[#000061] text-[#000061] font-semibold p-2 rounded-lg cursor-pointer hover:bg-blue-50 transition-colors duration-200"
128-
aria-label={`Sort ${sortDirection === 'asc' ? 'ascending' : 'descending'}`}
109+
aria-label={`Sort ${props.sortDirection === 'asc' ? 'ascending' : 'descending'}`}
129110
>
130-
{sortDirection === 'asc' ? (
111+
{props.sortDirection === 'desc' ? (
131112
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
132113
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
133114
</svg>

0 commit comments

Comments
 (0)