diff --git a/src/components/IOBanner.js b/src/components/IOBanner.js index 60e4f58d..37e688cf 100644 --- a/src/components/IOBanner.js +++ b/src/components/IOBanner.js @@ -6,12 +6,12 @@ import bannerOverlayLeft from '../images/io-banner/banner-style-left.svg'; import { SearchInput } from '@newrelic/gatsby-theme-newrelic'; import { QUICKSTARTS_COLLAPSE_BREAKPOINT } from '@data/constants'; -const BannerHeaderContent = ({ search, handleSearch }) => { - const updateSearch = (e) => { - const value = e.target.value; - handleSearch(value); - }; - +const BannerHeaderContent = ({ + search, + updateSearch, + handleSearch, + clearParam, +}) => { return (
{ value={search || ''} placeholder="Search" onClear={() => { + clearParam('search'); handleSearch(''); }} onSubmit={(value) => handleSearch(value)} - onChange={updateSearch} + onChange={(e) => updateSearch(e.target.value)} css={css` box-shadow: none; max-width: 816px; @@ -125,7 +126,7 @@ const BannerHeaderContent = ({ search, handleSearch }) => { ); }; -const IOBanner = ({ search, handleSearch }) => { +const IOBanner = (props) => { return (
{ loading="lazy" />
- +
{ ); }; +IOBanner.propTypes = { + search: PropTypes.string, + updateSearch: PropTypes.func, + handleSearch: PropTypes.func, + clearParam: PropTypes.func, +}; + BannerHeaderContent.propTypes = { search: PropTypes.string, + updateSearch: PropTypes.func, handleSearch: PropTypes.func, + clearParam: PropTypes.func, }; -IOBanner.propTypes = { search: PropTypes.string, handleSearch: PropTypes.func }; export default IOBanner; diff --git a/src/hooks/useSearchAndCategory.jsx b/src/hooks/useSearchAndCategory.jsx index 8950507a..5282b8a0 100644 --- a/src/hooks/useSearchAndCategory.jsx +++ b/src/hooks/useSearchAndCategory.jsx @@ -1,14 +1,10 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useCallback } from 'react'; +import { navigate } from 'gatsby'; import { useTessen } from '@newrelic/gatsby-theme-newrelic'; -import { navigate, useLocation } from '@reach/router'; import CATEGORIES from '@data/instant-observability-categories'; -const useSearchAndCategory = () => { +const useSearchAndCategory = (setSearch, setCategory, location) => { const tessen = useTessen(); - const location = useLocation(); - - const [search, setSearch] = useState(''); - const [category, setCategory] = useState(''); // used to update search and category values useEffect(() => { @@ -17,7 +13,7 @@ const useSearchAndCategory = () => { const categoryParam = params.get('category'); const validCategory = CATEGORIES.some((cat) => cat.value === categoryParam); - setSearch(searchParam); + setSearch(searchParam || ''); setCategory(categoryParam && validCategory ? categoryParam : ''); if (searchParam || categoryParam) { tessen.track({ @@ -27,45 +23,41 @@ const useSearchAndCategory = () => { quickstartCategory: categoryParam, }); } - }, [location.search, tessen]); + }, [location.search, tessen, setSearch, setCategory]); /** * Updates search parameter from location - * @param {String} value to update search term + * @param {String} parameter to set + * @param {Function => void} callback function to update search term */ - const handleSearch = (value) => { - if (value !== null && value !== undefined && value !== '') { + const handleParam = (param) => (value) => { + if (value !== null && value !== undefined) { const params = new URLSearchParams(location.search); - params.set('search', value); - navigate(`?${params.toString()}`); - } else { - const params = new URLSearchParams(location.search); - params.delete('search'); + if (value === '') { + params.delete(param); + } else { + params.set(param, value); + } - navigate(location.pathname); + navigate(`?${params.toString()}`); } }; - /** - * Updates category parameter from location - * @param {String} value to update category term - */ - const handleCategory = (value) => { - if (value !== null && value !== undefined && value !== '') { - const params = new URLSearchParams(location.search); - params.set('category', value); - - navigate(`?${params.toString()}`); - } else { - const params = new URLSearchParams(location.search); - params.delete('category'); - - navigate(location.pathname); + const clearParam = (param) => { + if (param === 'search') { + setSearch(''); } + if (param === 'category') { + setCategory(''); + } + }; + + const updateSearch = (value) => { + setSearch((s) => s + value); }; - return { search, category, handleSearch, handleCategory }; + return { handleParam, updateSearch, clearParam }; }; export default useSearchAndCategory; diff --git a/src/pages/index.jsx b/src/pages/index.jsx index f65d1649..56b6563c 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -80,12 +80,13 @@ const filterByCategory = (category) => { }; const QuickstartsPage = ({ data, location }) => { - const { - search, - category, - handleCategory, - handleSearch, - } = useSearchAndCategory(); + const [search, setSearch] = useState(''); + const [category, setCategory] = useState(''); + const { handleParam, clearParam } = useSearchAndCategory( + setSearch, + setCategory, + location + ); const [isCategoriesOverlayOpen, setIsCategoriesOverlayOpen] = useState(false); // variable to check if the page load completed @@ -277,7 +278,14 @@ const QuickstartsPage = ({ data, location }) => { location={location} type="quickstarts" /> - handleSearch && + {handleParam && ( + + )}
{ key={value} disabled={count === 0} variant={Button.VARIANT.PRIMARY} - onClick={() => handleCategory(value)} + onClick={() => handleParam('category')(value)} css={css` padding: 8px 12px; font-family: 'SoĢˆhne-Leicht'; @@ -527,7 +535,7 @@ const QuickstartsPage = ({ data, location }) => {
- {Boolean(category) && Boolean(!search) && ( + {!category && !search && ( <> {mostPopularQuickStarts.length > 0 && ( <>