diff options
author | lonkaars <l.leblansch@gmail.com> | 2021-04-01 14:18:51 +0200 |
---|---|---|
committer | lonkaars <l.leblansch@gmail.com> | 2021-04-01 14:18:51 +0200 |
commit | d2d813c04ce37cdb4a283dcd60b7986882970be5 (patch) | |
tree | b22be2d5317c7e94169371fca962dd3fad92b5f0 /pages | |
parent | 98ceefd46d394c627edd35552b1f9e11f2f7926c (diff) |
simple fuzzy search working
Diffstat (limited to 'pages')
-rw-r--r-- | pages/search.tsx | 52 |
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> |