From fa65b15a18a30060d4d6d663c8b2391d44e3fa63 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sun, 28 Jun 2020 02:25:01 +0300
Subject: feat: implement searchBar fetching logic

---
 src/components/Header/SearchBar.tsx | 38 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

(limited to 'src/components/Header/SearchBar.tsx')

diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx
index 182a1a4..8382028 100644
--- a/src/components/Header/SearchBar.tsx
+++ b/src/components/Header/SearchBar.tsx
@@ -1,7 +1,12 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
 import SearchIcon from '@material-ui/icons/Search';
 import { InputBase } from '@material-ui/core';
 import { makeStyles } from '@material-ui/core/styles';
+import { User } from 'which-types';
+import { get } from '../../requests';
+
+
+const INTERVAL = 300;
 
 const useStyles = makeStyles(theme => ({
   root: {
@@ -15,12 +20,43 @@ const useStyles = makeStyles(theme => ({
 
 const SearchBar: React.FC = () => {
   const classes = useStyles();
+  const [query, setQuery] = useState<string>('');
+  const [results, setResults] = useState<User[]>([]);
+  const [isReady, setIsReady] = useState<boolean>(true);
+  const [shouldRefetch, setShouldRefetch] = useState<boolean>(false);
+
+  const sleep = () => {
+    setIsReady(false);
+    setTimeout(() => setIsReady(true), INTERVAL);
+  };
+
+  const fetchPolls = () => {
+    sleep();
+    get(`/users?username[$regex]=${query}`).then(response => {
+      setResults(response.data);
+    });
+  }
+
+  useEffect(() => {
+    if (isReady && shouldRefetch) {
+      fetchPolls();
+      setShouldRefetch(false);
+    }
+  }, [isReady])
+
+  const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
+    setQuery(event.target.value);
+    if (isReady) fetchPolls();
+    else setShouldRefetch(true);
+  };
 
   return (
     <div className={classes.root}>
       <SearchIcon />
       <InputBase
         placeholder="Search..."
+        value={query}
+        onChange={handleChange}
       />
     </div>
   );
-- 
cgit v1.2.3


From 64d58182cf5bc509af8ab1fa3fa57f30b46d6501 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sun, 28 Jun 2020 03:53:13 +0300
Subject: feat: show search results

---
 src/components/Header/SearchBar.tsx | 51 +++++++++++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 5 deletions(-)

(limited to 'src/components/Header/SearchBar.tsx')

diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx
index 8382028..d240db9 100644
--- a/src/components/Header/SearchBar.tsx
+++ b/src/components/Header/SearchBar.tsx
@@ -1,29 +1,45 @@
 import React, { useState, useEffect } from 'react';
 import SearchIcon from '@material-ui/icons/Search';
-import { InputBase } from '@material-ui/core';
+import {
+  InputBase,
+  List,
+  ListItem,
+  Paper,
+  Divider
+} from '@material-ui/core';
 import { makeStyles } from '@material-ui/core/styles';
 import { User } from 'which-types';
 import { get } from '../../requests';
+import UserStrip from '../UserStrip/UserStrip';
 
+interface PropTypes {
+  navigate: (prefix: string, id: string) => void;
+}
 
 const INTERVAL = 300;
 
 const useStyles = makeStyles(theme => ({
   root: {
+    position: 'relative',
     background: 'rgba(255, 255, 255, 0.5)',
     borderRadius: '2px',
     padding: theme.spacing(0.5),
     display: 'flex',
     alignItems: 'center'
+  },
+  results: {
+    position: 'absolute',
+    width: '100%',
+    top: theme.spacing(5)
   }
 }));
 
-const SearchBar: React.FC = () => {
-  const classes = useStyles();
+const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
   const [query, setQuery] = useState<string>('');
   const [results, setResults] = useState<User[]>([]);
   const [isReady, setIsReady] = useState<boolean>(true);
   const [shouldRefetch, setShouldRefetch] = useState<boolean>(false);
+  const classes = useStyles();
 
   const sleep = () => {
     setIsReady(false);
@@ -35,14 +51,15 @@ const SearchBar: React.FC = () => {
     get(`/users?username[$regex]=${query}`).then(response => {
       setResults(response.data);
     });
-  }
+  };
 
   useEffect(() => {
     if (isReady && shouldRefetch) {
       fetchPolls();
       setShouldRefetch(false);
     }
-  }, [isReady])
+  }, [isReady]);
+
 
   const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
     setQuery(event.target.value);
@@ -50,6 +67,29 @@ const SearchBar: React.FC = () => {
     else setShouldRefetch(true);
   };
 
+  const handleNavigate = (index: number) => () => {
+    navigate('profile', results[index]._id);
+    setQuery('');
+    setResults([]);
+  };
+
+  const SearchResults = (
+    <Paper className={classes.results}>
+      <List>
+        {
+        results.map((result, index) => (
+          <>
+            <ListItem button onClick={handleNavigate(index)}>
+              <UserStrip user={result} navigate={navigate} />
+            </ListItem>
+            {(index < results.length - 1) && <Divider />}
+          </>
+        ))
+      }
+      </List>
+    </Paper>
+  );
+
   return (
     <div className={classes.root}>
       <SearchIcon />
@@ -58,6 +98,7 @@ const SearchBar: React.FC = () => {
         value={query}
         onChange={handleChange}
       />
+      {results.length > 0 && SearchResults}
     </div>
   );
 };
-- 
cgit v1.2.3


From ea9920d9ed0e7b3a3e565623e434e75bd3362f02 Mon Sep 17 00:00:00 2001
From: eug-vs <eug-vs@keemail.me>
Date: Sun, 28 Jun 2020 04:12:01 +0300
Subject: feat: close search on clickaway

---
 src/components/Header/SearchBar.tsx | 41 ++++++++++++++++++++++---------------
 1 file changed, 24 insertions(+), 17 deletions(-)

(limited to 'src/components/Header/SearchBar.tsx')

diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx
index d240db9..2be8f6f 100644
--- a/src/components/Header/SearchBar.tsx
+++ b/src/components/Header/SearchBar.tsx
@@ -5,7 +5,8 @@ import {
   List,
   ListItem,
   Paper,
-  Divider
+  Divider,
+  ClickAwayListener
 } from '@material-ui/core';
 import { makeStyles } from '@material-ui/core/styles';
 import { User } from 'which-types';
@@ -67,27 +68,33 @@ const SearchBar: React.FC<PropTypes> = ({ navigate }) => {
     else setShouldRefetch(true);
   };
 
-  const handleNavigate = (index: number) => () => {
-    navigate('profile', results[index]._id);
+  const handleClose = () => {
     setQuery('');
     setResults([]);
   };
 
+  const handleNavigate = (index: number) => () => {
+    navigate('profile', results[index]._id);
+    handleClose();
+  };
+
   const SearchResults = (
-    <Paper className={classes.results}>
-      <List>
-        {
-        results.map((result, index) => (
-          <>
-            <ListItem button onClick={handleNavigate(index)}>
-              <UserStrip user={result} navigate={navigate} />
-            </ListItem>
-            {(index < results.length - 1) && <Divider />}
-          </>
-        ))
-      }
-      </List>
-    </Paper>
+    <ClickAwayListener onClickAway={handleClose}>
+      <Paper className={classes.results}>
+        <List>
+          {
+          results.map((result, index) => (
+            <>
+              <ListItem button onClick={handleNavigate(index)}>
+                <UserStrip user={result} navigate={navigate} />
+              </ListItem>
+              {(index < results.length - 1) && <Divider />}
+            </>
+          ))
+        }
+        </List>
+      </Paper>
+    </ClickAwayListener>
   );
 
   return (
-- 
cgit v1.2.3

