diff --git a/client/package-lock.json b/client/package-lock.json
index 43334ad..b82eb69 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -14,6 +14,7 @@
"chart.js": "^4.4.0",
"d3": "^7.8.5",
"date-fns": "^2.30.0",
+ "fuse.js": "^7.0.0",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",
"react-dom": "^18.2.0",
@@ -9161,6 +9162,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/fuse.js": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+ "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
diff --git a/client/package.json b/client/package.json
index 307aba4..4cdfbce 100644
--- a/client/package.json
+++ b/client/package.json
@@ -10,6 +10,7 @@
"chart.js": "^4.4.0",
"d3": "^7.8.5",
"date-fns": "^2.30.0",
+ "fuse.js": "^7.0.0",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",
"react-dom": "^18.2.0",
diff --git a/client/src/components/GameSessionList.tsx b/client/src/components/GameSessionList.tsx
index 347a1eb..330bc03 100644
--- a/client/src/components/GameSessionList.tsx
+++ b/client/src/components/GameSessionList.tsx
@@ -1,24 +1,47 @@
import "../styles/GameSessionList.css";
-import React, { useContext, useState } from "react";
+import React, { useContext, useEffect, useState } from "react";
import GameSessionCard from "./GameSessionCard";
import { GoodplaysContext } from "../models/GoodplaysContextType";
import AddGameSessionModal from "./AddGameSessionModal";
import { fetchGameSessions } from "../AppUtils";
import { faSync } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import Fuse from "fuse.js";
const GameSessionList: React.FC = () => {
const { gameSessions, setGameSessions, goodplaysUser } =
useContext(GoodplaysContext);
+ const [search, setSearch] = useState("");
+ const [searchResults, setSearchResults] = useState(gameSessions);
+
+ const fuseOptions = {
+ keys: ['gameName'],
+ includeScore: true,
+ threshold: 0.3,
+ };
+ const fuse = new Fuse(gameSessions, fuseOptions);
+ useEffect(() => {
+ if (search === '') {
+ setSearchResults(gameSessions);
+ } else {
+ const result = fuse.search(search);
+ const sortedResults = result.map(({ item }) => item).sort((a, b) => {
+ // Assuming endTimestamp is a Date object
+ return new Date(b.endTimestamp).getTime() - new Date(a.endTimestamp).getTime();
+ });
+ setSearchResults(sortedResults);
+ }
+ }, [search, gameSessions]);
+
const gamesPerPage = 5;
- const totalPages = Math.ceil(gameSessions.length / gamesPerPage);
+ const totalPages = Math.ceil(searchResults.length / gamesPerPage);
const paginate = (pageNumber: number) => {
const startIndex = (pageNumber - 1) * gamesPerPage;
const endIndex = startIndex + gamesPerPage;
- return gameSessions.slice(startIndex, endIndex);
+ return searchResults.slice(startIndex, endIndex);
};
const [currentPage, setCurrentPage] = useState(1);
@@ -81,6 +104,14 @@ const GameSessionList: React.FC = () => {
+ setSearch(e.target.value)}
+ placeholder="Search game sessions"
+ />
+
+
{currentGameSessions.map((session, index) => (
))}