From eb32fdfe40eeb3796a5691735c2dede97ef1b90e Mon Sep 17 00:00:00 2001
From: Matt Kirby <MattJKirby@outlook.com>
Date: Sun, 16 Apr 2023 21:40:28 +0100
Subject: [PATCH] Added standalone UserSearch

---
 .../src/components/form/UserSearch.tsx        | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 daily-thought-frontend/src/components/form/UserSearch.tsx

diff --git a/daily-thought-frontend/src/components/form/UserSearch.tsx b/daily-thought-frontend/src/components/form/UserSearch.tsx
new file mode 100644
index 00000000..33d70ea0
--- /dev/null
+++ b/daily-thought-frontend/src/components/form/UserSearch.tsx
@@ -0,0 +1,82 @@
+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;
\ No newline at end of file
-- 
GitLab