aboutsummaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
authorlonkaars <l.leblansch@gmail.com>2021-04-01 14:18:51 +0200
committerlonkaars <l.leblansch@gmail.com>2021-04-01 14:18:51 +0200
commitd2d813c04ce37cdb4a283dcd60b7986882970be5 (patch)
treeb22be2d5317c7e94169371fca962dd3fad92b5f0 /pages
parent98ceefd46d394c627edd35552b1f9e11f2f7926c (diff)
simple fuzzy search working
Diffstat (limited to 'pages')
-rw-r--r--pages/search.tsx52
1 files changed, 39 insertions, 13 deletions
diff --git a/pages/search.tsx b/pages/search.tsx
index 8053d4a..af9bfeb 100644
--- a/pages/search.tsx
+++ b/pages/search.tsx
@@ -1,21 +1,20 @@
import { useState, useEffect } from 'react';
+import Fuse from 'fuse.js';
import Navbar from '../components/navbar';
-import { FormEvent } from 'react';
-import { ArticleMeta } from './post/[id]';
import Tags from '../components/tag'
import SearchOutlinedIcon from '@material-ui/icons/SearchOutlined';
-function SearchBar(props: {
- searchFunction: (event?: FormEvent<HTMLFormElement>) => void;
-}) {
+function SearchBar(props: { searchFunction: () => void }) {
return <div className="searchBar">
- <form onSubmit={props.searchFunction}>
- <input className="input" placeholder="Search for posts..." autoComplete="off"/>
- <button className="button" onClick={() => props.searchFunction()}><SearchOutlinedIcon/></button>
- <input type="submit" style={{ display: "none" }}/>
- </form>
+ <input
+ className="input"
+ id="searchInput"
+ placeholder="Search for posts..."
+ onChange={() => props.searchFunction()}
+ autoComplete="off"/>
+ <button className="button" onClick={() => props.searchFunction()}><SearchOutlinedIcon/></button>
</div>
}
@@ -54,12 +53,39 @@ function Posts(props: { posts: Array<Post> }) {
export default function SearchPage() {
var [posts, setPosts] = useState<PostsInfo>({ posts: [], valid_tags: [] });
+ var [query, setQuery] = useState("");
+ var [visiblePosts, setVisiblePosts] = useState<Array<Post>>([]);
+
+ var fuse = new Fuse(posts.posts, {
+ keys: [
+ "title",
+ "subtitle",
+ "author",
+ "date",
+ "urlname",
+ "tags"
+ ],
+ isCaseSensitive: false
+ })
useEffect(() => {(async () => {
+ var query = new URLSearchParams(window.location.search).get("q") || "";
+ if(query)
+ (document.getElementById("searchInput") as HTMLInputElement).value = query;
+ setQuery(query);
+
var posts = await fetch("/posts.json");
setPosts(await posts.json());
})()}, []);
+ useEffect(() => {
+ if(query.length == 0) {
+ setVisiblePosts(posts.posts)
+ } else {
+ setVisiblePosts(fuse.search(query).map(res => res.item))
+ }
+ }, [query]);
+
return <div>
<div className="centeredPage">
<div className="titleWrapper">
@@ -71,10 +97,10 @@ export default function SearchPage() {
</div>
</div>
<div className="contentWrapper">
- <SearchBar searchFunction={(event?: FormEvent<HTMLFormElement>) => {
- event?.preventDefault();
+ <SearchBar searchFunction={() => {
+ setTimeout(() => setQuery((document.getElementById("searchInput") as HTMLInputElement).value));
}}/>
- <Posts posts={posts.posts}/>
+ <Posts posts={visiblePosts}/>
</div>
</div>
</div>