MCPcopy Create free account
hub / github.com/Open-Dev-Society/OpenStock / SearchCommand

Function SearchCommand

components/SearchCommand.tsx:11–117  ·  view source on GitHub ↗
({ renderAs = 'button', label = 'Add stock', initialStocks }: SearchCommandProps)

Source from the content-addressed store, hash-verified

9import {useDebounce} from "@/hooks/useDebounce";
10
11export default function SearchCommand({ renderAs = 'button', label = 'Add stock', initialStocks }: SearchCommandProps) {
12 const [open, setOpen] = useState(false)
13 const [searchTerm, setSearchTerm] = useState("")
14 const [loading, setLoading] = useState(false)
15 const [stocks, setStocks] = useState<StockWithWatchlistStatus[]>(initialStocks);
16
17 const isSearchMode = !!searchTerm.trim();
18 const displayStocks = isSearchMode ? stocks : stocks?.slice(0, 10);
19
20 useEffect(() => {
21 const onKeyDown = (e: KeyboardEvent) => {
22 if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
23 e.preventDefault()
24 setOpen(v => !v)
25 }
26 }
27 window.addEventListener("keydown", onKeyDown)
28 return () => window.removeEventListener("keydown", onKeyDown)
29 }, [])
30
31 const handleSearch = async () => {
32 if(!isSearchMode) return setStocks(initialStocks);
33
34 setLoading(true)
35 try {
36 const results = await searchStocks(searchTerm.trim());
37 setStocks(results);
38 } catch {
39 setStocks([])
40 } finally {
41 setLoading(false)
42 }
43 }
44
45 const debouncedSearch = useDebounce(handleSearch, 300);
46
47 useEffect(() => {
48 debouncedSearch();
49 }, [debouncedSearch, searchTerm]);
50
51 const handleSelectStock = () => {
52 setOpen(false);
53 setSearchTerm("");
54 setStocks(initialStocks);
55 }
56
57 return (
58 <>
59 {renderAs === 'text' ? (
60 <button
61 type="button"
62 onClick={() => setOpen(true)}
63 className="search-text"
64 >
65 {label}
66 </button>
67 ): (
68 <Button onClick={() => setOpen(true)} className="search-btn">

Callers

nothing calls this directly

Calls 1

useDebounceFunction · 0.90

Tested by

no test coverage detected