feat: implement site filter

This commit is contained in:
Derrick Hammer 2023-12-23 06:42:46 -05:00
parent 0ad37ad433
commit 0c404bd3b1
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
3 changed files with 49 additions and 33 deletions

View File

@ -7,21 +7,14 @@ import React, {
useRef,
useState,
} from "react";
import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline"; // Assuming usage of Heroicons for icons
import { ChevronRightIcon } from "@heroicons/react/24/outline"; // Assuming usage of Heroicons for icons
import { flushSync } from "react-dom";
import {
Link,
useFetcher,
useLocation,
useNavigate,
useSearchParams,
} from "@remix-run/react";
import { FILTER_TIMES, formatDate, getResults } from "@/utils";
import { Link, useFetcher, useSearchParams } from "@remix-run/react";
import { FILTER_TIMES, formatDate } from "@/utils";
import {
Select,
SelectContent,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "./ui/select";
@ -31,8 +24,6 @@ import { SearchResult, SiteList } from "@/types.js";
type Props = {};
const SearchBar = ({ sites }: { sites: SiteList }) => {
let navigate = useNavigate();
let { pathname } = useLocation();
let [searchParams] = useSearchParams();
const [query, setQuery] = useState(searchParams.get("q") ?? "");
const inputRef = useRef<HTMLInputElement>();
@ -40,29 +31,36 @@ const SearchBar = ({ sites }: { sites: SiteList }) => {
const [activeInput, setActiveInput] = useState(true);
const [dirtyInput, setDirtyInput] = useState(false);
const [results, setResults] = useState<SearchResult[]>([]);
const [selectedSite, setSelectedSite] = useState(null);
const fetcher = useFetcher();
const fetcher = useFetcher({ key: "seach" });
const handleSearch = useCallback(
async (event: FormEvent<HTMLFormElement>) => {
(event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setIsLoading(true);
let newSearchParams = new URLSearchParams(searchParams.toString());
if (query) {
newSearchParams.set("q", query);
} else {
newSearchParams.delete("q");
return;
}
navigate(`${pathname}?${newSearchParams.toString()}`);
fetcher.load(`/api/search?${newSearchParams}`);
doSearch();
},
[query, searchParams, navigate, pathname]
[query, selectedSite]
);
function doSearch() {
setIsLoading(true);
let newSearchParams = new URLSearchParams(searchParams.toString());
if (query) {
newSearchParams.set("q", query);
} else {
newSearchParams.delete("q");
return;
}
if (selectedSite) {
newSearchParams.set("site", selectedSite);
}
fetcher.load(`/api/search?${newSearchParams}`);
}
useEffect(() => {
if (fetcher.data) {
setResults(fetcher.data as SearchResult[]);
@ -71,6 +69,10 @@ const SearchBar = ({ sites }: { sites: SiteList }) => {
}
}, [fetcher.data]);
useEffect(() => {
doSearch();
}, [selectedSite]);
const isActive = results.length > 0 || dirtyInput;
return (
@ -155,7 +157,7 @@ const SearchBar = ({ sites }: { sites: SiteList }) => {
) : (
<div className="justify-self-end min-w-[220px] flex justify-end gap-2">
{/* Dropdown component should be here */}
<SitesCombobox siteList={sites} />
<SitesCombobox siteList={sites} onSiteSelect={setSelectedSite} />
{/* Dropdown component should be here */}
<Select defaultValue={"0"}>
<SelectTrigger className="hover:bg-muted w-auto">

View File

@ -17,8 +17,15 @@ import {
import { ChevronDownIcon } from "@heroicons/react/24/solid";
import { SelectOptions, SiteList } from "@/types.js";
import slugify from "slugify";
import { useEffect } from "react";
export function SitesCombobox({ siteList }: { siteList: SiteList }) {
export function SitesCombobox({
siteList,
onSiteSelect,
}: {
siteList: SiteList;
onSiteSelect: React.Dispatch<React.SetStateAction<any>>;
}) {
const sites = Object.entries(siteList).map((item) => {
return {
label: item[1].name,
@ -30,6 +37,10 @@ export function SitesCombobox({ siteList }: { siteList: SiteList }) {
null
);
useEffect(() => {
onSiteSelect(selectedSite?.value as any);
}, [selectedSite]);
return (
<div className="flex flex- items-center space-x-4">
<Popover open={open} onOpenChange={setOpen}>
@ -55,8 +66,7 @@ export function SitesCombobox({ siteList }: { siteList: SiteList }) {
value={status.value}
onSelect={(value) => {
setSelectedSite(
sites.find((priority) => priority.value === value) ||
null
sites.find((site) => site.value === value) || null
);
setOpen(false);
}}

View File

@ -12,7 +12,11 @@ export async function loader({ request }: LoaderFunctionArgs) {
});
}
const results = await search.index("articles").search(query);
const site = searchParams.get("site");
const results = await search.index("articles").search(query, {
filter: site ? `siteKey = ${site}` : undefined,
});
return results.hits.map((item) => {
return {