From fa65b15a18a30060d4d6d663c8b2391d44e3fa63 Mon Sep 17 00:00:00 2001 From: eug-vs 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(-) 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(''); + const [results, setResults] = useState([]); + const [isReady, setIsReady] = useState(true); + const [shouldRefetch, setShouldRefetch] = useState(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): void => { + setQuery(event.target.value); + if (isReady) fetchPolls(); + else setShouldRefetch(true); + }; return (
); -- cgit v1.2.3 From 64d58182cf5bc509af8ab1fa3fa57f30b46d6501 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sun, 28 Jun 2020 03:53:13 +0300 Subject: feat: show search results --- src/components/Header/Header.tsx | 2 +- src/components/Header/SearchBar.tsx | 51 ++++++++++++++++++++++++++++++---- src/components/UserStrip/UserStrip.tsx | 2 +- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 2e3fc20..1825647 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -52,7 +52,7 @@ const Header: React.FC = ({ navigate, userImage }) => { Which - +
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 = ({ navigate }) => { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); const [isReady, setIsReady] = useState(true); const [shouldRefetch, setShouldRefetch] = useState(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): 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 = ( + + + { + results.map((result, index) => ( + <> + + + + {(index < results.length - 1) && } + + )) + } + + + ); + return (
@@ -58,6 +98,7 @@ const SearchBar: React.FC = () => { value={query} onChange={handleChange} /> + {results.length > 0 && SearchResults}
); }; diff --git a/src/components/UserStrip/UserStrip.tsx b/src/components/UserStrip/UserStrip.tsx index 6e84768..f02adc3 100644 --- a/src/components/UserStrip/UserStrip.tsx +++ b/src/components/UserStrip/UserStrip.tsx @@ -10,8 +10,8 @@ import { User } from 'which-types'; interface PropTypes { user: User; - info: string | JSX.Element navigate: (prefix: string, id: string) => void; + info?: string | JSX.Element } -- cgit v1.2.3 From b02ebbcb75faceb140d484c4a3a6779040ba0ca7 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sun, 28 Jun 2020 04:01:32 +0300 Subject: feat: add missing verified icon to profileInfo --- src/pages/ProfilePage/ProfileInfo.tsx | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pages/ProfilePage/ProfileInfo.tsx b/src/pages/ProfilePage/ProfileInfo.tsx index f52e374..cb6867f 100644 --- a/src/pages/ProfilePage/ProfileInfo.tsx +++ b/src/pages/ProfilePage/ProfileInfo.tsx @@ -1,11 +1,12 @@ import React, { useState } from 'react'; -import { Avatar, Badge } from '@material-ui/core/'; +import { Avatar, Badge, Typography } from '@material-ui/core/'; import { makeStyles } from '@material-ui/core/styles'; import { User } from 'which-types'; import CameraAltIcon from '@material-ui/icons/CameraAlt'; import MoreMenu from './MoreMenu'; import Highlight from './Highlight'; import UploadImage from '../../components/UploadImage/UploadImage'; +import VerifiedIcon from '@material-ui/icons/CheckCircleOutline'; interface PropTypes { @@ -27,9 +28,15 @@ const useStyles = makeStyles(theme => ({ margin: '0 auto' }, name: { - fontSize: 20, - textAlign: 'center', - margin: '10px 0' + margin: theme.spacing(1, 0), + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }, + verified: { + marginLeft: theme.spacing(0.5), + width: theme.spacing(3), + height: theme.spacing(3) }, profileMenu: { display: 'flex', @@ -110,13 +117,14 @@ const ProfileInfo: React.FC = ({ ) : } -
+ {user?.username} -
+ {user?.verified && } +
- +
); -- cgit v1.2.3 From ea9920d9ed0e7b3a3e565623e434e75bd3362f02 Mon Sep 17 00:00:00 2001 From: eug-vs Date: Sun, 28 Jun 2020 04:12:01 +0300 Subject: feat: close search on clickaway --- src/components/Header/SearchBar.tsx | 41 ++++++++++++++++++++--------------- src/pages/ProfilePage/ProfileInfo.tsx | 2 +- 2 files changed, 25 insertions(+), 18 deletions(-) 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 = ({ 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 = ( - - - { - results.map((result, index) => ( - <> - - - - {(index < results.length - 1) && } - - )) - } - - + + + + { + results.map((result, index) => ( + <> + + + + {(index < results.length - 1) && } + + )) + } + + + ); return ( diff --git a/src/pages/ProfilePage/ProfileInfo.tsx b/src/pages/ProfilePage/ProfileInfo.tsx index cb6867f..2b9227e 100644 --- a/src/pages/ProfilePage/ProfileInfo.tsx +++ b/src/pages/ProfilePage/ProfileInfo.tsx @@ -3,10 +3,10 @@ import { Avatar, Badge, Typography } from '@material-ui/core/'; import { makeStyles } from '@material-ui/core/styles'; import { User } from 'which-types'; import CameraAltIcon from '@material-ui/icons/CameraAlt'; +import VerifiedIcon from '@material-ui/icons/CheckCircleOutline'; import MoreMenu from './MoreMenu'; import Highlight from './Highlight'; import UploadImage from '../../components/UploadImage/UploadImage'; -import VerifiedIcon from '@material-ui/icons/CheckCircleOutline'; interface PropTypes { -- cgit v1.2.3