diff options
author | Eugene Sokolov <eug-vs@keemail.me> | 2020-06-28 04:14:02 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-28 04:14:02 +0300 |
commit | 2f1ee1baab72be2ae38a921a7c0da7ce6e03fbc1 (patch) | |
tree | 3fdca2db655c80907cdef7ac3fdfabed6f78a5ec /src/components/Header/SearchBar.tsx | |
parent | 5057fe763d423be607336d6b839909843c5a2567 (diff) | |
parent | ea9920d9ed0e7b3a3e565623e434e75bd3362f02 (diff) | |
download | which-ui-2f1ee1baab72be2ae38a921a7c0da7ce6e03fbc1.tar.gz |
Merge pull request #50 from which-ecosystem/search
SearchBar functionality
Diffstat (limited to 'src/components/Header/SearchBar.tsx')
-rw-r--r-- | src/components/Header/SearchBar.tsx | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/src/components/Header/SearchBar.tsx b/src/components/Header/SearchBar.tsx index 182a1a4..2be8f6f 100644 --- a/src/components/Header/SearchBar.tsx +++ b/src/components/Header/SearchBar.tsx @@ -1,27 +1,111 @@ -import React from 'react'; +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, + ClickAwayListener +} 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 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); + 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); + }; + + const handleClose = () => { + setQuery(''); + setResults([]); + }; + + const handleNavigate = (index: number) => () => { + navigate('profile', results[index]._id); + handleClose(); + }; + + const SearchResults = ( + <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 ( <div className={classes.root}> <SearchIcon /> <InputBase placeholder="Search..." + value={query} + onChange={handleChange} /> + {results.length > 0 && SearchResults} </div> ); }; |