feat: implement filtering in search page

This commit is contained in:
Derrick Hammer 2023-12-23 07:28:52 -05:00
parent 35ca7b1ea5
commit 446131bf47
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
3 changed files with 49 additions and 8 deletions

View File

@ -1,4 +1,4 @@
import React, { FormEvent, useState } from "react"; import React, { FormEvent, useCallback, useEffect, useState } from "react";
import { useLocation, useNavigate } from "@remix-run/react"; import { useLocation, useNavigate } from "@remix-run/react";
import { import {
Select, Select,
@ -31,19 +31,43 @@ const SimplifiedSearchBar = ({
let navigate = useNavigate(); let navigate = useNavigate();
let location = useLocation(); let location = useLocation();
const [value, setValue] = useState<string>(initialValue); const [value, setValue] = useState<string>(initialValue);
const [selectedSite, setSelectedSite] = useState<any>(null);
const [selectedTime, setSelectedTime] = useState<string | null>(null);
const handleSearch = (event: FormEvent<HTMLFormElement>) => { const handleSearch = useCallback(
event.preventDefault(); (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
doSearch();
},
[value]
);
function doSearch() {
const newSearchParams = new URLSearchParams(location.search); const newSearchParams = new URLSearchParams(location.search);
if (value) { if (value) {
newSearchParams.set("q", value); newSearchParams.set("q", value);
} else { } else {
newSearchParams.delete("q"); newSearchParams.delete("q");
return;
}
if (selectedSite) {
newSearchParams.set("site", selectedSite);
}
if (selectedTime) {
const timestampInMilliseconds = Date.parse(selectedTime); // Date.parse returns the timestamp in milliseconds
const timestamp = timestampInMilliseconds / 1000;
newSearchParams.set("time", timestamp.toString());
} }
navigate(`${location.pathname}?${newSearchParams}`); navigate(`${location.pathname}?${newSearchParams}`);
}; }
useEffect(() => {
doSearch();
}, [selectedSite, selectedTime]);
return ( return (
<form <form
@ -72,9 +96,9 @@ const SimplifiedSearchBar = ({
</div> </div>
<div className="w-56 flex gap-2"> <div className="w-56 flex gap-2">
{/* Dropdown component should be here */} {/* Dropdown component should be here */}
<SitesCombobox siteList={sites} /> <SitesCombobox siteList={sites} onSiteSelect={setSelectedSite} />
{/* Dropdown component should be here */} {/* Dropdown component should be here */}
<Select defaultValue={"0"}> <Select defaultValue={"0"} onValueChange={(v) => setSelectedTime(v)}>
<SelectTrigger className="hover:bg-muted w-auto"> <SelectTrigger className="hover:bg-muted w-auto">
<SelectValue placeholder="Time ago" /> <SelectValue placeholder="Time ago" />
</SelectTrigger> </SelectTrigger>

View File

@ -16,7 +16,9 @@ export let loader: LoaderFunction = async ({ request }) => {
const sites = getAvailableSites(); const sites = getAvailableSites();
const search = new URL(request.url).searchParams; const search = new URL(request.url).searchParams;
const query = search.get("q") ?? ""; const query = search.get("q") ?? "";
const results = await getResults({ query: query }); const site = search.get("site") ?? undefined;
const time = search.get("time") ?? undefined;
const results = await getResults({ query: query, site, time });
// Return the fetched data as JSON // Return the fetched data as JSON
return json({ sites, results, query }); return json({ sites, results, query });

View File

@ -23,14 +23,29 @@ export const formatDate = (date: string | Date) => {
export async function getResults({ export async function getResults({
query, query,
site,
time,
}: { }: {
query?: string; query?: string;
site?: string;
time?: string;
}): Promise<SearchResult[]> { }): Promise<SearchResult[]> {
if (!query) { if (!query) {
return []; return [];
} }
const results = await search.index("articles").search(query); let filters = [];
if (site) {
filters.push(`siteKey = ${site}`);
}
if (time) {
filters.push(`createdTimestamp >= ${parseInt(time).toString()}`);
}
const results = await search.index("articles").search(query, {
filter: filters.length ? filters.join(" AND ") : undefined,
});
return results.hits.map((item) => { return results.hits.map((item) => {
return { return {