feat: implement real search

This commit is contained in:
Derrick Hammer 2023-12-23 05:51:12 -05:00
parent 9b964dd4f4
commit 0ad37ad433
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
3 changed files with 40 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
import { flushSync } from "react-dom";
import {
Link,
useFetcher,
useLocation,
useNavigate,
useSearchParams,
@ -40,6 +41,8 @@ const SearchBar = ({ sites }: { sites: SiteList }) => {
const [dirtyInput, setDirtyInput] = useState(false);
const [results, setResults] = useState<SearchResult[]>([]);
const fetcher = useFetcher();
const handleSearch = useCallback(
async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
@ -50,22 +53,24 @@ const SearchBar = ({ sites }: { sites: SiteList }) => {
newSearchParams.set("q", query);
} else {
newSearchParams.delete("q");
return;
}
navigate(`${pathname}?${newSearchParams.toString()}`);
// Perform search and update results state
// const searchResults = await fetchResults(query);
// Mock the search results
const searchResults = await getResults({ query });
setResults(searchResults);
setIsLoading(false);
setActiveInput(false);
fetcher.load(`/api/search?${newSearchParams}`);
},
[query, searchParams, navigate, pathname]
);
useEffect(() => {
if (fetcher.data) {
setResults(fetcher.data as SearchResult[]);
setIsLoading(false);
setActiveInput(false);
}
}, [fetcher.data]);
const isActive = results.length > 0 || dirtyInput;
return (

View File

@ -9,13 +9,10 @@ import {
} from "@remix-run/react";
import Header from "@/components/LayoutHeader"; // Adjust the import path as needed
import Footer from "@/components/LayoutFooter"; // Adjust the import path as needed
import globalStyles from "../styles/global.scss?inline";
import { cssBundleHref } from "@remix-run/css-bundle"; // Adjust the import path as needed
import globalStyles from "../styles/global.scss?url";
export const links: LinksFunction = () => [
{ rel: "stylesheet", href: globalStyles },
...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
// Add your Google font links here
// Example: { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Be+Vietnam+Pro:wght@400&display=swap" },
// Example: { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Jaldi:wght@400&display=swap" },

26
app/routes/api.search.ts Normal file
View File

@ -0,0 +1,26 @@
import { type LoaderFunctionArgs } from "@remix-run/node";
import search from "@/lib/search.js";
export async function loader({ request }: LoaderFunctionArgs) {
const searchParams = new URL(request.url).searchParams;
const query = searchParams.get("q");
if (!query || !query.length) {
throw new Response("Invalid query", {
status: 400,
});
}
const results = await search.index("articles").search(query);
return results.hits.map((item) => {
return {
id: item.id,
timestamp: item.createdAt,
title: item.title,
description: "",
slug: item.slug,
};
});
}