frigate/web/src/pages/Search.tsx

89 lines
2.9 KiB
TypeScript
Raw Normal View History

import SearchFilterGroup from "@/components/filter/SearchFilterGroup";
2024-06-22 02:05:59 +03:00
import SearchThumbnailPlayer from "@/components/player/SearchThumbnailPlayer";
2024-06-22 01:15:06 +03:00
import { Input } from "@/components/ui/input";
import { Toaster } from "@/components/ui/sonner";
2024-06-22 02:05:59 +03:00
import { SearchResult } from "@/types/search";
import { useEffect, useState } from "react";
2024-06-22 01:15:06 +03:00
import { LuSearchCheck } from "react-icons/lu";
2024-06-22 02:05:59 +03:00
import useSWR from "swr";
2024-06-22 01:15:06 +03:00
export default function Search() {
2024-06-22 02:05:59 +03:00
// search field handler
const [searchTimeout, setSearchTimeout] = useState<NodeJS.Timeout>();
const [search, setSearch] = useState("");
2024-06-22 01:15:06 +03:00
const [searchTerm, setSearchTerm] = useState("");
2024-06-22 02:05:59 +03:00
// search api
useEffect(() => {
if (searchTimeout) {
clearTimeout(searchTimeout);
}
setSearchTimeout(
setTimeout(() => {
setSearchTimeout(undefined);
setSearchTerm(search);
}, 500),
);
}, [search]);
const { data: searchResults } = useSWR<SearchResult[]>(
searchTerm.length > 0 ? ["events/search", { query: searchTerm }] : null,
);
2024-06-22 01:15:06 +03:00
return (
<div className="flex size-full flex-col pt-2 md:py-2">
<Toaster closeButton={true} />
<div className="relative mb-2 flex h-11 items-center justify-between pl-2 pr-2 md:pl-3">
<Input
className="w-full bg-muted md:w-1/3"
placeholder="Search for a specific detection..."
2024-06-22 02:05:59 +03:00
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
2024-06-22 02:05:59 +03:00
<SearchFilterGroup onUpdateFilter={() => {}} />
2024-06-22 01:15:06 +03:00
</div>
<div className="no-scrollbar flex flex-1 flex-wrap content-start gap-2 overflow-y-auto md:gap-4">
{searchTerm == "" && (
<div className="absolute left-1/2 top-1/2 flex -translate-x-1/2 -translate-y-1/2 flex-col items-center justify-center text-center">
<LuSearchCheck className="size-16" />
Search For Detections
</div>
)}
2024-06-22 02:05:59 +03:00
{searchResults &&
searchResults.map((value) => {
const selected = false;
return (
<div
key={value.id}
data-start={value.start_time}
className="review-item relative rounded-lg"
>
<div className="aspect-video overflow-hidden rounded-lg">
<SearchThumbnailPlayer
searchResult={value}
allPreviews={[]}
scrollLock={false}
onClick={() => {}}
//onTimeUpdate={onPreviewTimeUpdate}
//onClick={onSelectReview}
/>
</div>
<div
className={`review-item-ring pointer-events-none absolute inset-0 z-10 size-full rounded-lg outline outline-[3px] -outline-offset-[2.8px] ${selected ? `shadow-severity_alert outline-severity_alert` : "outline-transparent duration-500"}`}
/>
</div>
);
})}
2024-06-22 01:15:06 +03:00
</div>
</div>
);
}