| @@ -2,6 +2,7 @@ import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| CategoryCardContainer, | |||
| CategoryCardDetailsContainer, | |||
| CategoryCardLeftContainer, | |||
| CategoryCardRightContainer, | |||
| } from "./CategoryCard.styled"; | |||
| @@ -18,16 +19,18 @@ const CategoryCard = (props) => { | |||
| <CategoryCardContainer> | |||
| <CategoryCardLeftContainer> | |||
| <CategoryCardName categoryName={props?.category?.name} /> | |||
| <CategoryDetail | |||
| label={t("admin.categories.noOfOffers")} | |||
| value={props?.category?.offerCount} | |||
| /> | |||
| {!props.hideSecondLabel && ( | |||
| <CategoryCardDetailsContainer> | |||
| <CategoryDetail | |||
| label={props?.secondLabel} | |||
| value={props?.category?.subcategories?.length} | |||
| label={t("admin.categories.noOfOffers")} | |||
| value={props?.category?.offerCount} | |||
| /> | |||
| )} | |||
| {!props.hideSecondLabel && ( | |||
| <CategoryDetail | |||
| label={props?.secondLabel} | |||
| value={props?.category?.subcategories?.length} | |||
| /> | |||
| )} | |||
| </CategoryCardDetailsContainer> | |||
| </CategoryCardLeftContainer> | |||
| <CategoryCardRightContainer> | |||
| <CategoryRemoveButton /> | |||
| @@ -1,5 +1,6 @@ | |||
| import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| export const CategoryCardContainer = styled(Box)` | |||
| background: white; | |||
| @@ -8,9 +9,15 @@ export const CategoryCardContainer = styled(Box)` | |||
| margin: 5px; | |||
| margin-top: 13px; | |||
| margin-bottom: 13px; | |||
| border: 1px solid ${selectedTheme.colors.borderNormal}; | |||
| border-radius: 4px; | |||
| display: flex; | |||
| flex-direction: row; | |||
| justify-content: space-between; | |||
| position: relative; | |||
| @media (max-width: 600px) { | |||
| height: 102px; | |||
| } | |||
| `; | |||
| export const CategoryCardLeftContainer = styled(Box)` | |||
| display: flex; | |||
| @@ -20,3 +27,13 @@ export const CategoryCardRightContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: row; | |||
| `; | |||
| export const CategoryCardDetailsContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: row; | |||
| @media (max-width: 600px) { | |||
| position: absolute; | |||
| bottom: 18px; | |||
| left: 0; | |||
| max-height: 16px; | |||
| } | |||
| `; | |||
| @@ -14,4 +14,8 @@ export const CategoryCardNameText = styled(Typography)` | |||
| padding-top: 12px; | |||
| color: ${selectedTheme.colors.primaryPurple}; | |||
| cursor: pointer; | |||
| @media (max-width: 600px) { | |||
| font-size: 18px; | |||
| padding: 0; | |||
| } | |||
| `; | |||
| @@ -11,7 +11,16 @@ export const CategoryDetailContainer = styled(Box)` | |||
| min-width: 150px; | |||
| text-align: center; | |||
| border-left: 1px solid ${hexToRGB(selectedTheme.colors.primaryText, 0.13)}; | |||
| @media (max-width: 600px) { | |||
| margin: 0; | |||
| min-width: 123px; | |||
| &:nth-child(1) { | |||
| border-left: 0; | |||
| } | |||
| &:nth-child(2) { | |||
| padding-left: 18px; | |||
| } | |||
| } | |||
| `; | |||
| export const CategoryDetailLabel = styled(Typography)` | |||
| font-family: ${selectedTheme.fonts.textFont}; | |||
| @@ -20,6 +29,12 @@ export const CategoryDetailLabel = styled(Typography)` | |||
| letter-spacing: 0.01rem; | |||
| padding-top: 14px; | |||
| padding-right: 3px; | |||
| @media (max-width: 600px) { | |||
| position: relative; | |||
| bottom: 2.5px; | |||
| padding-top: 0; | |||
| } | |||
| `; | |||
| export const CategoryDetailValue = styled(Typography)` | |||
| font-family: ${selectedTheme.fonts.textFont}; | |||
| @@ -28,4 +43,11 @@ export const CategoryDetailValue = styled(Typography)` | |||
| line-height: 21px; | |||
| padding-top: 11px; | |||
| color: ${selectedTheme.colors.primaryPurple}; | |||
| @media (max-width: 600px) { | |||
| position: relative; | |||
| bottom: 2.5px; | |||
| padding: 0; | |||
| font-size: 12px; | |||
| font-weight: 600; | |||
| } | |||
| `; | |||
| @@ -14,10 +14,11 @@ export const CategoryEditButtonContainer = styled(IconButton)` | |||
| padding-top: 2px; | |||
| text-align: center; | |||
| @media (max-width: 600px) { | |||
| width: 30px; | |||
| height: 30px; | |||
| top: 16px; | |||
| right: 16px; | |||
| width: 32px; | |||
| height: 32px; | |||
| top: 18px; | |||
| right: 18px; | |||
| margin-right: 0; | |||
| padding: 0; | |||
| ${(props) => | |||
| props.vertical && | |||
| @@ -29,7 +30,7 @@ export const CategoryEditButtonContainer = styled(IconButton)` | |||
| height: 16px; | |||
| position: relative; | |||
| top: -3px; | |||
| left: -3.5px; | |||
| left: -1.5px; | |||
| } | |||
| } | |||
| `; | |||
| @@ -14,10 +14,10 @@ export const CategoryRemoveButtonContainer = styled(IconButton)` | |||
| padding-top: 2px; | |||
| text-align: center; | |||
| @media (max-width: 600px) { | |||
| width: 30px; | |||
| height: 30px; | |||
| top: 16px; | |||
| right: 16px; | |||
| width: 32px; | |||
| height: 32px; | |||
| top: 18px; | |||
| right: 12px; | |||
| padding: 0; | |||
| ${(props) => | |||
| props.vertical && | |||
| @@ -29,7 +29,7 @@ export const CategoryRemoveButtonContainer = styled(IconButton)` | |||
| height: 16px; | |||
| position: relative; | |||
| top: -3px; | |||
| left: -3.5px; | |||
| left: -1.5px; | |||
| } | |||
| } | |||
| `; | |||
| @@ -33,6 +33,7 @@ import MyMessagesButton from "./MyMessagesButton/MyMessagesButton"; | |||
| import UserButton from "./UserButton/UserButton"; | |||
| import LoginButton from "./LoginButton/LoginButton"; | |||
| import RegisterButton from "./RegisterButton/RegisterButton"; | |||
| import useIsMobile from "../../hooks/useIsMobile"; | |||
| const Header = () => { | |||
| const [showCreateOfferModal, setShowCreateOfferModal] = useState(false); | |||
| @@ -47,12 +48,13 @@ const Header = () => { | |||
| const drawerRef = useRef(null); | |||
| const [shouldShow, setShouldShow] = useState(true); | |||
| const routeMatch = useRouteMatch(); | |||
| const { isMobile } = useIsMobile(); | |||
| // Dont show header on auth routes(login, register, etc.) and admin routes | |||
| useEffect(() => { | |||
| if (isAuthRoute() || isAdminRoute()) setShouldShow(false); | |||
| if (isAuthRoute() || (isAdminRoute && !isMobile)) setShouldShow(false); | |||
| else setShouldShow(true); | |||
| }, [routeMatch]); | |||
| }, [routeMatch, isMobile]); | |||
| // Fetch mine profile on loading home page | |||
| useEffect(() => { | |||
| @@ -76,14 +78,19 @@ const Header = () => { | |||
| } | |||
| // Handling search when user is on marketplace and when he is not | |||
| const handleSearch = (value) => { | |||
| if (!routeMatches(HOME_PAGE) && !routeMatches(BASE_PAGE)) { | |||
| const newQueryString = new URLSearchParams({ search: value }); | |||
| history.push({ | |||
| pathname: HOME_PAGE, | |||
| search: newQueryString.toString(), | |||
| }); | |||
| if (isAdminRoute()) { | |||
| console.log("admin"); | |||
| search.setSearchStringManually(value); | |||
| } else { | |||
| search.searchOffersImmediately(value); | |||
| if (!routeMatches(HOME_PAGE) && !routeMatches(BASE_PAGE)) { | |||
| const newQueryString = new URLSearchParams({ search: value }); | |||
| history.push({ | |||
| pathname: HOME_PAGE, | |||
| search: newQueryString.toString(), | |||
| }); | |||
| } else { | |||
| search.searchOffersImmediately(value); | |||
| } | |||
| } | |||
| }; | |||
| @@ -105,7 +112,7 @@ const Header = () => { | |||
| }; | |||
| if (!shouldShow) { | |||
| return (<></>) | |||
| return <></>; | |||
| } | |||
| return ( | |||
| @@ -180,6 +187,7 @@ const Header = () => { | |||
| Header.propTypes = { | |||
| isGrid: PropTypes.bool, | |||
| showModalHandler: PropTypes.func, | |||
| manualSearch: PropTypes.func, | |||
| }; | |||
| export default Header; | |||
| @@ -147,10 +147,12 @@ const Header = (props) => { | |||
| </HeaderTitleText> | |||
| </HeaderTitleContainer> | |||
| ) : ( | |||
| <ButtonContainer onClick={goBack}> | |||
| <ArrowButton side={"left"}></ArrowButton> | |||
| <HeaderText>{t("messages.goBack")}</HeaderText> | |||
| </ButtonContainer> | |||
| !props.hideBackButton && ( | |||
| <ButtonContainer onClick={goBack}> | |||
| <ArrowButton side={"left"}></ArrowButton> | |||
| <HeaderText>{t("messages.goBack")}</HeaderText> | |||
| </ButtonContainer> | |||
| ) | |||
| )} | |||
| </> | |||
| )} | |||
| @@ -220,9 +222,21 @@ const Header = (props) => { | |||
| </HeaderContainer> | |||
| {isMobile && ( | |||
| <PageTitleContainer> | |||
| <SwapsIcon /> | |||
| {props.users ? ( | |||
| <UserIcon /> | |||
| ) : props.categories ? ( | |||
| <CategoryIcon /> | |||
| ) : ( | |||
| <SwapsIcon /> | |||
| )} | |||
| <SwapsTitle> | |||
| {props?.myOffers ? t("header.myOffers") : t("offer.offers")} | |||
| {props.users | |||
| ? t("admin.users.headerTitle") | |||
| : props.categories | |||
| ? t("admin.categories.headerTitle") | |||
| : props?.myOffers | |||
| ? t("header.myOffers") | |||
| : t("offer.offers")} | |||
| </SwapsTitle> | |||
| </PageTitleContainer> | |||
| )} | |||
| @@ -244,6 +258,7 @@ Header.propTypes = { | |||
| categories: PropTypes.bool, | |||
| hideGrid: PropTypes.bool, | |||
| className: PropTypes.string, | |||
| hideBackButton: PropTypes.bool, | |||
| }; | |||
| Header.defaultProps = { | |||
| isGrid: false, | |||
| @@ -199,12 +199,19 @@ export const CategoryIcon = styled(Category)` | |||
| position: relative; | |||
| top: 4px; | |||
| right: 2px; | |||
| ` | |||
| `; | |||
| export const PageTitleContainer = styled(Box)` | |||
| position: relative; | |||
| left: 6px; | |||
| margin-top: 36px; | |||
| width: 100px; | |||
| @media (max-width: 600px) { | |||
| & svg { | |||
| width: 12px; | |||
| height: 12px; | |||
| top: 2px; | |||
| } | |||
| } | |||
| `; | |||
| export const SwapsIcon = styled(RefreshIcon)` | |||
| width: 12px; | |||
| @@ -28,7 +28,8 @@ const SearchField = (props) => { | |||
| const handleSearch = () => { | |||
| if (props.isAdmin) { | |||
| console.log(searchRef.current.value); | |||
| search.searchOffersImmediately(searchRef.current.value); | |||
| if (props.handleSearch) props.handleSearch(searchRef.current.value); | |||
| else search.searchOffersImmediately(searchRef.current.value); | |||
| } else { | |||
| props.searchMyOffers(searchRef.current.value); | |||
| props.handleSearch(); | |||
| @@ -3,8 +3,14 @@ import { useDispatch, useSelector } from "react-redux"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import { BASE_PAGE, HOME_PAGE } from "../../constants/pages"; | |||
| import { KEY_SEARCH } from "../../constants/queryStringConstants"; | |||
| import { setSearchString } from "../../store/actions/filters/filtersActions"; | |||
| import { selectSearchString } from "../../store/selectors/filtersSelectors"; | |||
| import { | |||
| setManualSearchString, | |||
| setSearchString, | |||
| } from "../../store/actions/filters/filtersActions"; | |||
| import { | |||
| selectManualSearchString, | |||
| selectSearchString, | |||
| } from "../../store/selectors/filtersSelectors"; | |||
| import { routeMatches } from "../../util/helpers/routeHelpers"; | |||
| const useSearch = (applyAllFilters) => { | |||
| @@ -13,6 +19,7 @@ const useSearch = (applyAllFilters) => { | |||
| const dispatch = useDispatch(); | |||
| const searchString = useSelector(selectSearchString); | |||
| const history = useHistory(); | |||
| const manualSearchString = useSelector(selectManualSearchString); | |||
| // On every global change of search string, new request to backend should be sent | |||
| useEffect(() => { | |||
| @@ -48,18 +55,20 @@ const useSearch = (applyAllFilters) => { | |||
| }, [searchStringLocally]); | |||
| const searchOffers = (searchValue) => { | |||
| console.log('searchoff') | |||
| setIsInitiallyLoaded(true); | |||
| setSearchStringLocally(searchValue); | |||
| }; | |||
| const searchOffersImmediately = (searchValue) => { | |||
| console.log('searchoffersimm'); | |||
| setIsInitiallyLoaded(true); | |||
| searchOffers(searchValue); | |||
| applyAllFilters(); | |||
| }; | |||
| const setSearchStringManually = (searchValue) => { | |||
| dispatch(setManualSearchString(searchValue)); | |||
| }; | |||
| const clear = () => { | |||
| setSearchStringLocally(""); | |||
| }; | |||
| @@ -67,9 +76,11 @@ const useSearch = (applyAllFilters) => { | |||
| return { | |||
| searchOffers, | |||
| setSearchStringLocally, | |||
| setSearchStringManually, | |||
| searchOffersImmediately, | |||
| searchStringLocally, | |||
| searchString, | |||
| manualSearchString, | |||
| clear, | |||
| }; | |||
| }; | |||
| @@ -11,22 +11,49 @@ import { | |||
| AdminCategoriesPageContainer, | |||
| AdminCategoriesSearchField, | |||
| } from "./AdminCategoriesPage.styled"; | |||
| import { selectManualSearchString } from "../../store/selectors/filtersSelectors"; | |||
| import { useMemo } from "react"; | |||
| import { setManualSearchString } from "../../store/actions/filters/filtersActions"; | |||
| const AdminCategoriesPage = () => { | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const categories = useSelector(selectCategories); | |||
| const manualSearchString = useSelector(selectManualSearchString); | |||
| useEffect(() => { | |||
| dispatch(fetchCategories()); | |||
| }, []); | |||
| const handleSearch = (value) => { | |||
| console.log(value); | |||
| dispatch(setManualSearchString(value)); | |||
| }; | |||
| const categoriesToShow = useMemo(() => { | |||
| if (categories) { | |||
| console.log(categories); | |||
| console.log(manualSearchString); | |||
| if (manualSearchString) | |||
| return categories.filter((item) => | |||
| item.name.toLowerCase().includes(manualSearchString.toLowerCase()) | |||
| ); | |||
| return categories; | |||
| } | |||
| return []; | |||
| }, [categories, manualSearchString]); | |||
| return ( | |||
| <AdminCategoriesPageContainer> | |||
| <AdminCategoriesSearchField | |||
| isAdmin | |||
| handleSearch={handleSearch} | |||
| placeholder={t("admin.categories.placeholder")} | |||
| /> | |||
| <AdminCategoriesHeader myOffers categories hideGrid isAdmin /> | |||
| {categories.map((category) => ( | |||
| <AdminCategoriesHeader | |||
| myOffers | |||
| categories | |||
| hideGrid | |||
| isAdmin | |||
| hideBackButton | |||
| /> | |||
| {categoriesToShow.map((category) => ( | |||
| <CategoryCard | |||
| key={category._id} | |||
| category={category} | |||
| @@ -5,11 +5,28 @@ import SearchField from "../../components/TextFields/SearchField/SearchField"; | |||
| export const AdminCategoriesPageContainer = styled(Box)` | |||
| padding: 60px; | |||
| @media (max-width: 600px) { | |||
| padding: 18px; | |||
| position: relative; | |||
| top: 65px; | |||
| } | |||
| `; | |||
| export const AdminCategoriesHeader = styled(Header)` | |||
| /* top: 40px; */ | |||
| top: 0; | |||
| ` | |||
| /* top: 40px; */ | |||
| top: 0; | |||
| @media (max-width: 600px) { | |||
| top: -10px; | |||
| & div { | |||
| margin-top: 0; | |||
| } | |||
| & div div:nth-child(1) { | |||
| top: 22px; | |||
| } | |||
| } | |||
| `; | |||
| export const AdminCategoriesSearchField = styled(SearchField)` | |||
| top: -15px; | |||
| ` | |||
| top: -15px; | |||
| @media (max-width: 600px) { | |||
| display: none; | |||
| } | |||
| `; | |||
| @@ -1,6 +1,6 @@ | |||
| import { createClearType, createSetType } from "../actionHelpers" | |||
| import { createClearType, createSetType } from "../actionHelpers"; | |||
| const FILTERS_SCOPE = "FILTERS" | |||
| const FILTERS_SCOPE = "FILTERS"; | |||
| export const SET_FILTERS = createSetType(FILTERS_SCOPE); | |||
| export const CLEAR_FILTERS = createClearType(FILTERS_SCOPE); | |||
| export const SET_CATEGORY = createSetType("FILTERS_SET_CATEGORY"); | |||
| @@ -11,3 +11,6 @@ export const SET_IS_APPLIED = createSetType("FILTERS_SET_IS_APPLIED"); | |||
| export const SET_QUERY_STRING = createSetType("FILTERS_SET_QUERY_STRING"); | |||
| export const SET_HEADER_STRING = createSetType("FILTERS_SET_HEADER_STRING"); | |||
| export const SET_SEARCH_STRING = createSetType("FILTERS_SET_SEARCH"); | |||
| export const SET_MANUAL_SEARCH_STRING = createSetType( | |||
| "FILTERS_SET_MANUAL_SEARCH_STRING" | |||
| ); | |||
| @@ -1,41 +1,57 @@ | |||
| import { CLEAR_FILTERS, SET_CATEGORY, SET_FILTERS, SET_HEADER_STRING, SET_IS_APPLIED, SET_LOCATIONS, SET_QUERY_STRING, SET_SEARCH_STRING, SET_SORT_OPTION, SET_SUBCATEGORY } from "./filtersActionConstants"; | |||
| import { | |||
| CLEAR_FILTERS, | |||
| SET_CATEGORY, | |||
| SET_FILTERS, | |||
| SET_HEADER_STRING, | |||
| SET_IS_APPLIED, | |||
| SET_LOCATIONS, | |||
| SET_MANUAL_SEARCH_STRING, | |||
| SET_QUERY_STRING, | |||
| SET_SEARCH_STRING, | |||
| SET_SORT_OPTION, | |||
| SET_SUBCATEGORY, | |||
| } from "./filtersActionConstants"; | |||
| export const setFilters = (payload) => ({ | |||
| type: SET_FILTERS, | |||
| payload, | |||
| }) | |||
| type: SET_FILTERS, | |||
| payload, | |||
| }); | |||
| export const clearFilters = () => ({ | |||
| type: CLEAR_FILTERS | |||
| }) | |||
| type: CLEAR_FILTERS, | |||
| }); | |||
| export const setFilteredCategory = (payload) => ({ | |||
| type: SET_CATEGORY, | |||
| payload | |||
| }) | |||
| type: SET_CATEGORY, | |||
| payload, | |||
| }); | |||
| export const setFilteredSubcategory = (payload) => ({ | |||
| type: SET_SUBCATEGORY, | |||
| payload | |||
| }) | |||
| type: SET_SUBCATEGORY, | |||
| payload, | |||
| }); | |||
| export const setManualSearchString = (payload) => ({ | |||
| type: SET_MANUAL_SEARCH_STRING, | |||
| payload, | |||
| }); | |||
| export const setFilteredLocations = (payload) => ({ | |||
| type: SET_LOCATIONS, | |||
| payload | |||
| }) | |||
| type: SET_LOCATIONS, | |||
| payload, | |||
| }); | |||
| export const setFilteredSortOption = (payload) => ({ | |||
| type: SET_SORT_OPTION, | |||
| payload | |||
| }) | |||
| type: SET_SORT_OPTION, | |||
| payload, | |||
| }); | |||
| export const setIsAppliedStatus = (payload) => ({ | |||
| type: SET_IS_APPLIED, | |||
| payload, | |||
| }) | |||
| type: SET_IS_APPLIED, | |||
| payload, | |||
| }); | |||
| export const setQueryString = (payload) => ({ | |||
| type: SET_QUERY_STRING, | |||
| payload, | |||
| }) | |||
| type: SET_QUERY_STRING, | |||
| payload, | |||
| }); | |||
| export const setHeaderString = (payload) => ({ | |||
| type: SET_HEADER_STRING, | |||
| payload | |||
| }) | |||
| type: SET_HEADER_STRING, | |||
| payload, | |||
| }); | |||
| export const setSearchString = (payload) => ({ | |||
| type: SET_SEARCH_STRING, | |||
| payload | |||
| }) | |||
| type: SET_SEARCH_STRING, | |||
| payload, | |||
| }); | |||
| @@ -5,6 +5,7 @@ import { | |||
| SET_HEADER_STRING, | |||
| SET_IS_APPLIED, | |||
| SET_LOCATIONS, | |||
| SET_MANUAL_SEARCH_STRING, | |||
| SET_SEARCH_STRING, | |||
| SET_SORT_OPTION, | |||
| SET_SUBCATEGORY, | |||
| @@ -23,9 +24,10 @@ const initialState = { | |||
| categoryString: "", | |||
| subcategoryString: "", | |||
| locationsString: "", | |||
| text: "" | |||
| text: "", | |||
| }, | |||
| searchString: "" | |||
| searchString: "", | |||
| manualSearchString: "", | |||
| }, | |||
| }; | |||
| @@ -40,10 +42,21 @@ export default createReducer( | |||
| [SET_IS_APPLIED]: setIsAppliedStatus, | |||
| [SET_HEADER_STRING]: setHeaderString, | |||
| [SET_SEARCH_STRING]: setSearchString, | |||
| [SET_MANUAL_SEARCH_STRING]: setManualSearchString, | |||
| }, | |||
| initialState | |||
| ); | |||
| function setManualSearchString(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| manualSearchString: payload, | |||
| }, | |||
| }; | |||
| } | |||
| function setFilters(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| @@ -84,39 +97,39 @@ function setFilteredLocations(state, { payload }) { | |||
| }, | |||
| }; | |||
| } | |||
| function setFilteredSortOption(state, {payload}) { | |||
| function setFilteredSortOption(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| sortOption: payload, | |||
| } | |||
| } | |||
| }, | |||
| }; | |||
| } | |||
| function setIsAppliedStatus(state, {payload}) { | |||
| function setIsAppliedStatus(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| isApplied: payload, | |||
| } | |||
| } | |||
| }, | |||
| }; | |||
| } | |||
| function setHeaderString(state, {payload}) { | |||
| function setHeaderString(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| headerString: payload | |||
| } | |||
| } | |||
| headerString: payload, | |||
| }, | |||
| }; | |||
| } | |||
| function setSearchString(state, {payload}) { | |||
| function setSearchString(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| searchString: payload | |||
| } | |||
| } | |||
| searchString: payload, | |||
| }, | |||
| }; | |||
| } | |||
| @@ -1,36 +1,40 @@ | |||
| import { createSelector } from 'reselect'; | |||
| import { createSelector } from "reselect"; | |||
| const filtersSelector = (state) => state.filters; | |||
| export const selectFilters = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters, | |||
| (state) => state.filters | |||
| ); | |||
| export const selectSelectedCategory = createSelector( | |||
| filtersSelector, | |||
| (state => state.filters.category) | |||
| ) | |||
| (state) => state.filters.category | |||
| ); | |||
| export const selectSelectedSubcategory = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.subcategory | |||
| ) | |||
| ); | |||
| export const selectSelectedLocations = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.locations | |||
| ) | |||
| ); | |||
| export const selectSelectedSortOption = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.sortOption | |||
| ) | |||
| ); | |||
| export const selectAppliedStatus = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.isApplied | |||
| ) | |||
| ); | |||
| export const selectHeaderString = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.headerString | |||
| ) | |||
| ); | |||
| export const selectSearchString = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.searchString, | |||
| ) | |||
| (state) => state.filters.searchString | |||
| ); | |||
| export const selectManualSearchString = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.manualSearchString | |||
| ); | |||