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 { 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: FormEvent<HTMLFormElement>) => {
|
||||||
event.preventDefault();
|
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>
|
||||||
|
|
|
@ -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 });
|
||||||
|
|
17
app/utils.ts
17
app/utils.ts
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue