diff --git a/src/common/MainLayout/components/Header/Header.tsx b/src/common/MainLayout/components/Header/Header.tsx index 0ed0e90..b75e9ed 100644 --- a/src/common/MainLayout/components/Header/Header.tsx +++ b/src/common/MainLayout/components/Header/Header.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { StringParam, useQueryParam, withDefault } from 'use-query-params'; import { useTranslation } from 'react-i18next'; import { useLocation } from 'react-router-dom'; import { TWHELP, NAME } from '@config/app'; @@ -20,7 +19,7 @@ import { import { Input as InputIcon } from '@material-ui/icons'; import Link from '@common/Link/Link'; import VersionSelector from '@common/VersionSelector/VersionSelector'; -import SearchInput from './SearchInput'; +import SearchInput from '@libs/GlobalSearch/SearchInput'; export interface Props { appBarProps?: AppBarProps; @@ -30,7 +29,6 @@ export default function Header({ appBarProps = {} }: Props) { const { t } = useTranslation(NAMESPACES.COMMON); const location = useLocation(); const classes = useStyles(); - const [q] = useQueryParam('q', withDefault(StringParam, '')); const versionSelector = (
@@ -42,9 +40,7 @@ export default function Header({ appBarProps = {} }: Props) {
- + {location.pathname !== ROUTES.INDEX_PAGE && ( diff --git a/src/features/ServerPage/common/PageLayout/components/Sidebar/Sidebar.tsx b/src/features/ServerPage/common/PageLayout/components/Sidebar/Sidebar.tsx index 729c605..a4d6505 100644 --- a/src/features/ServerPage/common/PageLayout/components/Sidebar/Sidebar.tsx +++ b/src/features/ServerPage/common/PageLayout/components/Sidebar/Sidebar.tsx @@ -24,7 +24,7 @@ import { Fireplace as FireplaceIcon, } from '@material-ui/icons'; import DevNote from '@common/DevNote/DevNote'; -import SearchInput from '@common/MainLayout/components/Header/SearchInput'; +import SearchInput from '@libs/GlobalSearch/SearchInput'; import Nav from './components/Nav/Nav'; import ServerInfo from './components/ServerInfo/ServerInfo'; diff --git a/src/features/ServerPage/common/PageLayout/components/TopBar/TopBar.tsx b/src/features/ServerPage/common/PageLayout/components/TopBar/TopBar.tsx index 3049475..fb9886a 100644 --- a/src/features/ServerPage/common/PageLayout/components/TopBar/TopBar.tsx +++ b/src/features/ServerPage/common/PageLayout/components/TopBar/TopBar.tsx @@ -17,7 +17,7 @@ import { import { Menu as MenuIcon, Input as InputIcon } from '@material-ui/icons'; import VersionSelector from '@common/VersionSelector/VersionSelector'; import Link from '@common/Link/Link'; -import SearchInput from '@common/MainLayout/components/Header/SearchInput'; +import SearchInput from '@libs/GlobalSearch/SearchInput'; export interface Props { className?: string; diff --git a/src/index.tsx b/src/index.tsx index 763499a..741ab76 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,6 +7,7 @@ import { ApolloProvider } from '@apollo/client'; import { BrowserRouter, Route } from 'react-router-dom'; import { I18nextProvider } from 'react-i18next'; import { QueryParamProvider } from 'use-query-params'; +import GlobalSearchProvider from './libs/GlobalSearch/Provider'; import App from './features/App'; import createTheme from './theme/createTheme'; import createGraphQLClient from './libs/graphql/createClient'; @@ -20,7 +21,9 @@ const jsx = ( - + + + diff --git a/src/libs/GlobalSearch/Provider.tsx b/src/libs/GlobalSearch/Provider.tsx new file mode 100644 index 0000000..5395571 --- /dev/null +++ b/src/libs/GlobalSearch/Provider.tsx @@ -0,0 +1,32 @@ +import React, { useState } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; +import { useQueryParam, StringParam, withDefault } from 'use-query-params'; +import { SEARCH_PAGE } from '@config/routes'; + +import Context from './context'; + +export interface Props { + children?: React.ReactNode; +} + +function Provider({ children, ...rest }: Props) { + const [defaultQ] = useQueryParam('q', withDefault(StringParam, '')); + const history = useHistory(); + const location = useLocation(); + const [q, setQ] = useState( + location.pathname === SEARCH_PAGE ? defaultQ : '' + ); + const href = SEARCH_PAGE + `?q=${encodeURIComponent(q)}`; + + const goToSearchPage = () => { + history.push(href); + }; + + return ( + + {children} + + ); +} + +export default Provider; diff --git a/src/common/MainLayout/components/Header/SearchInput.tsx b/src/libs/GlobalSearch/SearchInput.tsx similarity index 61% rename from src/common/MainLayout/components/Header/SearchInput.tsx rename to src/libs/GlobalSearch/SearchInput.tsx index 130d5da..00c89ff 100644 --- a/src/common/MainLayout/components/Header/SearchInput.tsx +++ b/src/libs/GlobalSearch/SearchInput.tsx @@ -1,6 +1,6 @@ -import React, { useState } from 'react'; +import React from 'react'; import { useTranslation } from 'react-i18next'; -import * as ROUTES from '@config/routes'; +import useGlobalSearch from './useGlobalSearch'; import * as NAMESPACES from '@config/namespaces'; import { InputAdornment, IconButton, TextFieldProps } from '@material-ui/core'; @@ -8,13 +8,9 @@ import { Search as SearchIcon } from '@material-ui/icons'; import SearchInput from '@common/Form/SearchInput'; import Link from '@common/Link/Link'; -export type Props = TextFieldProps & { - defaultQ?: string; -}; - -function HeaderSearchInput({ defaultQ = '', ...rest }: Props) { +function CustomizedSearchInput(props: TextFieldProps) { const { t } = useTranslation(NAMESPACES.COMMON); - const [q, setQ] = useState(defaultQ); + const { q, setQ, href } = useGlobalSearch(); const trimmedQLength = q.trim().length; const iconButton = ( @@ -26,9 +22,9 @@ function HeaderSearchInput({ defaultQ = '', ...rest }: Props) { ('mainLayout.header.search')} + placeholder={t('globalSearch.searchInput.placeholder')} size="small" - {...rest} + {...props} value={q} onChange={e => { setQ(e.target.value); @@ -36,13 +32,7 @@ function HeaderSearchInput({ defaultQ = '', ...rest }: Props) { InputProps={{ startAdornment: ( - {trimmedQLength ? ( - - {iconButton} - - ) : ( - iconButton - )} + {trimmedQLength ? {iconButton} : iconButton} ), }} @@ -51,4 +41,4 @@ function HeaderSearchInput({ defaultQ = '', ...rest }: Props) { ); } -export default HeaderSearchInput; +export default CustomizedSearchInput; diff --git a/src/libs/GlobalSearch/context.ts b/src/libs/GlobalSearch/context.ts new file mode 100644 index 0000000..0710364 --- /dev/null +++ b/src/libs/GlobalSearch/context.ts @@ -0,0 +1,11 @@ +import { createContext } from 'react'; +import { ContextValue } from './types'; + +const ctx = createContext({ + href: '', + q: '', + setQ: (v: string) => {}, + goToSearchPage: () => {}, +}); + +export default ctx; diff --git a/src/libs/GlobalSearch/types.ts b/src/libs/GlobalSearch/types.ts new file mode 100644 index 0000000..436d741 --- /dev/null +++ b/src/libs/GlobalSearch/types.ts @@ -0,0 +1,6 @@ +export type ContextValue = { + href: string; + q: string; + setQ: (v: string) => void; + goToSearchPage: () => void; +}; diff --git a/src/libs/GlobalSearch/useGlobalSearch.ts b/src/libs/GlobalSearch/useGlobalSearch.ts new file mode 100644 index 0000000..76e1231 --- /dev/null +++ b/src/libs/GlobalSearch/useGlobalSearch.ts @@ -0,0 +1,9 @@ +import { useContext } from 'react'; +import ctx from './context'; +import { ContextValue } from './types'; + +const useGlobalSearch = (): ContextValue => { + return useContext(ctx); +}; + +export default useGlobalSearch; diff --git a/src/libs/i18n/en/common.ts b/src/libs/i18n/en/common.ts index e1ad62a..01d871f 100644 --- a/src/libs/i18n/en/common.ts +++ b/src/libs/i18n/en/common.ts @@ -17,10 +17,14 @@ const translations = { loading: 'Loading version...', }, devNote: `This website is still under development and some things may be broken.`, + globalSearch: { + searchInput: { + placeholder: 'Search', + }, + }, mainLayout: { header: { home: 'Home', - search: 'Search', }, }, }; diff --git a/src/libs/i18n/pl/common.ts b/src/libs/i18n/pl/common.ts index 766523f..ec95b55 100644 --- a/src/libs/i18n/pl/common.ts +++ b/src/libs/i18n/pl/common.ts @@ -17,10 +17,14 @@ const translations = { loading: 'Ładowanie wersji...', }, devNote: `Strona jest ciągle w procesie tworzenia i mogą występować błędy.`, + globalSearch: { + searchInput: { + placeholder: 'Wyszukaj', + }, + }, mainLayout: { header: { home: 'Strona główna', - search: 'Wyszukaj', }, }, }; diff --git a/src/libs/i18n/pt/common.ts b/src/libs/i18n/pt/common.ts index 0be4025..9b599ba 100644 --- a/src/libs/i18n/pt/common.ts +++ b/src/libs/i18n/pt/common.ts @@ -17,6 +17,11 @@ const translations = { loading: 'Carregando a versão...', }, devNote: `Este site ainda está em desenvolvimento e poder conter erros.`, + globalSearch: { + searchInput: { + placeholder: 'Pesquisa', + }, + }, mainLayout: { header: { home: 'Início', diff --git a/src/libs/i18n/pt_br/common.ts b/src/libs/i18n/pt_br/common.ts index 21a4fb8..ec2134c 100644 --- a/src/libs/i18n/pt_br/common.ts +++ b/src/libs/i18n/pt_br/common.ts @@ -17,6 +17,11 @@ const translations = { loading: 'Carregando a versão...', }, devNote: `Este site ainda está sendo desenvolvido e pode conter algum erro.`, + globalSearch: { + searchInput: { + placeholder: 'Pesquisa', + }, + }, mainLayout: { header: { home: 'Página inicial',