diff --git a/src/App.css b/src/App.css index 529d3a5..4409249 100644 --- a/src/App.css +++ b/src/App.css @@ -10,6 +10,11 @@ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; } +.search-highlight { + background-color: #FFFF00; + font-weight: normal; +} + /* html, body { font-family: monospace; unicode-range: U+0600-06FF; diff --git a/src/App.tsx b/src/App.tsx index 4a5fb61..86e75f3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,10 +22,7 @@ import { isProd } from "./lib/isProd"; import ReactGA from "react-ga"; import { useUser } from "./user-context"; import PrivacyPolicy from "./pages/PrivacyPolicy"; -// import algoliasearch from "algoliasearch"; - -// const client = algoliasearch('M5GQZF38JA', '1e3b529b909acf72fde1515f520f3913'); -// const index = client.initIndex('netlify_150beb8b-aae1-4cef-a05c-2add5d8904f7_master_all'); +import SearchPage from "./pages/SearchPage"; const chapters = content.reduce((chapters, item) => ( item.content @@ -64,33 +61,26 @@ function App() { logAnalytics(); // eslint-disable-next-line }, [window.location.pathname]); - // function handleSearch(s: string) { - // setSearch(s); - // index.search(s, { - // attributesToSnippet: [ - // "content:20", - // ], - // }).then(({ hits }) => { - // console.log(hits); - // }); - // } return ( <>
-
+
- {/* handleSearch(e.target.value)} value={search} /> */} } /> + } + /> } diff --git a/src/components/Header.jsx b/src/components/Header.jsx index 656571f..6750b38 100644 --- a/src/components/Header.jsx +++ b/src/components/Header.jsx @@ -28,6 +28,11 @@ function Header({ setNavOpen }) {

Pashto Grammar

+
+ + + +
diff --git a/src/pages/SearchPage.tsx b/src/pages/SearchPage.tsx new file mode 100644 index 0000000..cb15080 --- /dev/null +++ b/src/pages/SearchPage.tsx @@ -0,0 +1,102 @@ +import Link from "../components/Link"; +import Footer from "../components/Footer"; +import algoliasearch from "algoliasearch"; +import { useEffect, useState } from "react"; +import { createSearchParams, useSearchParams } from "react-router-dom"; + +const client = algoliasearch( + process.env.ALGOLIA_GRAMMAR_APP_ID || "", + process.env.ALGOLIA_GRAMMAR_API_KEY || "", +); +const index = client.initIndex(process.env.ALGOLIA_GRAMMAR_INDEX || ""); + +const SearchPage = () => { + const [search, setSearch] = useState(""); + const [results, setResults] = useState([]); + const [searchParams, setSearchParams] = useSearchParams(); + useEffect(() => { + const inParams = searchParams.get("search"); + if (inParams) { + setSearch(inParams); + doSearch(inParams); + } else { + setResults([]); + setSearch(""); + } + }, [window.location.search]); + function handleSearch(e: React.FormEvent) { + e.preventDefault(); + if (!search) return; + setSearchParams(createSearchParams({ + search, + })); + doSearch(search); + } + function doSearch(s: string) { + setResults("searching"); + index.search(s, { + attributesToSnippet: [ + "content:30", + ], + highlightPreTag: '', + highlightPostTag: '' + }).then(({ hits }) => { + setResults(hits.length ? hits : "none"); + }).catch(e => { + console.error(e); + alert("Connect to the internet to search"); + }); + } + return <> +
+

Search

+
+ setSearch(e.target.value)} + value={search} + /> +
+ +
+
+ {results === "none" + ?
No results found
+ : results === "searching" + ?

Searching...

+ : <> + {results.length > 0 &&
{`${results.length} result${results.length > 1 ? "s" : ""}`}
} + {results.map(result =>
+ +
+
{getHiearchy(result.hierarchy)}
+
+
+ +
)} + } + {/* + @ts-ignore */} +
+ ; +}; + +function getHiearchy(s: any): string { + const levels: string[] = [s.lvl0]; + for (let i = 1; i < 6; i++) { + const key = `lvl${i}`; + if (s[key]) { + levels.push(s[key]); + } else break; + } + return levels.join(" • "); +} + +export default SearchPage;