Skip to content
Snippets Groups Projects
UserSearch.tsx 4.25 KiB
Newer Older
import useDebounce from "@/hooks/useDebounce";
import { useFriends } from "@/hooks/useFriends";
import { UserCircleIcon, UserPlusIcon } from "@heroicons/react/24/outline";
import { FC, PropsWithChildren, useEffect, useState } from "react";
import UserAvatar from "../user/UserAvatar";
import BasicField from "./BasicField";

type UserSearchProps = {
  limit?: number;
  friends: Map<string, any> | undefined;
}

const UserSearch:FC<PropsWithChildren<UserSearchProps>> = ({
  limit = 6,
  friends
}) => {
  const [searchQuery, setSearchQuery] = useState<string>("");
  const debouncedSearchQuery = useDebounce<string>(searchQuery, 500)
  const [searchResults, setSearchResults] = useState<Map<[key: string], any>>(new Map([]));
  const [loading, setLoading] = useState<boolean>(false);

  useEffect(() => {
    setLoading(true)
    if(searchQuery.length === 0){
      setSearchResults(new Map([]))
    }
  }, [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(new Map(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 mb-2'>
            <p className='text-xs text-gray-500'>
              Enter a search query to find friends
            </p>
          </div>
        }
        <div className="border-b">
          {searchQuery && !loading && Array.from(searchResults.values()).map((result, index) => {
            if(index < limit && !friends?.has(result[0])){
              console.log(result)
              return (
                <div className="flex justify-between hover:bg-gray-100 rounded-md mb-2" key={index}>
                  <UserAvatar key={result[0]} username={result.username} firstName={result.firstName} lastName={result.lastName} />
                      <button
                      type="button"
                      className="ml-auto mr-1 flex-shrink-1 rounded-full text-c-pink p-1 hover:text-gray-200 focus:outline-none "
                    >
                      <span className="sr-only">View notifications</span>
                      <UserPlusIcon className="h-6 w-6" aria-hidden="true" />
                    </button>
                </div>
                )
              }
            })}

            {searchQuery && loading && 
            <div className="flex justify-center mb-2">
              <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.size === 0 && 
            <div>
              <p className='text-xs text-gray-500 flex justify-center mb-2'>
                No results found
              </p>
            </div>
          } 


          </div>



        <div className="w-full pt-2 text-xs text-gray-500">
          Friends
        </div>
        {friends && searchQuery && !loading && Array.from(friends.values()).map((result, index) => {
          if(friends?.has(result[0])){
            return (
              <div className="flex justify-between hover:bg-gray-100 rounded-md" key={index}>
                <UserAvatar key={index} username={result[1].username} firstName={result[1].firstName} lastName={result[1].lastName} />
                    <button
                    type="button"
                    className="ml-auto mr-1 flex-shrink-1 rounded-full text-c-pink p-1 hover:text-gray-200 focus:outline-none "
                  >
                    <span className="sr-only">View notifications</span>
                    <UserPlusIcon className="h-6 w-6" aria-hidden="true" />
                  </button>
              </div>
              )
            }
          })}
        </div> 
      </div>
  )
}

export default UserSearch;