Skip to content

Commit 5db3cf1

Browse files
committed
Hopefully better search function
1 parent 0495e8c commit 5db3cf1

3 files changed

Lines changed: 90 additions & 43 deletions

File tree

my-app/package-lock.json

Lines changed: 63 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

my-app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"@xyflow/react": "^12.5.5",
1818
"autoprefixer": "^10.4.21",
1919
"firebase": "^11.5.0",
20+
"fuse.js": "^7.1.0",
2021
"ldrs": "^1.1.6",
22+
"lodash.debounce": "^4.0.8",
2123
"lodash.throttle": "^4.1.1",
2224
"mobx": "^6.13.7",
2325
"mobx-react-lite": "^4.1.0",

my-app/src/presenters/SearchbarPresenter.jsx

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,39 @@
1-
import React, { useEffect } from 'react';
1+
import React, { useEffect, useCallback } from 'react';
22
import { observer } from "mobx-react-lite";
33
import { useState } from 'react';
44
import CoursePagePopup from '../views/Components/CoursePagePopup.jsx';
55
import PrerequisitePresenter from './PrerequisitePresenter.jsx';
66
import { ReviewPresenter } from "../presenters/ReviewPresenter.jsx";
77
import SearchbarView from "../views/SearchbarView.jsx";
8+
import Fuse from 'fuse.js'
9+
import debounce from 'lodash.debounce';
810

911
const SearchbarPresenter = observer(({ model }) => {
1012

11-
const searchCourses = (query) => {
12-
//model.filteredCourses is essentially a smaller subset of model.courses, if theres no filters, it should be the same
13-
console.log("---------------search recalculated");
14-
console.log("filtered courses length: ", model.filteredCourses.length);
15-
const searchResults = model.filteredCourses.filter(course =>
16-
course.code.toLowerCase().includes(query.toLowerCase()) ||
17-
course.name.toLowerCase().includes(query.toLowerCase()) ||
18-
course.description?.toLowerCase().includes(query.toLowerCase())
19-
);
20-
model.setCurrentSearchText(query);
21-
model.setCurrentSearch(searchResults);
22-
console.log(model.currentSearch.length);
13+
const [searchQuery, setSearchQuery] = useState("");
14+
15+
const fuseOptions = {
16+
keys: [
17+
{ name: 'code', weight: 0.6 },
18+
{ name: 'name', weight: 0.3 },
19+
{ name: 'description', weight: 0.1 },
20+
],
21+
threshold: 0.3, // adjust this for sensitivity
22+
ignoreLocation: true,
23+
minMatchCharLength: 2,
2324
};
2425

26+
// Debounced search function
27+
const searchCourses = useCallback(debounce((query) => {
28+
if (!query.trim()) {
29+
model.setCurrentSearch(model.filteredCourses);
30+
} else {
31+
const fuse = new Fuse(model.filteredCourses, fuseOptions);
32+
const results = fuse.search(query).map((r) => r.item);
33+
model.setCurrentSearch(results);
34+
}
35+
}, 500), []);
36+
2537
const addFavourite = (course) => {
2638
model.addFavourite(course);
2739
};
@@ -54,7 +66,6 @@ const SearchbarPresenter = observer(({ model }) => {
5466
const [selectedCourse, setSelectedCourse] = useState(null);
5567
const preP = <PrerequisitePresenter model={model} selectedCourse={selectedCourse} />;
5668
const reviewPresenter = <ReviewPresenter model={model} course={selectedCourse} />;
57-
const [searchQuery, setSearchQuery] = useState("");
5869

5970
const popup = <CoursePagePopup
6071
favouriteCourses={model.favourites}

0 commit comments

Comments
 (0)