diff --git a/apps/website/components/blog-search/blog-search.tsx b/apps/website/components/blog-search/blog-search.tsx index f057966..d3b2b03 100644 --- a/apps/website/components/blog-search/blog-search.tsx +++ b/apps/website/components/blog-search/blog-search.tsx @@ -1,10 +1,59 @@ +import {useEffect, useState} from "react"; +import {BehaviorSubject, catchError, debounceTime, delay, distinctUntilChanged, filter, map, of, switchMap} from "rxjs"; +import {useRouter} from "next/router"; +import {MeiliSearch} from "meilisearch"; +import {useDispatch} from "react-redux"; + +import {environment} from "../../environments/environment"; + import styles from './blog-search.module.scss'; +import {setSearchState} from "../../store/searchSlice"; /* eslint-disable-next-line */ export interface BlogSearchProps { } export function BlogSearch(props: BlogSearchProps) { + const router = useRouter(); + const [client, setClient] = useState(null); + const [loading, setLoading] = useState(false); + const [subject, setSubject] = useState(null); + const dispatch = useDispatch(); + + useEffect(() => { + if (subject === null) { + const sub = new BehaviorSubject(''); + const client = new MeiliSearch({ + host: 'http://127.0.0.1:7700', + apiKey: environment.meiliMasterKey + }) + setSubject(sub); + setClient(client); + } else { + subject.pipe( + map((s: string) => s.trim()), + distinctUntilChanged(), + filter((s: string) => s.length >= 2), + debounceTime(200), + map((value) => { + setLoading(true); + return value; + }), + delay(2000), + switchMap(async (value: string) => { + const index = await client.getIndex('article'); + const articles = await index.search(value); + setLoading(false); + await router.push('/search'); + dispatch(setSearchState(articles.hits)); + }), + catchError((err) => of(false)) + ).subscribe(() => setLoading(false)); + } + }, [subject]); + + const onSearchChange = (e) => subject.next(e.target.value); + return (