Skip to content
Snippets Groups Projects
Commit f4ae857e authored by Matt Kirby's avatar Matt Kirby
Browse files

Complex user search component

parent 4448e4b2
No related branches found
No related tags found
1 merge request!18Fe search and friends (sorry in advance)
import useDebounce from "@/hooks/useDebounce";
import { useFriends } from "@/hooks/useFriends";
import { UserCircleIcon } from "@heroicons/react/24/outline";
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
limit?: number;
friends: Map<string, any> | undefined;
}
const UserSearch:FC<PropsWithChildren<UserSearchProps>> = ({
limit = 6
limit = 6,
friends
}) => {
const [searchQuery, setSearchQuery] = useState<string>("");
const debouncedSearchQuery = useDebounce<string>(searchQuery, 500)
const [searchResults, setSearchResults] = useState<any[]>([]);
const [searchResults, setSearchResults] = useState<Map<[key: string], any>>(new Map([]));
const [loading, setLoading] = useState<boolean>(false);
const friends = useFriends();
console.log(friends)
useEffect(() => {
setLoading(true)
if(searchQuery.length === 0){
setSearchResults([])
setSearchResults(new Map([]))
}
}, [searchQuery, setSearchResults])
......@@ -32,52 +32,81 @@ const UserSearch:FC<PropsWithChildren<UserSearchProps>> = ({
fetch(endpoint).then(async (result) => {
const data = await result.json();
setLoading(false)
setSearchResults(data.result)
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'>
<div className='flex items-center justify-center mb-2'>
<p className='text-xs text-gray-500'>
Enter a search query to add friends
Enter a search query to find 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' key={index}>
<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 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">
<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 &&
)
}
})}
{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'>
<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>
)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment