/[sudobot]/trunk/docs/components/Searching/SearchModal.tsx
ViewVC logotype

Annotation of /trunk/docs/components/Searching/SearchModal.tsx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 575 - (hide annotations)
Mon Jul 29 17:59:26 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 5385 byte(s)
chore: add trunk
1 rakinar2 575 import useDebouncedState from "@/hooks/useDebouncedState";
2     import { Button, CircularProgress, TextField } from "@mui/material";
3     import { useEffect, useState } from "react";
4     import { MdClose } from "react-icons/md";
5     import SearchResult from "./SearchResult";
6    
7     type SearchModalProps = {
8     onClose: () => void;
9     };
10    
11     export type SearchResultItem = {
12     title?: string;
13     description?: string;
14     data: string;
15     match: "title" | "description" | "data";
16     url: string;
17     };
18    
19     export default function SearchModal({ onClose }: SearchModalProps) {
20     const [query, isQueued, setQuery] = useDebouncedState<string | null>(
21     null,
22     500,
23     );
24     const [results, setResults] = useState<SearchResultItem[] | null>(null);
25     const [isLoading, setIsLoading] = useState(false);
26     const [isNotFound, setIsNotFound] = useState(false);
27    
28     useEffect(() => {
29     if (!query?.trim()) {
30     return;
31     }
32    
33     const controller = new AbortController();
34    
35     if (!isLoading) {
36     setIsLoading(true);
37     }
38    
39     fetch(`/search?q=${encodeURIComponent(query)}`, {
40     signal: controller.signal,
41     })
42     .then(response => response.json())
43     .then(data => {
44     if (isNotFound) {
45     setIsNotFound(false);
46     }
47    
48     setIsLoading(false);
49     setResults(data.results);
50    
51     if (data.results.length === 0) {
52     setIsNotFound(true);
53     }
54     })
55     .catch(console.error);
56    
57     return () => controller.abort();
58     }, [query]);
59    
60     return (
61     <>
62     <div
63     className="h-[100vh] w-[100vw] fixed top-0 left-0 bg-[rgba(0,0,0,0.3)] z-[10001]"
64     onClick={onClose}
65     >
66     <div
67     onClick={event => event.stopPropagation()}
68     className="max-h-[95vh] block z-[10002] shadow-[0_0_1px_1px_rgba(255,255,255,0.2)] fixed bottom-[10px] lg:top-[50vh] left-[50%] translate-x-[-50%] lg:translate-y-[-50%] bg-[#222] min-h-[50vh] overflow-y-scroll w-[calc(100%-20px)] lg:w-[auto] md:min-w-[50vw] rounded-md p-4"
69     >
70     <div className="text-xl lg:text-2xl text-center mb-5 grid grid-cols-[1fr_5fr_1fr]">
71     <span></span>
72     <span>Search Docs</span>
73     <div className="flex justify-end">
74     <Button
75     style={{ minWidth: 0, color: "white" }}
76     onClick={onClose}
77     >
78     <MdClose />
79     </Button>
80     </div>
81     </div>
82    
83     <TextField
84     fullWidth
85     autoFocus
86     type="text"
87     variant="outlined"
88     placeholder="Type here to search"
89     onChange={event => setQuery(event.target.value.trim())}
90     onKeyUp={event => {
91     if (!(event.target as HTMLInputElement).value) {
92     setQuery(null);
93     setResults(null);
94     }
95    
96     if (isNotFound) {
97     setIsNotFound(false);
98     }
99     }}
100     />
101     <br />
102     <div className="mt-4">
103     {isLoading ? (
104     <div className="flex justify-center items-center">
105     <CircularProgress />
106     </div>
107     ) : results && results.length > 0 && !isNotFound ? (
108     <>
109     {results?.length && (
110     <>
111     <p className="text-[#aaa] text-sm">
112     Found {results.length} results.
113     </p>
114     <br />
115     </>
116     )}
117    
118     {results?.map((result, index) => (
119     <SearchResult
120     result={result}
121     query={query ?? ""}
122     key={index}
123     onClick={onClose}
124     />
125     ))}
126     </>
127     ) : isNotFound ? (
128     <h3 className="text-lg md:text-xl text-center">
129     No results found.{" "}
130     <span className="text-[#999]">
131     Maybe search again with a different
132     keyboard?
133     </span>
134     </h3>
135     ) : (
136     ""
137     )}
138     </div>
139     </div>
140     </div>
141     </>
142     );
143     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26