feat: implement filtering in search page
This commit is contained in:
parent
35ca7b1ea5
commit
446131bf47
|
@ -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 {
|
||||
Select,
|
||||
|
@ -31,19 +31,43 @@ const SimplifiedSearchBar = ({
|
|||
let navigate = useNavigate();
|
||||
let location = useLocation();
|
||||
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: FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
doSearch();
|
||||
},
|
||||
[value]
|
||||
);
|
||||
|
||||
function doSearch() {
|
||||
const newSearchParams = new URLSearchParams(location.search);
|
||||
|
||||
if (value) {
|
||||
newSearchParams.set("q", value);
|
||||
} else {
|
||||
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}`);
|
||||
};
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
doSearch();
|
||||
}, [selectedSite, selectedTime]);
|
||||
|
||||
return (
|
||||
<form
|
||||
|
@ -72,9 +96,9 @@ const SimplifiedSearchBar = ({
|
|||
</div>
|
||||
<div className="w-56 flex gap-2">
|
||||
{/* Dropdown component should be here */}
|
||||
<SitesCombobox siteList={sites} />
|
||||
<SitesCombobox siteList={sites} onSiteSelect={setSelectedSite} />
|
||||
{/* Dropdown component should be here */}
|
||||
<Select defaultValue={"0"}>
|
||||
<Select defaultValue={"0"} onValueChange={(v) => setSelectedTime(v)}>
|
||||
<SelectTrigger className="hover:bg-muted w-auto">
|
||||
<SelectValue placeholder="Time ago" />
|
||||
</SelectTrigger>
|
||||
|
|
|
@ -16,7 +16,9 @@ export let loader: LoaderFunction = async ({ request }) => {
|
|||
const sites = getAvailableSites();
|
||||
const search = new URL(request.url).searchParams;
|
||||
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 json({ sites, results, query });
|
||||
|
|
17
app/utils.ts
17
app/utils.ts
|
@ -23,14 +23,29 @@ export const formatDate = (date: string | Date) => {
|
|||
|
||||
export async function getResults({
|
||||
query,
|
||||
site,
|
||||
time,
|
||||
}: {
|
||||
query?: string;
|
||||
site?: string;
|
||||
time?: string;
|
||||
}): Promise<SearchResult[]> {
|
||||
if (!query) {
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue