| @@ -0,0 +1,49 @@ | |||
| import React, { | |||
| forwardRef, | |||
| useEffect, | |||
| useImperativeHandle, | |||
| useState, | |||
| } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { CompanyIcon } from "./CompanyChoser.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import FilterSubDropdown from "../../FilterDropdown/Checkbox/FilterSubDropdown/FilterSubDropdown"; | |||
| const CompanyChoser = forwardRef((props, ref) => { | |||
| const [isOpened, setIsOpened] = useState(false); | |||
| const filters = props.filters; | |||
| const { t } = useTranslation(); | |||
| useImperativeHandle(ref, () => ({ | |||
| closeSection: () => { | |||
| setIsOpened(false); | |||
| }, | |||
| })); | |||
| useEffect(() => { | |||
| if (filters.companies.selectedCompaniesLocally.length > 0 && !isOpened) { | |||
| setIsOpened(true); | |||
| } | |||
| }, [filters.companies.selectedCompaniesLocally]); | |||
| return ( | |||
| <FilterSubDropdown | |||
| searchPlaceholder={t("filters.company.placeholder")} | |||
| data={[...filters.companies.allCompanies]} | |||
| filters={[...filters.companies.selectedCompaniesLocally]} | |||
| open={isOpened} | |||
| handleOpen={() => setIsOpened((prevIsOpened) => !prevIsOpened)} | |||
| icon={<CompanyIcon />} | |||
| title={t("filters.company.title")} | |||
| setItemsSelected={filters.companies.setSelectedCompanies} | |||
| companies | |||
| /> | |||
| ); | |||
| }); | |||
| CompanyChoser.displayName = "CompanyChoser"; | |||
| CompanyChoser.propTypes = { | |||
| filters: PropTypes.any, | |||
| }; | |||
| export default CompanyChoser; | |||
| @@ -0,0 +1,11 @@ | |||
| import styled from "styled-components"; | |||
| import { ReactComponent as Company } from "../../../../../assets/images/svg/user-gray.svg"; | |||
| export const CompanyIcon = styled(Company)` | |||
| @media (max-width: 600px) { | |||
| width: 16px; | |||
| height: 16px; | |||
| position: relative; | |||
| bottom: 2px; | |||
| } | |||
| `; | |||
| @@ -7,6 +7,7 @@ import FilterFooter from "./FilterFooter/FilterFooter"; | |||
| import CategoryChoser from "./Choser/CategoryChoser/CategoryChoser"; | |||
| import SubcategoryChoser from "./Choser/SubcategoryChoser/SubcategoryChoser"; | |||
| import LocationChoser from "./Choser/LocationChoser/LocationChoser"; | |||
| import CompanyChoser from "./Choser/CompanyChoser/CompanyChoser"; | |||
| import SkeletonFilterCard from "./Skeleton/SkeletonFilterCard"; | |||
| const FilterCard = (props) => { | |||
| @@ -15,11 +16,14 @@ const FilterCard = (props) => { | |||
| const categoryRef = useRef(null); | |||
| const subcategoryRef = useRef(null); | |||
| const locationRef = useRef(null); | |||
| const companyRef = useRef(null); | |||
| const closeAllSections = () => { | |||
| categoryRef.current.closeSection(); | |||
| subcategoryRef.current.closeSection(); | |||
| locationRef.current.closeSection(); | |||
| companyRef.current.closeSection(); | |||
| }; | |||
| console.log(offers); | |||
| return ( | |||
| <FilterCardContainer | |||
| filtersOpened={props.filtersOpened} | |||
| @@ -54,6 +58,7 @@ const FilterCard = (props) => { | |||
| {!props.myOffers && ( | |||
| <LocationChoser filters={filters} ref={locationRef} /> | |||
| )} | |||
| <CompanyChoser filters={filters} ref={companyRef} /> | |||
| </ContentContainer> | |||
| <FilterFooter | |||
| @@ -4,15 +4,18 @@ import { CheckBox as CheckboxButton } from "../../../../../CheckBox/CheckBox"; | |||
| const Checkbox = (props) => { | |||
| const item = props.item; | |||
| return ( | |||
| <CheckboxButton | |||
| leftText={item.city} | |||
| leftText={props.companies ? item.company.name : item.city} | |||
| // rightText={item.offerCount} | |||
| value={item} | |||
| checked={ | |||
| props.filters.find( | |||
| (itemInList) => | |||
| itemInList?.city?.toString() === item?.city?.toString() | |||
| props.filters.find((itemInList) => | |||
| props.companies | |||
| ? itemInList?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| : itemInList?.city?.toString() === item?.city?.toString() | |||
| ) | |||
| ? true | |||
| : false | |||
| @@ -27,6 +30,7 @@ Checkbox.propTypes = { | |||
| item: PropTypes.any, | |||
| filters: PropTypes.any, | |||
| onChange: PropTypes.func, | |||
| companies: PropTypes.bool, | |||
| }; | |||
| export default Checkbox; | |||
| @@ -31,9 +31,7 @@ const CheckboxDropdownList = (props) => { | |||
| : selectedTheme.colors.primaryText | |||
| } | |||
| dropdownIcon={ | |||
| <NumberedIcon number={props.filters.length}> | |||
| {props.icon} | |||
| </NumberedIcon> | |||
| <NumberedIcon number={props.filters.length}>{props.icon}</NumberedIcon> | |||
| } | |||
| toggleIconClosed={<DropdownDown />} | |||
| toggleIconOpened={<DropdownUp />} | |||
| @@ -49,12 +47,20 @@ const CheckboxDropdownList = (props) => { | |||
| <React.Fragment> | |||
| <SelectedItemsContainer> | |||
| {props.filters.map((item) => ( | |||
| <SelectedItem key={item.city} onClick={() => handleDelete(item)}> | |||
| { | |||
| data.find( | |||
| (p) => p?.city?.toString() === item?.city?.toString() | |||
| )?.city | |||
| } | |||
| <SelectedItem | |||
| key={props.companies ? item.company.name : item.city} | |||
| onClick={() => handleDelete(item)} | |||
| > | |||
| {props.companies | |||
| ? data.find( | |||
| (p) => | |||
| p?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| )?.company?.name | |||
| : data.find( | |||
| (p) => p?.city?.toString() === item?.city?.toString() | |||
| )?.city} | |||
| <CloseIcon /> | |||
| </SelectedItem> | |||
| ))} | |||
| @@ -85,6 +91,7 @@ CheckboxDropdownList.propTypes = { | |||
| setIsOpened: PropTypes.func, | |||
| open: PropTypes.bool, | |||
| handleOpen: PropTypes.func, | |||
| companies: PropTypes.bool, | |||
| }; | |||
| export default CheckboxDropdownList; | |||
| @@ -18,7 +18,9 @@ const FilterCheckboxDropdown = (props) => { | |||
| if (toSearch.length > 0) { | |||
| setDataToShow( | |||
| data.filter((item) => | |||
| item.city.toLowerCase().includes(toSearch.toLowerCase()) | |||
| props.companies | |||
| ? item.company.name.toLowerCase().includes(toSearch.toLowerCase()) | |||
| : item.city.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ) | |||
| ); | |||
| } else { | |||
| @@ -69,6 +71,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| open={props?.open !== undefined ? props.open : isOpened} | |||
| handleOpen={handleOpen} | |||
| setItemsSelected={props.setItemsSelected} | |||
| companies={props.companies} | |||
| > | |||
| {dataToShow.map((item) => { | |||
| return ( | |||
| @@ -77,6 +80,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| item={item} | |||
| filters={props.filters} | |||
| onChange={() => handleChange(item)} | |||
| companies={props.companies} | |||
| /> | |||
| </DropdownItem> | |||
| ); | |||
| @@ -96,6 +100,7 @@ FilterCheckboxDropdown.propTypes = { | |||
| filters: PropTypes.array, | |||
| open: PropTypes.bool, | |||
| handleOpen: PropTypes.func, | |||
| companies: PropTypes.bool, | |||
| }; | |||
| FilterCheckboxDropdown.defaultProps = { | |||
| oneValueAllowed: false, | |||
| @@ -0,0 +1,109 @@ | |||
| import React, { useState, useEffect } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import Checkbox from "../../Checkbox/Checkbox"; | |||
| import DropdownItem from "../../../../../../Dropdown/DropdownItem/DropdownItem"; | |||
| import { filterCompanies } from "../../../../../../../util/helpers/filterCompanies"; | |||
| import { | |||
| REGEXP_FIRST, | |||
| REGEXP_SECOND, | |||
| REGEXP_THIRD, | |||
| } from "../../../../../../../constants/filterCompanies"; | |||
| import { | |||
| SmallDropdownContainer, | |||
| SmallDropdownContent, | |||
| SmallDropdownIcon, | |||
| SmallDropdownText, | |||
| } from "./FilterSmallDropdown.styled"; | |||
| const FilterSmallDropdown = (props) => { | |||
| const [data, setData] = useState([]); | |||
| const [showDropdown, setShowDropdown] = useState(false); | |||
| useEffect(() => { | |||
| setData([...props.dataToShow]); | |||
| }, [props.dataToShow]); | |||
| let dataFiltered; | |||
| if (props.letters === "A-H") { | |||
| dataFiltered = filterCompanies(data, REGEXP_FIRST); | |||
| } else if (props.letters === "I-Q") { | |||
| dataFiltered = filterCompanies(data, REGEXP_SECOND); | |||
| } else if (props.letters === "R-Z") { | |||
| dataFiltered = filterCompanies(data, REGEXP_THIRD); | |||
| } | |||
| const handleChange = (item) => { | |||
| if (props.oneValueAllowed) { | |||
| props.setItemsSelected([item]); | |||
| } else { | |||
| if ( | |||
| props.filters.find( | |||
| (itemInList) => | |||
| itemInList?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| ) | |||
| ) { | |||
| props.setItemsSelected([ | |||
| ...props.filters.filter( | |||
| (p) => | |||
| p?.company?.name?.toString() !== item?.company?.name?.toString() | |||
| ), | |||
| ]); | |||
| } else { | |||
| props.setItemsSelected([...props.filters, item]); | |||
| } | |||
| } | |||
| }; | |||
| const setDropdownHandler = () => { | |||
| setShowDropdown((prevState) => !prevState); | |||
| }; | |||
| return ( | |||
| <> | |||
| <SmallDropdownContainer> | |||
| <SmallDropdownText>{props.letters}</SmallDropdownText> | |||
| <SmallDropdownIcon | |||
| onClick={() => setDropdownHandler()} | |||
| dropdown={showDropdown} | |||
| /> | |||
| </SmallDropdownContainer> | |||
| <SmallDropdownContent dropdown={showDropdown}> | |||
| {dataFiltered.map((item) => { | |||
| return ( | |||
| <DropdownItem key={item.company._id}> | |||
| <Checkbox | |||
| item={item} | |||
| filters={props.filters} | |||
| onChange={() => handleChange(item)} | |||
| companies={props.companies} | |||
| /> | |||
| </DropdownItem> | |||
| ); | |||
| })} | |||
| </SmallDropdownContent> | |||
| </> | |||
| ); | |||
| }; | |||
| FilterSmallDropdown.propTypes = { | |||
| children: PropTypes.node, | |||
| icon: PropTypes.node, | |||
| data: PropTypes.array, | |||
| title: PropTypes.string, | |||
| oneValueAllowed: PropTypes.bool, | |||
| searchPlaceholder: PropTypes.string, | |||
| setItemsSelected: PropTypes.func, | |||
| filters: PropTypes.array, | |||
| open: PropTypes.bool, | |||
| handleOpen: PropTypes.func, | |||
| companies: PropTypes.bool, | |||
| letters: PropTypes.any, | |||
| dataToShow: PropTypes.array, | |||
| }; | |||
| FilterSmallDropdown.defaultProps = { | |||
| oneValueAllowed: false, | |||
| }; | |||
| export default FilterSmallDropdown; | |||
| @@ -0,0 +1,30 @@ | |||
| import styled from "styled-components"; | |||
| import { Box, Typography } from "@mui/material"; | |||
| import { ReactComponent as DropdownDown } from "../../../../../../../assets/images/svg/down-arrow.svg"; | |||
| export const SmallDropdownContainer = styled(Box)` | |||
| display: flex; | |||
| align-items: center; | |||
| gap: 8px; | |||
| margin-top: 20px; | |||
| margin-left: -20px; | |||
| margin-bottom: 14px; | |||
| `; | |||
| export const SmallDropdownText = styled(Typography)` | |||
| font-family: "DM Sans"; | |||
| font-size: 12px; | |||
| `; | |||
| export const SmallDropdownIcon = styled(DropdownDown)` | |||
| width: 12px; | |||
| ${(props) => | |||
| props.dropdown && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| `; | |||
| export const SmallDropdownContent = styled(Box)` | |||
| display: ${(props) => (props.dropdown ? "block" : "none")}; | |||
| `; | |||
| @@ -0,0 +1,99 @@ | |||
| import React, { useState, useEffect } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import CheckboxDropdownList from "../CheckboxDropdownList/CheckboxDropdownList"; | |||
| import FilterSmallDropdown from "./FilterSmallDropdown/FilterSmallDropdown"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const FilterSubDropdown = (props) => { | |||
| const [dataToShow, setDataToShow] = useState([]); | |||
| const [isOpened, setIsOpened] = useState(false); | |||
| const [toSearch, setToSearch] = useState(""); | |||
| const { t } = useTranslation(); | |||
| const { data } = props; | |||
| useEffect(() => { | |||
| setDataToShow([...data]); | |||
| }, [data]); | |||
| useEffect(() => { | |||
| if (toSearch.length > 0) { | |||
| setDataToShow( | |||
| data.filter((item) => | |||
| props.companies | |||
| ? item.company.name.toLowerCase().includes(toSearch.toLowerCase()) | |||
| : item.city.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ) | |||
| ); | |||
| } else { | |||
| setDataToShow([...data]); | |||
| } | |||
| }, [toSearch]); | |||
| useEffect(() => { | |||
| if (props.filters?.length > 0) { | |||
| setIsOpened(true); | |||
| } | |||
| }, [props.filters]); | |||
| const handleOpen = () => { | |||
| setIsOpened((prevState) => !prevState); | |||
| if (props.handleOpen) props.handleOpen(); | |||
| }; | |||
| return ( | |||
| <CheckboxDropdownList | |||
| toSearch={toSearch} | |||
| setToSearch={setToSearch} | |||
| title={props.title} | |||
| filters={props.filters} | |||
| icon={props.icon} | |||
| data={data} | |||
| searchPlaceholder={props.searchPlaceholder} | |||
| open={props?.open !== undefined ? props.open : isOpened} | |||
| handleOpen={handleOpen} | |||
| setItemsSelected={props.setItemsSelected} | |||
| companies={props.companies} | |||
| > | |||
| <FilterSmallDropdown | |||
| letters={t("filters.company.firstSort")} | |||
| dataToShow={dataToShow} | |||
| filters={props.filters} | |||
| setItemsSelected={props.setItemsSelected} | |||
| companies={props.companies} | |||
| /> | |||
| <FilterSmallDropdown | |||
| letters={t("filters.company.secondSort")} | |||
| dataToShow={dataToShow} | |||
| filters={props.filters} | |||
| setItemsSelected={props.setItemsSelected} | |||
| companies={props.companies} | |||
| /> | |||
| <FilterSmallDropdown | |||
| letters={t("filters.company.thirdSort")} | |||
| dataToShow={dataToShow} | |||
| filters={props.filters} | |||
| setItemsSelected={props.setItemsSelected} | |||
| companies={props.companies} | |||
| /> | |||
| </CheckboxDropdownList> | |||
| ); | |||
| }; | |||
| FilterSubDropdown.propTypes = { | |||
| children: PropTypes.node, | |||
| icon: PropTypes.node, | |||
| data: PropTypes.array, | |||
| title: PropTypes.string, | |||
| oneValueAllowed: PropTypes.bool, | |||
| searchPlaceholder: PropTypes.string, | |||
| setItemsSelected: PropTypes.func, | |||
| filters: PropTypes.array, | |||
| open: PropTypes.bool, | |||
| handleOpen: PropTypes.func, | |||
| companies: PropTypes.bool, | |||
| }; | |||
| FilterSubDropdown.defaultProps = { | |||
| oneValueAllowed: false, | |||
| }; | |||
| export default FilterSubDropdown; | |||
| @@ -0,0 +1,43 @@ | |||
| import styled from "styled-components"; | |||
| import { Box, Typography } from "@mui/material"; | |||
| import { ReactComponent as DropdownDown } from "../../../../../../assets/images/svg/down-arrow.svg"; | |||
| export const SmallDropdownContainer = styled(Box)` | |||
| display: flex; | |||
| align-items: center; | |||
| gap: 8px; | |||
| margin-top: 20px; | |||
| margin-left: -20px; | |||
| margin-bottom: 14px; | |||
| `; | |||
| export const SmallDropdownText = styled(Typography)` | |||
| font-family: "DM Sans"; | |||
| font-size: 12px; | |||
| `; | |||
| export const SmallDropdownIcon = styled(DropdownDown)` | |||
| width: 12px; | |||
| ${(props) => | |||
| props.firstDropdown && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| ${(props) => | |||
| props.secondDropdown && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| ${(props) => | |||
| props.thirdDropdown && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| `; | |||
| export const SmallDropdownContent = styled(Box)` | |||
| display: ${(props) => | |||
| props.firstDropdown || props.secondDropdown || props.thirdDropdown | |||
| ? "block" | |||
| : "none"}; | |||
| `; | |||
| @@ -0,0 +1,3 @@ | |||
| export const REGEXP_FIRST = /^[a-hA-H]/; | |||
| export const REGEXP_SECOND = /^[i-qI-Q]/; | |||
| export const REGEXP_THIRD = /^[r-zR-Z]/; | |||
| @@ -0,0 +1,58 @@ | |||
| import { useEffect, useState } from "react"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import { setFilteredCompany } from "../../store/actions/filters/filtersActions"; | |||
| import { fetchAllProfiles } from "../../store/actions/profile/profileActions"; | |||
| import { selectSelectedCompany } from "../../store/selectors/filtersSelectors"; | |||
| import { selectAllProfiles } from "../../store/selectors/profileSelectors"; | |||
| const useCompaniesFilter = () => { | |||
| const selectedCompanies = useSelector(selectSelectedCompany); | |||
| const dispatch = useDispatch(); | |||
| const allCompanies = useSelector(selectAllProfiles); | |||
| const [selectedCompaniesLocally, setSelectedCompaniesLocally] = useState([]); | |||
| useEffect(() => { | |||
| dispatch(fetchAllProfiles()); | |||
| }, []); | |||
| useEffect(() => { | |||
| setSelectedCompaniesLocally(selectedCompanies); | |||
| }, [selectedCompanies]); | |||
| const setSelectedCompanies = (companies, immediateApply = false) => { | |||
| setSelectedCompaniesLocally(companies); | |||
| if (immediateApply) { | |||
| dispatch(setFilteredCompany(companies)); | |||
| } | |||
| }; | |||
| const setSelectedCompaniesFromArray = (companies) => { | |||
| let companiesToPush = []; | |||
| companies.forEach((companyName) => { | |||
| companiesToPush.push( | |||
| allCompanies.find((p) => p.company.name === companyName) | |||
| ); | |||
| }); | |||
| setSelectedCompanies([...companiesToPush]); | |||
| }; | |||
| const apply = () => { | |||
| dispatch(setFilteredCompany(selectedCompaniesLocally)); | |||
| }; | |||
| const clear = () => { | |||
| setSelectedCompaniesLocally([]); | |||
| dispatch(setFilteredCompany([])); | |||
| }; | |||
| return { | |||
| selectedCompanies, | |||
| selectedCompaniesLocally, | |||
| setSelectedCompanies, | |||
| setSelectedCompaniesFromArray, | |||
| allCompanies, | |||
| apply, | |||
| clear, | |||
| }; | |||
| }; | |||
| export default useCompaniesFilter; | |||
| @@ -1,5 +1,6 @@ | |||
| import { useEffect, useMemo } from "react"; | |||
| import useCategoryFilter from "./useCategoryFilter"; | |||
| import useCompaniesFilter from "./useCompanyFilter"; | |||
| import useLocationsFilter from "./useLocationsFilter"; | |||
| import useSubcategoryFilter from "./useSubcategoryFilter"; | |||
| @@ -7,6 +8,7 @@ const useFilters = (clearAll = false) => { | |||
| const category = useCategoryFilter(); | |||
| const subcategory = useSubcategoryFilter(); | |||
| const locations = useLocationsFilter(); | |||
| const companies = useCompaniesFilter(); | |||
| useEffect(() => { | |||
| if (clearAll) { | |||
| @@ -24,12 +26,14 @@ const useFilters = (clearAll = false) => { | |||
| category.selectedCategoryLocally, | |||
| subcategory.selectedSubcategoryLocally, | |||
| locations.selectedLocationsLocally, | |||
| companies.selectedCompaniesLocally, | |||
| ]); | |||
| const apply = (immediatelyApply = false, applyAllFilters) => { | |||
| category.apply(); | |||
| subcategory.apply(); | |||
| locations.apply(); | |||
| companies.apply(); | |||
| if (immediatelyApply) applyAllFilters(); | |||
| }; | |||
| @@ -37,12 +41,14 @@ const useFilters = (clearAll = false) => { | |||
| category.clear(); | |||
| subcategory.clear(); | |||
| locations.clear(); | |||
| companies.clear(); | |||
| }; | |||
| return { | |||
| category, | |||
| subcategory, | |||
| locations, | |||
| companies, | |||
| numOfFiltersChosen, | |||
| apply, | |||
| clear, | |||
| @@ -28,7 +28,7 @@ const useLocationsFilter = () => { | |||
| locations.forEach((locationName) => { | |||
| locationsToPush.push(allLocations.find((p) => p.city === locationName)); | |||
| }); | |||
| setSelectedLocations([...locationsToPush]) | |||
| setSelectedLocations([...locationsToPush]); | |||
| }; | |||
| const apply = () => { | |||
| @@ -19,10 +19,10 @@ export default { | |||
| labelPassword: "Lozinka", | |||
| labelFirm: "Ime Firme", | |||
| labelPIB: "PIB", | |||
| labelPhone: "Telefon", | |||
| labelPhone: "Telefon (opciono)", | |||
| labelPhoneNumber: "Broj telefona", | |||
| labelLocation: "Lokacija", | |||
| labelWebsite: "Adresa Websajta", | |||
| labelLocation: "Lokacija (opciono)", | |||
| labelWebsite: "Adresa Websajta (opciono)", | |||
| logout: "Odjavi se", | |||
| next: "Sledeće", | |||
| nextPage: "Sledeća strana", | |||
| @@ -156,6 +156,13 @@ export default { | |||
| title: "Lokacija", | |||
| placeholder: "Pretraži gradove...", | |||
| }, | |||
| company: { | |||
| title: "Kompanija", | |||
| placeholder: "Pretraži kompanije...", | |||
| firstSort: "A-H", | |||
| secondSort: "I-Q", | |||
| thirdSort: "R-Z", | |||
| }, | |||
| }, | |||
| offer: { | |||
| title: "NASLOV", | |||
| @@ -453,15 +460,15 @@ export default { | |||
| title: "Izmena Kategorije", | |||
| fieldTitle: "Naslov", | |||
| placeholder: "Naziv kategorije...", | |||
| save: "Izmeni" | |||
| save: "Izmeni", | |||
| }, | |||
| add: { | |||
| title: "Nova Kategorija", | |||
| fieldTitle: "Naslov", | |||
| placeholder: "Naziv kategorije...", | |||
| save: "Dodaj", | |||
| next: "Sledeća" | |||
| } | |||
| next: "Sledeća", | |||
| }, | |||
| }, | |||
| subcategories: { | |||
| noOfOffers: "Broj objava: ", | |||
| @@ -469,20 +476,21 @@ export default { | |||
| subcategoriesHeaderTitle: "Podkategorije", | |||
| placeholder: "Pretražite podkategorije...", | |||
| addSubcategory: "Dodaj podkategoriju", | |||
| reassuranceDelete: "Da li ste sigurni da želite da obrišete odabranu podkategoriju?", | |||
| reassuranceDelete: | |||
| "Da li ste sigurni da želite da obrišete odabranu podkategoriju?", | |||
| edit: { | |||
| title: "Izmena Podkategorije", | |||
| fieldTitle: "Naslov", | |||
| placeholder: "Naziv podkategorije...", | |||
| save: "Izmeni" | |||
| save: "Izmeni", | |||
| }, | |||
| add: { | |||
| title: "Nova Podkategorija", | |||
| fieldTitle: "Naslov", | |||
| placeholder: "Naziv podkategorije...", | |||
| save: "Dodaj", | |||
| next: "Sledeća" | |||
| } | |||
| next: "Sledeća", | |||
| }, | |||
| }, | |||
| }, | |||
| }; | |||
| @@ -6,6 +6,7 @@ export const CLEAR_FILTERS = createClearType(FILTERS_SCOPE); | |||
| export const SET_CATEGORY = createSetType("FILTERS_SET_CATEGORY"); | |||
| export const SET_SUBCATEGORY = createSetType("FILTERS_SET_SUBCATEGORY"); | |||
| export const SET_LOCATIONS = createSetType("FILTERS_SET_LOCATIONS"); | |||
| export const SET_COMPANY = createSetType("FILTERS_SET_COMPANY"); | |||
| export const SET_SORT_OPTION = createSetType("FILTERS_SET_SORT_OPTION"); | |||
| export const SET_IS_APPLIED = createSetType("FILTERS_SET_IS_APPLIED"); | |||
| export const SET_QUERY_STRING = createSetType("FILTERS_SET_QUERY_STRING"); | |||
| @@ -1,6 +1,7 @@ | |||
| import { | |||
| CLEAR_FILTERS, | |||
| SET_CATEGORY, | |||
| SET_COMPANY, | |||
| SET_FILTERS, | |||
| SET_HEADER_STRING, | |||
| SET_IS_APPLIED, | |||
| @@ -35,6 +36,10 @@ export const setFilteredLocations = (payload) => ({ | |||
| type: SET_LOCATIONS, | |||
| payload, | |||
| }); | |||
| export const setFilteredCompany = (payload) => ({ | |||
| type: SET_COMPANY, | |||
| payload, | |||
| }); | |||
| export const setFilteredSortOption = (payload) => ({ | |||
| type: SET_SORT_OPTION, | |||
| payload, | |||
| @@ -1,6 +1,7 @@ | |||
| import { | |||
| CLEAR_FILTERS, | |||
| SET_CATEGORY, | |||
| SET_COMPANY, | |||
| SET_FILTERS, | |||
| SET_HEADER_STRING, | |||
| SET_IS_APPLIED, | |||
| @@ -17,6 +18,7 @@ const initialState = { | |||
| category: null, | |||
| subcategory: null, | |||
| locations: [], | |||
| company: [], | |||
| sortOption: null, | |||
| isApplied: false, | |||
| queryString: "", | |||
| @@ -24,6 +26,7 @@ const initialState = { | |||
| categoryString: "", | |||
| subcategoryString: "", | |||
| locationsString: "", | |||
| companyString: "", | |||
| text: "", | |||
| }, | |||
| searchString: "", | |||
| @@ -38,6 +41,7 @@ export default createReducer( | |||
| [SET_CATEGORY]: setFilteredCategory, | |||
| [SET_SUBCATEGORY]: setFilteredSubcategory, | |||
| [SET_LOCATIONS]: setFilteredLocations, | |||
| [SET_COMPANY]: setFilteredCompany, | |||
| [SET_SORT_OPTION]: setFilteredSortOption, | |||
| [SET_IS_APPLIED]: setIsAppliedStatus, | |||
| [SET_HEADER_STRING]: setHeaderString, | |||
| @@ -97,6 +101,15 @@ function setFilteredLocations(state, { payload }) { | |||
| }, | |||
| }; | |||
| } | |||
| function setFilteredCompany(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| filters: { | |||
| ...state.filters, | |||
| company: payload, | |||
| }, | |||
| }; | |||
| } | |||
| function setFilteredSortOption(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| @@ -18,6 +18,10 @@ export const selectSelectedLocations = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.locations | |||
| ); | |||
| export const selectSelectedCompany = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.company | |||
| ); | |||
| export const selectSelectedSortOption = createSelector( | |||
| filtersSelector, | |||
| (state) => state.filters.sortOption | |||
| @@ -0,0 +1,5 @@ | |||
| export const filterCompanies = (data, regexp) => { | |||
| return data.filter((company) => { | |||
| return regexp.test(company?.company?.name); | |||
| }); | |||
| }; | |||