search_awesome/islands/Search.tsx
2022-12-01 19:40:03 +09:00

67 lines
2.0 KiB
TypeScript

import { useEffect, useState } from "preact/hooks";
import { RepoData } from "../api/repo.ts";
import { SearchBar } from "../components/SearchBar.tsx";
import RepoViewer from "./RepoViewer.tsx";
export default function Search(props:{query?: string}) {
const [searchValue, setSearchValue] = useState(props.query ?? "");
const [searchResults, setSearchResults] = useState<RepoData[] | null>(null);
useEffect(() => {
// on mount
search(searchValue);
}, [])
useEffect(() => {
const callback = (ev: PopStateEvent)=>{
// pop state
if(ev.state && ev.state.q){
const q = ev.state.q;
setSearchValue(q);
search(q);
}
else{
setSearchValue("");
search("");
}
}
addEventListener("popstate", callback);
return ()=>{
removeEventListener("popstate", callback);
}
}, []);
useEffect(() => {
if (searchValue) {
document.title = `Search: ${searchValue}`;
} else {
document.title = "Search";
}
},[searchValue]);
return (<>
<SearchBar value={searchValue} onChange={(v) => {setSearchValue(v)}} onSubmit={()=>{
//window.location.href = `/?q=${searchValue}`;
history.pushState({q:searchValue}, "", `/?q=${searchValue}`);
search(searchValue);
}} />
<RepoViewer repos={searchResults ?? []} />
</>);
function search(searchValue: string) {
if (searchValue) {
console.log("searching", searchValue);
fetch(`/api/_query?q=${searchValue}`)
.then((res) => res.json())
.then((data) => {
setSearchResults(data);
}
);
} else {
fetch(`/api/_list`)
.then((res) => res.json())
.then((data) => {
setSearchResults(data);
}
);
}
}
}