import useDebounce from "@/hooks/useDebounce"; import { UserCircleIcon } from "@heroicons/react/24/outline"; import { FC, PropsWithChildren, useEffect, useState } from "react"; import BasicField from "./BasicField"; type UserSearchProps = { limit?: number } const UserSearch:FC<PropsWithChildren<UserSearchProps>> = ({ limit = 6 }) => { const [searchQuery, setSearchQuery] = useState<string>(""); const debouncedSearchQuery = useDebounce<string>(searchQuery, 500) const [searchResults, setSearchResults] = useState<any[]>([]); const [loading, setLoading] = useState<boolean>(false) useEffect(() => { setLoading(true) if(searchQuery.length === 0){ setSearchResults([]) } }, [searchQuery, setSearchResults]) useEffect(() => { if(debouncedSearchQuery.length > 0){ const endpoint = `${process.env.NEXT_PUBLIC_USER_SERVICE_URL}api/search?searchQuery=${debouncedSearchQuery}`; fetch(endpoint).then(async (result) => { const data = await result.json(); setLoading(false) setSearchResults(data.result) }); } }, [debouncedSearchQuery]) return ( <div> <BasicField name="search" placeholder="Search users" onChange={setSearchQuery}/> <div className="border-t pt-2 flex item-center flex-col"> {!searchQuery && <div className='flex items-center justify-center'> <p className='text-xs text-gray-500'> Enter a search query to add friends </p> </div> } {searchQuery && !loading && searchResults.map((result, index) => { if(index < limit){ return ( <div className='flex items-center hover:bg-gray-100 rounded-md p-1'> <div className=""> <UserCircleIcon className='h-12 w-12 rounded-full text-gray-300 flex items-center justify-center' /> </div> <div className='text-sm ml-1 text-gray-900'> {result.firstName && <div>{`${result.firstName} ${result.lastName || null}`}</div>} <p className='text-sm text-gray-500 font-normal'>@{result.username}</p> </div> </div> ) } })} {searchQuery && loading && <div className="flex justify-center"> <div className="h-6 w-6 animate-spin text-gray-300 rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]" role="status"> </div> </div>} {searchQuery && !loading && searchResults.length === 0 && <div> <p className='text-xs text-gray-500 flex justify-center'> No results found </p> </div> } </div> </div> ) } export default UserSearch;