Add spinner and some other minor changes

This commit is contained in:
bkellam 2024-08-24 20:58:31 -07:00
parent 90b6256a4e
commit 0ae2030cb1

View file

@ -3,11 +3,12 @@
import Image from "next/image";
import logo from "../../public/sb_logo_large_3.png"
import { Input } from "@/components/ui/input"
import { useEffect, useRef, useState } from "react";
import { useEffect, useState } from "react";
import { useDebouncedCallback } from 'use-debounce';
import { Separator } from "@/components/ui/separator"
import { useRouter } from "next/navigation";
import { useNonEmptyQueryParam } from "@/hooks/useNonEmptyQueryParam";
import { SymbolIcon } from "@radix-ui/react-icons";
interface ZoekMatch {
URL: string,
@ -31,10 +32,14 @@ interface ZoekFileMatch {
interface ZoekResult {
QueryStr: string,
FileMatches: ZoekFileMatch[] | null,
Stats: {
// Duration in nanoseconds
Duration: number,
}
}
interface ZoekSearchResponse {
result: ZoekResult;
result: ZoekResult,
}
export default function Home() {
@ -46,15 +51,11 @@ export default function Home() {
const [numResults, _setNumResults] = useState(defaultNumResults && !isNaN(Number(defaultNumResults)) ? Number(defaultNumResults) : 100);
const [fileMatches, setFileMatches] = useState<ZoekFileMatch[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [searchDurationMs, setSearchDurationMs] = useState(0);
/**
* @note : when the user navigates backwards/forwards, the defaultQuery
* will update, but the query state will not. This effect keeps things in
* sync for that scenario.
*/
useEffect(() => {
setQuery(defaultQuery);
}, [defaultQuery]);
// @todo: We need to be able to handle the case when the user navigates backwards / forwards.
// Currently we do not re-query.
return (
<main className="flex h-screen flex-col">
@ -68,15 +69,23 @@ export default function Home() {
query={query}
numResults={numResults}
onQueryChange={(query) => setQuery(query)}
onLoadingChange={(isLoading) => setIsLoading(isLoading)}
onSearchResult={(result) => {
setFileMatches(result?.FileMatches ?? []);
if (result) {
setFileMatches(result.FileMatches ?? []);
setSearchDurationMs(Math.round(result.Stats.Duration / 1000000));
}
router.push(`?query=${query}&numResults=${numResults}`);
}}
/>
{isLoading && (
<SymbolIcon className="h-4 w-4 animate-spin" />
)}
</div>
<Separator />
<div className="bg-accent p-2">
<p className="text-sm font-medium">Results for: {fileMatches.length} files</p>
<p className="text-sm font-medium">Results for: {fileMatches.length} files in {searchDurationMs} ms</p>
</div>
<div className="flex flex-col gap-2">
{fileMatches.map((match, index) => (
@ -90,6 +99,7 @@ export default function Home() {
interface SearchBarProps {
query: string;
numResults: number;
onLoadingChange: (isLoading: boolean) => void;
onQueryChange: (query: string) => void;
onSearchResult: (result?: ZoekResult) => void,
}
@ -97,17 +107,21 @@ interface SearchBarProps {
const SearchBar = ({
query,
numResults,
onLoadingChange,
onQueryChange,
onSearchResult,
}: SearchBarProps) => {
const SEARCH_DEBOUNCE_MS = 200;
// @todo : we should probably be cancelling any running requests
const search = useDebouncedCallback((query: string) => {
if (query === "") {
onSearchResult(undefined);
return;
}
console.log('making query...');
onLoadingChange(true);
fetch(`http://localhost:3000/zoekt/search?query=${query}&numResults=${numResults}`)
.then(response => response.json())
.then(({ data }: { data: ZoekSearchResponse }) => {
@ -118,7 +132,8 @@ const SearchBar = ({
console.error('Error:', error);
}).finally(() => {
console.log('done making query');
})
onLoadingChange(false);
});
}, SEARCH_DEBOUNCE_MS);
useEffect(() => {