diff options
Diffstat (limited to 'frontend/src/components/Sidebar/Search.tsx')
| -rw-r--r-- | frontend/src/components/Sidebar/Search.tsx | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/frontend/src/components/Sidebar/Search.tsx b/frontend/src/components/Sidebar/Search.tsx new file mode 100644 index 0000000..0c6b868 --- /dev/null +++ b/frontend/src/components/Sidebar/Search.tsx | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | import React, { useRef } from "react"; | ||
| 2 | import { Link } from "react-router-dom"; | ||
| 3 | |||
| 4 | import { Search } from "@customTypes/Search"; | ||
| 5 | import { API } from "@api/Api"; | ||
| 6 | import { UserProfile } from "@customTypes/Profile"; | ||
| 7 | |||
| 8 | interface SearchProps { | ||
| 9 | profile?: UserProfile; | ||
| 10 | isSearching: boolean; | ||
| 11 | }; | ||
| 12 | |||
| 13 | const _Search: React.FC<SearchProps> = ({ profile, isSearching }) => { | ||
| 14 | const [searchData, setSearchData] = React.useState<Search | undefined>( | ||
| 15 | undefined | ||
| 16 | ); | ||
| 17 | |||
| 18 | const searchbarRef = useRef<HTMLInputElement>(null); | ||
| 19 | |||
| 20 | const _handle_search_change = async (q: string) => { | ||
| 21 | const searchResponse = await API.get_search(q); | ||
| 22 | setSearchData(searchResponse); | ||
| 23 | }; | ||
| 24 | return ( | ||
| 25 | <div className="flex w-full flex-col justify-between p-3"> | ||
| 26 | <input | ||
| 27 | ref={searchbarRef} | ||
| 28 | type="text" | ||
| 29 | id="searchbar" | ||
| 30 | placeholder="Search for map or a player..." | ||
| 31 | onChange={e => _handle_search_change(e.target.value)} | ||
| 32 | className="w-full py-2 px-[19px] bg-input rounded-[2000px] outline-none placeholder-bright placeholder:text-[18px] placeholder:font-barlow-semicondensed-regular" | ||
| 33 | /> | ||
| 34 | |||
| 35 | {searchData && ( | ||
| 36 | <div className="overflow-y-auto"> | ||
| 37 | {searchData?.maps.map((q, index) => ( | ||
| 38 | <Link to={`/maps/${q.id}`} className="block p-2 mb-1 bg-surface1 rounded hover:bg-surface2 transition-colors min-w-0" key={index}> | ||
| 39 | <span className="block text-xs text-subtext1 truncate">{q.game}</span> | ||
| 40 | <span className="block text-xs text-subtext1 truncate">{q.chapter}</span> | ||
| 41 | <span className="block text-sm text-foreground truncate">{q.map}</span> | ||
| 42 | </Link> | ||
| 43 | ))} | ||
| 44 | {searchData?.players.map((q, index) => ( | ||
| 45 | <Link | ||
| 46 | to={ | ||
| 47 | profile && q.steam_id === profile.steam_id | ||
| 48 | ? `/profile` | ||
| 49 | : `/users/${q.steam_id}` | ||
| 50 | } | ||
| 51 | className="flex items-center p-2 mb-1 bg-surface1 rounded hover:bg-surface2 transition-colors min-w-0" | ||
| 52 | key={index} | ||
| 53 | > | ||
| 54 | <img src={q.avatar_link} alt="pfp" className="w-6 h-6 rounded-full mr-2 flex-shrink-0" /> | ||
| 55 | <span className="text-sm text-foreground truncate"> | ||
| 56 | {q.user_name} | ||
| 57 | </span> | ||
| 58 | </Link> | ||
| 59 | ))} | ||
| 60 | </div> | ||
| 61 | )} | ||
| 62 | </div> | ||
| 63 | ) | ||
| 64 | } | ||
| 65 | |||
| 66 | export default _Search; | ||