From 9bc432ace2330437603d06c048953c26f1acca2c Mon Sep 17 00:00:00 2001 From: AmasiaNalbandian Date: Mon, 28 Mar 2022 22:08:31 -0400 Subject: [PATCH 1/4] refactored search to remove searchprovider --- src/web/app/src/components/SearchBar.tsx | 17 +++- .../SearchInput/AuthorSearchInput.tsx | 45 --------- .../SearchInput/PostSearchInput.tsx | 14 ++- .../components/SearchInput/SearchInput.tsx | 51 ++++++++-- src/web/app/src/components/SearchPage.tsx | 13 ++- src/web/app/src/components/SearchProvider.tsx | 99 ------------------- src/web/app/src/components/SearchResults.tsx | 15 ++- src/web/app/src/pages/search.tsx | 5 +- 8 files changed, 88 insertions(+), 171 deletions(-) delete mode 100644 src/web/app/src/components/SearchInput/AuthorSearchInput.tsx delete mode 100644 src/web/app/src/components/SearchProvider.tsx diff --git a/src/web/app/src/components/SearchBar.tsx b/src/web/app/src/components/SearchBar.tsx index 042e60f0aa..a109a2789f 100644 --- a/src/web/app/src/components/SearchBar.tsx +++ b/src/web/app/src/components/SearchBar.tsx @@ -1,9 +1,10 @@ +import { FormEvent, useState } from 'react'; +import { useRouter } from 'next/router'; import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; import SearchIcon from '@material-ui/icons/Search'; import { Grid, MenuItem, TextField, FormControl, Paper, IconButton, Box } from '@material-ui/core'; import SearchInput from './SearchInput/SearchInput'; -import useSearchValue from '../hooks/use-search-value'; const useStyles = makeStyles((theme: Theme) => createStyles({ @@ -92,11 +93,17 @@ const useStyles = makeStyles((theme: Theme) => const SearchBar = () => { const classes = useStyles(); - - const { filter, onFilterChange, onSubmitHandler } = useSearchValue(); + const router = useRouter(); + const [filter, setFilter] = useState('post'); + const [text, setText] = useState(''); const searchOptions = ['post', 'author']; + const onSubmitHandler = (event: FormEvent) => { + event.preventDefault(); + router.push(`/search?text=${text}&filter=${filter}`); + }; + return ( @@ -109,7 +116,7 @@ const SearchBar = () => { value={filter} InputProps={{ disableUnderline: true }} className={classes.selectControl} - onChange={(event) => onFilterChange(event.target.value)} + onChange={(event) => setFilter(event.target.value)} > {searchOptions.map((option) => ( @@ -121,7 +128,7 @@ const SearchBar = () => { - + - createStyles({ - input: { - fontSize: '1.6rem', - '&:hover': { - borderColor: theme.palette.primary.main, - }, - '&:focus': { - borderColor: theme.palette.primary.main, - }, - '& > *': { - fontSize: '1.6rem !important', - color: theme.palette.text.primary, - }, - height: '55px', - backgroundColor: 'transparent', - paddingLeft: '10px', - paddingRight: '60px', - border: 'none', - outline: 'none', - color: theme.palette.text.primary, - }, - }) -); - -const AuthorSearchInput = () => { - const classes = useStyles(); - const { text, onTextChange } = useSearchValue(); - - return ( - <> - onTextChange(event.target.value)} - /> - - ); -}; - -export default AuthorSearchInput; diff --git a/src/web/app/src/components/SearchInput/PostSearchInput.tsx b/src/web/app/src/components/SearchInput/PostSearchInput.tsx index 07c93e3b6a..b32c0086e4 100644 --- a/src/web/app/src/components/SearchInput/PostSearchInput.tsx +++ b/src/web/app/src/components/SearchInput/PostSearchInput.tsx @@ -1,3 +1,4 @@ +import { Dispatch, SetStateAction } from 'react'; import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; import useSearchValue from '../../hooks/use-search-value'; @@ -27,10 +28,13 @@ const useStyles = makeStyles((theme: Theme) => }) ); -const PostSearchInput = () => { - const classes = useStyles(); +interface SearchInputInterface { + text: string; + setText: Dispatch>; +} - const { text, onTextChange } = useSearchValue(); +const SearchInput = ({ text, setText }: SearchInputInterface) => { + const classes = useStyles(); return ( <> @@ -38,10 +42,10 @@ const PostSearchInput = () => { className={classes.input} placeholder="How to contribute to Open Source" value={text} - onChange={(event) => onTextChange(event.target.value)} + onChange={(event) => setText(event.target.value)} /> ); }; -export default PostSearchInput; +export default SearchInput; diff --git a/src/web/app/src/components/SearchInput/SearchInput.tsx b/src/web/app/src/components/SearchInput/SearchInput.tsx index 37ede0ab07..680b5fedbb 100644 --- a/src/web/app/src/components/SearchInput/SearchInput.tsx +++ b/src/web/app/src/components/SearchInput/SearchInput.tsx @@ -1,11 +1,50 @@ -import PostSearchInput from './PostSearchInput'; -import AuthorSearchInput from './AuthorSearchInput'; -import useSearchValue from '../../hooks/use-search-value'; +import { Dispatch, SetStateAction } from 'react'; +import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; -const SearchInput = () => { - const { filter } = useSearchValue(); +const useStyles = makeStyles((theme: Theme) => + createStyles({ + input: { + fontSize: '1.6rem', + '&:hover': { + borderColor: theme.palette.primary.main, + }, + '&:focus': { + borderColor: theme.palette.primary.main, + }, + '& > *': { + fontSize: '1.6rem !important', + color: theme.palette.text.primary, + }, + height: '55px', + backgroundColor: 'transparent', + paddingLeft: '10px', + paddingRight: '60px', + border: 'none', + borderRadius: '7px', + outline: 'none', + color: theme.palette.text.primary, + }, + }) +); - return <>{filter === 'author' ? : }; +interface SearchInputInterface { + text: string; + setText: Dispatch>; +} + +const SearchInput = ({ text, setText }: SearchInputInterface) => { + const classes = useStyles(); + + return ( + <> + setText(event.target.value)} + /> + + ); }; export default SearchInput; diff --git a/src/web/app/src/components/SearchPage.tsx b/src/web/app/src/components/SearchPage.tsx index 1b0a56de81..e601f1e0f5 100644 --- a/src/web/app/src/components/SearchPage.tsx +++ b/src/web/app/src/components/SearchPage.tsx @@ -1,8 +1,9 @@ +import { useState } from 'react'; +import { useRouter } from 'next/router'; import { makeStyles, Theme } from '@material-ui/core/styles'; import SearchResults from './SearchResults'; import SearchBar from './SearchBar'; import SearchHelp from './SearchHelp'; -import useSearchValue from '../hooks/use-search-value'; const useStyles = makeStyles((theme: Theme) => ({ searchPage: { @@ -22,13 +23,19 @@ const useStyles = makeStyles((theme: Theme) => ({ const SearchPage = () => { const classes = useStyles(); - const { showHelp } = useSearchValue(); + const [showHelp, toggleHelp] = useState(true); + const router = useRouter(); + + const textParam = Array.isArray(router.query.text) + ? router.query.text[0] + : router.query.text || ''; + const filterParam = router.query.filter === 'post' || !router.query.filter ? 'post' : 'author'; return (
{showHelp && } - +
); }; diff --git a/src/web/app/src/components/SearchProvider.tsx b/src/web/app/src/components/SearchProvider.tsx deleted file mode 100644 index 1f267de050..0000000000 --- a/src/web/app/src/components/SearchProvider.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { createContext, ReactNode, useState, useEffect, FormEvent } from 'react'; -import { useRouter } from 'next/router'; - -type FilterProp = { - filter: 'post' | 'author' | string; -}; - -export interface SearchContextInterface { - text: string; - textParam: string; - filter: FilterProp['filter']; - showHelp: boolean; - toggleHelp: (value: boolean) => void; - onTextChange: (value: string) => void; - onFilterChange: (value: FilterProp['filter']) => void; - onSubmitHandler: (value: FormEvent) => void; -} - -const SearchContext = createContext({ - text: '', - textParam: '', - filter: 'post', - showHelp: true, - toggleHelp() { - throw new Error('This context must be wrapped inside SearchProvider'); - }, - onTextChange() { - throw new Error('This context must be wrapped inside SearchProvider'); - }, - onFilterChange() { - throw new Error('This context must be wrapped inside SearchProvider'); - }, - onSubmitHandler() { - throw new Error('This context must be wrapped inside SearchProvider'); - }, -}); - -type Props = { - children: ReactNode; -}; - -const SearchProvider = ({ children }: Props) => { - const router = useRouter(); - // We synchronize the `text` and `filter` values to the URL's query string - // Router query object for a query can be an array if url becomes text=123&text=456 - // https://stackoverflow.com/questions/60110364/type-string-string-is-not-assignable-to-type-string - const textParam = Array.isArray(router.query.text) - ? router.query.text[0] - : router.query.text || ''; - const filterParam = router.query.filter === 'post' || !router.query.filter ? 'post' : 'author'; - - // We manage the state of `text` and `filter` internally, and update URL on - // form submit only. These are used in the , and the user can change them. - const [text, setText] = useState(''); - const [filter, setFilter] = useState('post'); - const [showHelp, setShowHelp] = useState(true); - - const onSubmitHandler = (event: FormEvent) => { - event.preventDefault(); - router.push(`/search?text=${text}&filter=${filter}`); - }; - - const toggleHelp = (value: boolean) => { - setShowHelp(value); - }; - - const onTextChange = (value: string) => { - setText(value); - }; - - const onFilterChange = (value: FilterProp['filter']) => { - setFilter(value); - }; - - useEffect(() => { - setText(textParam); - setFilter(filterParam); - }, [textParam, filterParam]); - - return ( - - {children} - - ); -}; - -export default SearchProvider; -export { SearchContext }; diff --git a/src/web/app/src/components/SearchResults.tsx b/src/web/app/src/components/SearchResults.tsx index 0490b76ffe..87cc70947f 100644 --- a/src/web/app/src/components/SearchResults.tsx +++ b/src/web/app/src/components/SearchResults.tsx @@ -1,12 +1,10 @@ +import { Dispatch, useState, SetStateAction } from 'react'; import { makeStyles, Theme } from '@material-ui/core/styles'; import useSWRInfinite from 'swr/infinite'; import { Container, Box, createStyles } from '@material-ui/core'; -import { useState } from 'react'; - import { searchServiceUrl } from '../config'; import Timeline from './Posts/Timeline'; import Spinner from './Spinner'; -import useSearchValue from '../hooks/use-search-value'; const NoResultsImg = '/noResults.svg'; @@ -53,9 +51,16 @@ const useStyles = makeStyles((theme: Theme) => }) ); -const SearchResults = () => { +const SearchResults = ({ + textParam, + filter, + toggleHelp, +}: { + textParam: string; + filter: string; + toggleHelp: Dispatch>; +}) => { const classes = useStyles(); - const { textParam, filter, toggleHelp } = useSearchValue(); const [totalPosts, setTotalPosts] = useState(0); const prepareUrl = (index: number) => diff --git a/src/web/app/src/pages/search.tsx b/src/web/app/src/pages/search.tsx index 8df732d174..0e7708ec21 100644 --- a/src/web/app/src/pages/search.tsx +++ b/src/web/app/src/pages/search.tsx @@ -1,15 +1,14 @@ import SEO from '../components/SEO'; import SearchPage from '../components/SearchPage'; -import SearchProvider from '../components/SearchProvider'; import NavBar from '../components/NavBar'; const Search = () => { return ( - + <> - + ); }; From 9ee26835f3acd160599df61adf77c810a5ea297d Mon Sep 17 00:00:00 2001 From: AmasiaNalbandian Date: Tue, 29 Mar 2022 00:39:46 -0400 Subject: [PATCH 2/4] fixed bug with url query not showing in input box --- src/web/app/src/components/SearchBar.tsx | 15 ++++++++--- src/web/app/src/components/SearchPage.tsx | 13 +--------- src/web/app/src/components/SearchResults.tsx | 26 +++++++++----------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/web/app/src/components/SearchBar.tsx b/src/web/app/src/components/SearchBar.tsx index a109a2789f..fee0ed1dcc 100644 --- a/src/web/app/src/components/SearchBar.tsx +++ b/src/web/app/src/components/SearchBar.tsx @@ -1,4 +1,4 @@ -import { FormEvent, useState } from 'react'; +import { FormEvent, useState, useEffect } from 'react'; import { useRouter } from 'next/router'; import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'; import SearchIcon from '@material-ui/icons/Search'; @@ -94,16 +94,25 @@ const useStyles = makeStyles((theme: Theme) => const SearchBar = () => { const classes = useStyles(); const router = useRouter(); - const [filter, setFilter] = useState('post'); + const [filter, setFilter] = useState(''); const [text, setText] = useState(''); - const searchOptions = ['post', 'author']; + const textParam = Array.isArray(router.query.text) + ? router.query.text[0] + : router.query.text || ''; + const filterParam = router.query.filter === 'post' || !router.query.filter ? 'post' : 'author'; + const searchOptions = ['post', 'author']; const onSubmitHandler = (event: FormEvent) => { event.preventDefault(); router.push(`/search?text=${text}&filter=${filter}`); }; + useEffect(() => { + setFilter(filterParam); + setText(textParam); + }, [textParam, filterParam]); + return ( diff --git a/src/web/app/src/components/SearchPage.tsx b/src/web/app/src/components/SearchPage.tsx index e601f1e0f5..165dbc5349 100644 --- a/src/web/app/src/components/SearchPage.tsx +++ b/src/web/app/src/components/SearchPage.tsx @@ -1,9 +1,6 @@ -import { useState } from 'react'; -import { useRouter } from 'next/router'; import { makeStyles, Theme } from '@material-ui/core/styles'; import SearchResults from './SearchResults'; import SearchBar from './SearchBar'; -import SearchHelp from './SearchHelp'; const useStyles = makeStyles((theme: Theme) => ({ searchPage: { @@ -23,19 +20,11 @@ const useStyles = makeStyles((theme: Theme) => ({ const SearchPage = () => { const classes = useStyles(); - const [showHelp, toggleHelp] = useState(true); - const router = useRouter(); - - const textParam = Array.isArray(router.query.text) - ? router.query.text[0] - : router.query.text || ''; - const filterParam = router.query.filter === 'post' || !router.query.filter ? 'post' : 'author'; return (
- {showHelp && } - +
); }; diff --git a/src/web/app/src/components/SearchResults.tsx b/src/web/app/src/components/SearchResults.tsx index 87cc70947f..e4201bc56a 100644 --- a/src/web/app/src/components/SearchResults.tsx +++ b/src/web/app/src/components/SearchResults.tsx @@ -1,10 +1,12 @@ -import { Dispatch, useState, SetStateAction } from 'react'; +import { useState } from 'react'; +import { useRouter } from 'next/router'; import { makeStyles, Theme } from '@material-ui/core/styles'; import useSWRInfinite from 'swr/infinite'; import { Container, Box, createStyles } from '@material-ui/core'; import { searchServiceUrl } from '../config'; import Timeline from './Posts/Timeline'; import Spinner from './Spinner'; +import SearchHelp from './SearchHelp'; const NoResultsImg = '/noResults.svg'; @@ -51,20 +53,17 @@ const useStyles = makeStyles((theme: Theme) => }) ); -const SearchResults = ({ - textParam, - filter, - toggleHelp, -}: { - textParam: string; - filter: string; - toggleHelp: Dispatch>; -}) => { +const SearchResults = () => { + const router = useRouter(); const classes = useStyles(); const [totalPosts, setTotalPosts] = useState(0); + const textParam = Array.isArray(router.query.text) + ? router.query.text[0] + : router.query.text || ''; + const filterParam = router.query.filter === 'post' || !router.query.filter ? 'post' : 'author'; const prepareUrl = (index: number) => - `${searchServiceUrl}?${filter === 'author' ? `author` : `post`}=${encodeURIComponent( + `${searchServiceUrl}?${filterParam === 'author' ? `author` : `post`}=${encodeURIComponent( textParam )}&page=${index}`; @@ -91,11 +90,8 @@ const SearchResults = ({ // If there is no posts or if the search bar is empty, then show the search help, otherwise hide it if (!error && (isEmpty || textParam.length === 0)) { - toggleHelp(true); - } else { - toggleHelp(false); + return ; } - if (error) { return ( From 1f47bad528cbd7a50fba31b410ff72a2350518d8 Mon Sep 17 00:00:00 2001 From: AmasiaNalbandian Date: Tue, 29 Mar 2022 00:44:01 -0400 Subject: [PATCH 3/4] removed unused component --- .../SearchInput/PostSearchInput.tsx | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 src/web/app/src/components/SearchInput/PostSearchInput.tsx diff --git a/src/web/app/src/components/SearchInput/PostSearchInput.tsx b/src/web/app/src/components/SearchInput/PostSearchInput.tsx deleted file mode 100644 index b32c0086e4..0000000000 --- a/src/web/app/src/components/SearchInput/PostSearchInput.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { Dispatch, SetStateAction } from 'react'; -import { makeStyles, createStyles, Theme } from '@material-ui/core/styles'; -import useSearchValue from '../../hooks/use-search-value'; - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - input: { - fontSize: '1.6rem', - '&:hover': { - borderColor: theme.palette.primary.main, - }, - '&:focus': { - borderColor: theme.palette.primary.main, - }, - '& > *': { - fontSize: '1.6rem !important', - color: theme.palette.text.primary, - }, - height: '55px', - backgroundColor: 'transparent', - paddingLeft: '10px', - paddingRight: '60px', - border: 'none', - borderRadius: '7px', - outline: 'none', - color: theme.palette.text.primary, - }, - }) -); - -interface SearchInputInterface { - text: string; - setText: Dispatch>; -} - -const SearchInput = ({ text, setText }: SearchInputInterface) => { - const classes = useStyles(); - - return ( - <> - setText(event.target.value)} - /> - - ); -}; - -export default SearchInput; From 4e5e349b16f022aa88941ead0d4167d4fa753172 Mon Sep 17 00:00:00 2001 From: AmasiaNalbandian Date: Tue, 29 Mar 2022 01:01:45 -0400 Subject: [PATCH 4/4] removed unused hook --- src/web/app/src/hooks/use-search-value.ts | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/web/app/src/hooks/use-search-value.ts diff --git a/src/web/app/src/hooks/use-search-value.ts b/src/web/app/src/hooks/use-search-value.ts deleted file mode 100644 index 061c6c2717..0000000000 --- a/src/web/app/src/hooks/use-search-value.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { useContext } from 'react'; -import { SearchContext, SearchContextInterface } from '../components/SearchProvider'; - -const useSearchValue = (): SearchContextInterface => useContext(SearchContext); - -export default useSearchValue;