| subcategory={props.subcategory} | subcategory={props.subcategory} | ||||
| type={props.type} | type={props.type} | ||||
| method="edit" | method="edit" | ||||
| showSecondButton | |||||
| firstOutlined={false} | |||||
| // showSecondButton | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> |
| height: 16px; | height: 16px; | ||||
| position: relative; | position: relative; | ||||
| top: -3px; | top: -3px; | ||||
| left: -1.5px; | |||||
| left: -2.5px; | |||||
| } | } | ||||
| } | } | ||||
| `; | `; |
| 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; |
| 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; | |||||
| } | |||||
| `; |
| import React, { forwardRef, useEffect, useImperativeHandle, useState } from "react"; | |||||
| import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import FilterCheckboxDropdown from "../../FilterDropdown/Checkbox/FilterCheckboxDropdown"; | import FilterCheckboxDropdown from "../../FilterDropdown/Checkbox/FilterCheckboxDropdown"; | ||||
| import { LocationIcon } from "./LocationChoser.styled"; | import { LocationIcon } from "./LocationChoser.styled"; | ||||
| const [isOpened, setIsOpened] = useState(false); | const [isOpened, setIsOpened] = useState(false); | ||||
| const filters = props.filters; | const filters = props.filters; | ||||
| const allLocations = useMemo(() => filters.locations.allLocations || [], [filters.locations]) | |||||
| console.log("allLocations", allLocations); | |||||
| useImperativeHandle(ref, () => ({ | useImperativeHandle(ref, () => ({ | ||||
| closeSection: () => { | closeSection: () => { | ||||
| setIsOpened(false); | setIsOpened(false); | ||||
| return ( | return ( | ||||
| <FilterCheckboxDropdown | <FilterCheckboxDropdown | ||||
| searchPlaceholder={t("filters.location.placeholder")} | searchPlaceholder={t("filters.location.placeholder")} | ||||
| data={[...filters.locations.allLocations]} | |||||
| data={[...allLocations]} | |||||
| filters={[...filters.locations.selectedLocationsLocally]} | filters={[...filters.locations.selectedLocationsLocally]} | ||||
| open={isOpened} | open={isOpened} | ||||
| handleOpen={() => setIsOpened((prevIsOpened) => !prevIsOpened)} | handleOpen={() => setIsOpened((prevIsOpened) => !prevIsOpened)} |
| import CategoryChoser from "./Choser/CategoryChoser/CategoryChoser"; | import CategoryChoser from "./Choser/CategoryChoser/CategoryChoser"; | ||||
| import SubcategoryChoser from "./Choser/SubcategoryChoser/SubcategoryChoser"; | import SubcategoryChoser from "./Choser/SubcategoryChoser/SubcategoryChoser"; | ||||
| import LocationChoser from "./Choser/LocationChoser/LocationChoser"; | import LocationChoser from "./Choser/LocationChoser/LocationChoser"; | ||||
| import CompanyChoser from "./Choser/CompanyChoser/CompanyChoser"; | |||||
| import SkeletonFilterCard from "./Skeleton/SkeletonFilterCard"; | import SkeletonFilterCard from "./Skeleton/SkeletonFilterCard"; | ||||
| const FilterCard = (props) => { | const FilterCard = (props) => { | ||||
| const categoryRef = useRef(null); | const categoryRef = useRef(null); | ||||
| const subcategoryRef = useRef(null); | const subcategoryRef = useRef(null); | ||||
| const locationRef = useRef(null); | const locationRef = useRef(null); | ||||
| const companyRef = useRef(null); | |||||
| const closeAllSections = () => { | const closeAllSections = () => { | ||||
| categoryRef.current.closeSection(); | categoryRef.current.closeSection(); | ||||
| subcategoryRef.current.closeSection(); | subcategoryRef.current.closeSection(); | ||||
| locationRef.current.closeSection(); | locationRef.current.closeSection(); | ||||
| companyRef.current.closeSection(); | |||||
| }; | }; | ||||
| console.log(offers); | |||||
| return ( | return ( | ||||
| <FilterCardContainer | <FilterCardContainer | ||||
| filtersOpened={props.filtersOpened} | filtersOpened={props.filtersOpened} | ||||
| {!props.myOffers && ( | {!props.myOffers && ( | ||||
| <LocationChoser filters={filters} ref={locationRef} /> | <LocationChoser filters={filters} ref={locationRef} /> | ||||
| )} | )} | ||||
| <CompanyChoser filters={filters} ref={companyRef} /> | |||||
| </ContentContainer> | </ContentContainer> | ||||
| <FilterFooter | <FilterFooter |
| const Checkbox = (props) => { | const Checkbox = (props) => { | ||||
| const item = props.item; | const item = props.item; | ||||
| return ( | return ( | ||||
| <CheckboxButton | <CheckboxButton | ||||
| leftText={item.city} | |||||
| leftText={props.companies ? item.company.name : item.city} | |||||
| // rightText={item.offerCount} | // rightText={item.offerCount} | ||||
| value={item} | value={item} | ||||
| checked={ | 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 | ? true | ||||
| : false | : false | ||||
| item: PropTypes.any, | item: PropTypes.any, | ||||
| filters: PropTypes.any, | filters: PropTypes.any, | ||||
| onChange: PropTypes.func, | onChange: PropTypes.func, | ||||
| companies: PropTypes.bool, | |||||
| }; | }; | ||||
| export default Checkbox; | export default Checkbox; |
| : selectedTheme.colors.primaryText | : selectedTheme.colors.primaryText | ||||
| } | } | ||||
| dropdownIcon={ | dropdownIcon={ | ||||
| <NumberedIcon number={props.filters.length}> | |||||
| {props.icon} | |||||
| </NumberedIcon> | |||||
| <NumberedIcon number={props.filters.length}>{props.icon}</NumberedIcon> | |||||
| } | } | ||||
| toggleIconClosed={<DropdownDown />} | toggleIconClosed={<DropdownDown />} | ||||
| toggleIconOpened={<DropdownUp />} | toggleIconOpened={<DropdownUp />} | ||||
| <React.Fragment> | <React.Fragment> | ||||
| <SelectedItemsContainer> | <SelectedItemsContainer> | ||||
| {props.filters.map((item) => ( | {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 /> | <CloseIcon /> | ||||
| </SelectedItem> | </SelectedItem> | ||||
| ))} | ))} | ||||
| setIsOpened: PropTypes.func, | setIsOpened: PropTypes.func, | ||||
| open: PropTypes.bool, | open: PropTypes.bool, | ||||
| handleOpen: PropTypes.func, | handleOpen: PropTypes.func, | ||||
| companies: PropTypes.bool, | |||||
| }; | }; | ||||
| export default CheckboxDropdownList; | export default CheckboxDropdownList; |
| if (toSearch.length > 0) { | if (toSearch.length > 0) { | ||||
| setDataToShow( | setDataToShow( | ||||
| data.filter((item) => | 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 { | } else { | ||||
| open={props?.open !== undefined ? props.open : isOpened} | open={props?.open !== undefined ? props.open : isOpened} | ||||
| handleOpen={handleOpen} | handleOpen={handleOpen} | ||||
| setItemsSelected={props.setItemsSelected} | setItemsSelected={props.setItemsSelected} | ||||
| companies={props.companies} | |||||
| > | > | ||||
| {dataToShow.map((item) => { | {dataToShow.map((item) => { | ||||
| return ( | return ( | ||||
| item={item} | item={item} | ||||
| filters={props.filters} | filters={props.filters} | ||||
| onChange={() => handleChange(item)} | onChange={() => handleChange(item)} | ||||
| companies={props.companies} | |||||
| /> | /> | ||||
| </DropdownItem> | </DropdownItem> | ||||
| ); | ); | ||||
| filters: PropTypes.array, | filters: PropTypes.array, | ||||
| open: PropTypes.bool, | open: PropTypes.bool, | ||||
| handleOpen: PropTypes.func, | handleOpen: PropTypes.func, | ||||
| companies: PropTypes.bool, | |||||
| }; | }; | ||||
| FilterCheckboxDropdown.defaultProps = { | FilterCheckboxDropdown.defaultProps = { | ||||
| oneValueAllowed: false, | oneValueAllowed: false, |
| 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; |
| 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")}; | |||||
| `; |
| 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; |
| 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"}; | |||||
| `; |
| export const CancelButtonContainer = styled(PrimaryButton)` | export const CancelButtonContainer = styled(PrimaryButton)` | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 140px; | |||||
| width: 147px; | |||||
| height: 45px; | height: 45px; | ||||
| } | } | ||||
| `; | `; |
| OfferImage, | OfferImage, | ||||
| RemoveIconContainer, | RemoveIconContainer, | ||||
| RemoveIcon, | RemoveIcon, | ||||
| PinIcon, | |||||
| } from "./DeleteOffer.styled"; | } from "./DeleteOffer.styled"; | ||||
| import BackdropComponent from "../../../MUI/BackdropComponent"; | import BackdropComponent from "../../../MUI/BackdropComponent"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| categoryName={props.offer.category.name} | categoryName={props.offer.category.name} | ||||
| /> | /> | ||||
| <RemoveIconContainer> | <RemoveIconContainer> | ||||
| <RemoveIcon /> | |||||
| {props.pin ? <PinIcon /> : <RemoveIcon />} | |||||
| </RemoveIconContainer> | </RemoveIconContainer> | ||||
| </OfferInfo> | </OfferInfo> | ||||
| <DeleteQuestion> | <DeleteQuestion> |
| import { Box } from "@mui/system"; | import { Box } from "@mui/system"; | ||||
| import styled from "styled-components"; | import styled from "styled-components"; | ||||
| import { ReactComponent as Remove } from "../../../../assets/images/svg/trash-gold.svg"; | import { ReactComponent as Remove } from "../../../../assets/images/svg/trash-gold.svg"; | ||||
| import { ReactComponent as Pin } from "../../../../assets/images/svg/pin-outlined.svg"; | |||||
| import selectedTheme from "../../../../themes"; | import selectedTheme from "../../../../themes"; | ||||
| import { Icon } from "../../../Icon/Icon"; | import { Icon } from "../../../Icon/Icon"; | ||||
| align-items: center; | align-items: center; | ||||
| padding: 18px; | padding: 18px; | ||||
| margin-top: 36px; | margin-top: 36px; | ||||
| gap: 9px !important; | |||||
| background-color: ${selectedTheme.colors.chatHeaderColor}; | |||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| margin-left: calc(50% - 105px) !important; | margin-left: calc(50% - 105px) !important; | ||||
| export const OfferImageContainer = styled(Box)` | export const OfferImageContainer = styled(Box)` | ||||
| width: 54px; | width: 54px; | ||||
| min-width: 54px; | |||||
| height: 54px; | height: 54px; | ||||
| min-height: 54px; | |||||
| border-radius: 2px; | border-radius: 2px; | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| font-size: 14px; | font-size: 14px; | ||||
| margin: 27px 0; | |||||
| display: block; | |||||
| margin: 27px auto; | |||||
| text-align: center; | text-align: center; | ||||
| width: 100%; | |||||
| width: 220px; | |||||
| } | } | ||||
| `; | `; | ||||
| export const RemoveIconContainer = styled(RemoveIconBorder)` | export const RemoveIconContainer = styled(RemoveIconBorder)` | ||||
| cursor: default; | cursor: default; | ||||
| & span { | |||||
| position: relative; | |||||
| top: 4px; | |||||
| } | |||||
| `; | `; | ||||
| export const RemoveIcon = styled(Remove)` | export const RemoveIcon = styled(Remove)` | ||||
| cursor: default; | cursor: default; | ||||
| position: relative; | position: relative; | ||||
| top: 7px; | |||||
| top: 2px; | |||||
| `; | |||||
| export const PinIcon = styled(Pin)` | |||||
| cursor: default; | |||||
| position: relative; | |||||
| top: 3px; | |||||
| & g path { | |||||
| stroke: ${selectedTheme.colors.iconYellowColor}; | |||||
| } | |||||
| `; | `; | ||||
| export const ButtonsContainer = styled(Box)` | export const ButtonsContainer = styled(Box)` |
| display: flex; | display: flex; | ||||
| flex-direction: column; | flex-direction: column; | ||||
| margin-left: 9px; | margin-left: 9px; | ||||
| gap: 0 !important; | |||||
| `; | `; | ||||
| export const OfferDescriptionTitle = styled(Typography)` | export const OfferDescriptionTitle = styled(Typography)` | ||||
| font-size: 16px; | font-size: 16px; | ||||
| font-weight: 600; | font-weight: 600; | ||||
| color: ${selectedTheme.colors.primaryPurple}; | color: ${selectedTheme.colors.primaryPurple}; | ||||
| font-family: ${selectedTheme.fonts.textFont}; | |||||
| overflow: hidden; | |||||
| line-height: 19px; | |||||
| display: -webkit-box; | |||||
| -webkit-line-clamp: 2; | |||||
| -webkit-box-orient: vertical; | |||||
| text-overflow: ellipsis; | |||||
| max-height: 38px; | |||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| font-size: 14px; | font-size: 14px; | ||||
| export const OfferDescriptionCategory = styled(Typography)` | export const OfferDescriptionCategory = styled(Typography)` | ||||
| font-size: 12px; | font-size: 12px; | ||||
| letter-spacing: 2%; | letter-spacing: 2%; | ||||
| font-family: ${selectedTheme.fonts.textFont}; | |||||
| color: ${selectedTheme.colors.primaryDarkText}; | |||||
| `; | `; | ||||
| export const CategoryIconContainer = styled(Icon)` | export const CategoryIconContainer = styled(Icon)` | ||||
| margin-right: 4px; | margin-right: 4px; | ||||
| position: relative; | |||||
| top: 2px; | |||||
| & svg { | & svg { | ||||
| width: 14px; | width: 14px; | ||||
| position: relative; | position: relative; | ||||
| top: -1px; | |||||
| top: -6px; | |||||
| } | } | ||||
| `; | `; | ||||
| export const CategoryIcon = styled(Category)` | |||||
| ` | |||||
| export const CategoryIcon = styled(Category)``; |
| export const SaveButtonContainer = styled(PrimaryButton)` | export const SaveButtonContainer = styled(PrimaryButton)` | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 140px; | |||||
| width: 147px; | |||||
| height: 45px; | height: 45px; | ||||
| } | } | ||||
| `; | `; |
| right: 18px; | right: 18px; | ||||
| display: flex; | display: flex; | ||||
| flex-direction: row; | flex-direction: row; | ||||
| gap: 12px; | |||||
| gap: 18px; | |||||
| @media (max-width: 600px) { | |||||
| gap: 12px; | |||||
| } | |||||
| `; | `; | ||||
| export const MessageButton = styled(IconButton)` | export const MessageButton = styled(IconButton)` | ||||
| width: 180px; | width: 180px; | ||||
| height: 48px; | height: 48px; | ||||
| position: absolute; | position: absolute; | ||||
| bottom: 25px; | |||||
| bottom: 11px; | |||||
| right: 9px; | right: 9px; | ||||
| display: ${(props) => (props.halfwidth ? `none` : `block`)}; | display: ${(props) => (props.halfwidth ? `none` : `block`)}; | ||||
| & button:hover { | & button:hover { |
| <SkeletonProfileCard /> | <SkeletonProfileCard /> | ||||
| ) : ( | ) : ( | ||||
| <> | <> | ||||
| <ProfileCardContainer> | |||||
| <ProfileCardContainer isAdmin={props.isAdmin}> | |||||
| <ProfileCardHeader> | <ProfileCardHeader> | ||||
| <PersonOutlineIcon color="action" sx={{ mr: 0.9 }} /> | <PersonOutlineIcon color="action" sx={{ mr: 0.9 }} /> | ||||
| <HeaderTitle> | <HeaderTitle> |
| padding: 0 36px 0 0; | padding: 0 36px 0 0; | ||||
| } | } | ||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| padding: 0 18px; | |||||
| padding: 0 ${props => props.isAdmin ? "18px" : "0"}; | |||||
| } | } | ||||
| `; | `; | ||||
| export const EditIcon = styled(Edit)` | export const EditIcon = styled(Edit)` |
| export const ProfileContactContainer = styled(Grid)` | export const ProfileContactContainer = styled(Grid)` | ||||
| padding-top: ${(props) => (props.isAdmin ? `20px` : `2rem`)}; | padding-top: ${(props) => (props.isAdmin ? `20px` : `2rem`)}; | ||||
| padding-bottom: 2rem; | |||||
| padding-bottom: ${(props) => (props.isAdmin ? "0" : "2rem")}; | |||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| padding-bottom: 1rem; | padding-bottom: 1rem; | ||||
| padding-top: 88px; | padding-top: 88px; |
| return ( | return ( | ||||
| <> | <> | ||||
| <UserReviewsSingleCard review={review} handleRemove={handleRemove} /> | |||||
| <UserReviewsSingleCard | |||||
| review={review} | |||||
| showRemoveIcon={props.showRemoveIcon} | |||||
| handleRemove={handleRemove} | |||||
| /> | |||||
| {removeModalOpened && ( | {removeModalOpened && ( | ||||
| <DeleteReview | <DeleteReview | ||||
| review={review} | review={review} | ||||
| className: PropTypes.string, | className: PropTypes.string, | ||||
| review: PropTypes.any, | review: PropTypes.any, | ||||
| givingReview: PropTypes.bool, | givingReview: PropTypes.bool, | ||||
| showRemoveIcon: PropTypes.bool, | |||||
| }; | }; | ||||
| UserReviewsCard.defaultProps = { | UserReviewsCard.defaultProps = { | ||||
| isProfileReviews: false, | isProfileReviews: false, |
| ReviewOfferTitle, | ReviewOfferTitle, | ||||
| } from "./ReviewOffer.styled"; | } from "./ReviewOffer.styled"; | ||||
| import { getImageUrl, variants } from "../../../../../util/helpers/imageUrlGetter"; | import { getImageUrl, variants } from "../../../../../util/helpers/imageUrlGetter"; | ||||
| import { useTranslation } from "react-i18next"; | |||||
| const ReviewOffer = (props) => { | const ReviewOffer = (props) => { | ||||
| const {t} = useTranslation(); | |||||
| return ( | return ( | ||||
| <ReviewOfferContainer> | <ReviewOfferContainer> | ||||
| <ReviewOfferImage src={getImageUrl(props.image, variants.reviewCard)} /> | <ReviewOfferImage src={getImageUrl(props.image, variants.reviewCard)} /> | ||||
| <ReviewOfferDetails> | <ReviewOfferDetails> | ||||
| <ReviewOfferDescription>Proizvod: </ReviewOfferDescription> | |||||
| <ReviewOfferDescription>{t("reviews.offerTitle")}</ReviewOfferDescription> | |||||
| <ReviewOfferTitle>{props.name}</ReviewOfferTitle> | <ReviewOfferTitle>{props.name}</ReviewOfferTitle> | ||||
| </ReviewOfferDetails> | </ReviewOfferDetails> | ||||
| </ReviewOfferContainer> | </ReviewOfferContainer> |
| font-size: 16px; | font-size: 16px; | ||||
| font-weight: 600; | font-weight: 600; | ||||
| font-family: ${selectedTheme.fonts.textFont}; | font-family: ${selectedTheme.fonts.textFont}; | ||||
| overflow: hidden; | |||||
| line-height: 19px; | |||||
| display: -webkit-box; | |||||
| -webkit-line-clamp: 1; | |||||
| -webkit-box-orient: vertical; | |||||
| text-overflow: ellipsis; | |||||
| max-height: 19px; | |||||
| @media (max-width: 600px) { | |||||
| font-size: 12px; | |||||
| line-height: 16px; | |||||
| max-height: 16px; | |||||
| } | |||||
| `; | `; |
| isSuccessfulSwap={props.review?.isSuccessfulSwap} | isSuccessfulSwap={props.review?.isSuccessfulSwap} | ||||
| isGoodCommunication={props.review?.isGoodCommunication} | isGoodCommunication={props.review?.isGoodCommunication} | ||||
| /> | /> | ||||
| {!props.showRemoveIcon && <RemoveButton review={props.review} onClick={handleRemove} />} | |||||
| {props.showRemoveIcon && ( | |||||
| <RemoveButton review={props.review} onClick={handleRemove} /> | |||||
| )} | |||||
| <ReviewOffer | <ReviewOffer | ||||
| name={props.review?.offerName} | name={props.review?.offerName} | ||||
| image={props.review?.offerImage} | image={props.review?.offerImage} |
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| margin-left: 0; | margin-left: 0; | ||||
| margin-top: 310px; | |||||
| margin-top: 345px; | |||||
| svg { | svg { | ||||
| width: 14px; | width: 14px; |
| position: relative; | position: relative; | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 92%; | |||||
| width: calc(100vw - 36px); | |||||
| } | } | ||||
| `; | `; | ||||
| export const HeaderTop = styled(Box)` | export const HeaderTop = styled(Box)` |
| import React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import { ButtonContainer, DeleteButtonContainer } from "./DeleteButton.styled"; | |||||
| import selectedTheme from "../../../../themes"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| const DeleteButton = (props) => { | |||||
| const {t} = useTranslation(); | |||||
| return ( | |||||
| <DeleteButtonContainer> | |||||
| <ButtonContainer | |||||
| variant="contained" | |||||
| buttoncolor={selectedTheme.colors.primaryPurple} | |||||
| onClick={props.onClick} | |||||
| textcolor={selectedTheme.colors.primaryTextDisabled} | |||||
| > | |||||
| {t("admin.review.confirm")} | |||||
| </ButtonContainer> | |||||
| </DeleteButtonContainer> | |||||
| ); | |||||
| }; | |||||
| DeleteButton.propTypes = { | |||||
| onClick: PropTypes.func, | |||||
| }; | |||||
| export default DeleteButton; |
| import { Box } from "@mui/material"; | |||||
| import styled from "styled-components"; | |||||
| import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton"; | |||||
| export const DeleteButtonContainer = styled(Box)` | |||||
| position: absolute; | |||||
| bottom: 36px; | |||||
| left: 18px; | |||||
| background-color: white !important; | |||||
| border: 0 !important; | |||||
| padding: 0 !important; | |||||
| `; | |||||
| export const ButtonContainer = styled(PrimaryButton)` | |||||
| height: 44px; | |||||
| width: calc(100vw - 36px); | |||||
| background-color: white !important; | |||||
| & > button { | |||||
| background-color: ${(props) => props.buttoncolor} !important; | |||||
| } | |||||
| `; |
| import BackdropComponent from "../../MUI/BackdropComponent"; | import BackdropComponent from "../../MUI/BackdropComponent"; | ||||
| import UserReviewsSingleCard from "../../Cards/UserReviewsCard/UserReviewsSingleCard/UserReviewsSingleCard"; | import UserReviewsSingleCard from "../../Cards/UserReviewsCard/UserReviewsSingleCard/UserReviewsSingleCard"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import DeleteButton from "./DeleteButton/DeleteButton"; | |||||
| const DeleteReview = (props) => { | const DeleteReview = (props) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| deleteModal | deleteModal | ||||
| review={props.review} | review={props.review} | ||||
| /> | /> | ||||
| <XIcon /> | |||||
| <XIcon onClick={() => props.setOpenedDeleteModal(false)} /> | |||||
| <DeleteButton /> | |||||
| </DeleteReviewContainer> | </DeleteReviewContainer> | ||||
| </> | </> | ||||
| ); | ); |
| const title = useMemo(() => { | const title = useMemo(() => { | ||||
| return t(`admin.${props.type}.${props.method}.title`); | return t(`admin.${props.type}.${props.method}.title`); | ||||
| }, [props.type, props.method]); | }, [props.type, props.method]); | ||||
| const placeholder = useMemo(() => { | const placeholder = useMemo(() => { | ||||
| return t(`admin.${props.type}.${props.method}.placeholder`); | return t(`admin.${props.type}.${props.method}.placeholder`); | ||||
| }, [props.type, props.method]); | }, [props.type, props.method]); | ||||
| const fieldLabel = useMemo(() => { | const fieldLabel = useMemo(() => { | ||||
| return t(`admin.${props.type}.${props.method}.fieldTitle`); | return t(`admin.${props.type}.${props.method}.fieldTitle`); | ||||
| }, [props.type, props.method]); | }, [props.type, props.method]); | ||||
| const firstButtonText = useMemo(() => { | const firstButtonText = useMemo(() => { | ||||
| return t(`admin.${props.type}.${props.method}.next`); | return t(`admin.${props.type}.${props.method}.next`); | ||||
| }, [props.type, props.method]); | }, [props.type, props.method]); | ||||
| const formik = useFormik({ | const formik = useFormik({ | ||||
| initialValues: { | initialValues: { | ||||
| image: "", | image: "", | ||||
| title: props?.category?.name || "", | |||||
| title: props?.category?.name || props?.category?.city || "", | |||||
| }, | }, | ||||
| onSubmit: handleSubmit, | onSubmit: handleSubmit, | ||||
| }); | }); |
| `; | `; | ||||
| export const SaveButton = styled(PrimaryButton)` | export const SaveButton = styled(PrimaryButton)` | ||||
| max-width: 376px; | max-width: 376px; | ||||
| width: ${(props) => (props.showSecondButton ? "180px" : "376px")}; | |||||
| height: 48px; | height: 48px; | ||||
| & button { | & button { | ||||
| letter-spacing: 1.5px; | letter-spacing: 1.5px; |
| onClick={handleBackButton} | onClick={handleBackButton} | ||||
| component="header" | component="header" | ||||
| className={props.className} | className={props.className} | ||||
| isAdmin={props.isAdmin} | |||||
| > | > | ||||
| <ButtonContainer> | <ButtonContainer> | ||||
| <ArrowButton side={"left"}></ArrowButton> | <ArrowButton side={"left"}></ArrowButton> |
| margin-top: 20px; | margin-top: 20px; | ||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| margin-top: 40px; | |||||
| margin-left: 18px; | |||||
| margin-top: 49px; | |||||
| margin-left: ${props => props.isAdmin ? "18px" : "0"}; | |||||
| } | } | ||||
| `; | `; | ||||
| export const ButtonContainer = styled(Link)` | export const ButtonContainer = styled(Link)` |
| }; | }; | ||||
| return ( | return ( | ||||
| <ProfileOffersContainer> | |||||
| <ProfileOffersContainer isAdmin={props.isAdmin}> | |||||
| {isLoadingMineOffers || isLoadingMineOffers === undefined ? ( | {isLoadingMineOffers || isLoadingMineOffers === undefined ? ( | ||||
| <ProfileOffersHeaderSkeleton /> | <ProfileOffersHeaderSkeleton /> | ||||
| ) : ( | ) : ( |
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| padding: 0; | padding: 0; | ||||
| width: calc(100vw - 36px); | width: calc(100vw - 36px); | ||||
| margin: 34px 18px; | |||||
| margin: 34px ${props => props.isAdmin ? "18px" : "0"}; | |||||
| margin-bottom: ${props => !props.isAdmin && '0'} | |||||
| } | } | ||||
| `; | `; | ||||
| export const OffersContainer = styled(Box)` | export const OffersContainer = styled(Box)` |
| margin-top: 60px; | margin-top: 60px; | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 100%; | |||||
| width: calc(100vw - 18px); | |||||
| position: absolute; | position: absolute; | ||||
| top: 25px; | top: 25px; | ||||
| left: 18px; | |||||
| } | } | ||||
| `; | `; | ||||
| export const ProfileHeaderIconContainer = styled(Box)` | export const ProfileHeaderIconContainer = styled(Box)` | ||||
| border: 1px solid ${selectedTheme.colors.primaryPurple}; | border: 1px solid ${selectedTheme.colors.primaryPurple}; | ||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| width: 92%; | |||||
| width: calc(100vw - 36px); | |||||
| } | } | ||||
| `; | `; |
| position: relative; | position: relative; | ||||
| left: 2px; | left: 2px; | ||||
| width: 332px; | width: 332px; | ||||
| gap: 0 !important; | |||||
| ${(props) => props.current === 3 && `margin-bottom: 30px;`} | ${(props) => props.current === 3 && `margin-bottom: 30px;`} | ||||
| @media screen and (min-width: 468px) and (max-width: 600px) { | @media screen and (min-width: 468px) and (max-width: 600px) { | ||||
| width: 80%; | width: 80%; | ||||
| gap: 0 !important; | |||||
| } | } | ||||
| @media (max-width: 600px) { | @media (max-width: 600px) { |
| <SkeletonUserReviews /> | <SkeletonUserReviews /> | ||||
| ) : ( | ) : ( | ||||
| <ReviewsBox | <ReviewsBox | ||||
| isAdmin={props.isAdmin} | |||||
| profile={props.isProfileReviews} | profile={props.isProfileReviews} | ||||
| numOfReviews={lastThreeReviews?.length} | numOfReviews={lastThreeReviews?.length} | ||||
| > | > | ||||
| {lastThreeReviews?.length > 0 ? ( | {lastThreeReviews?.length > 0 ? ( | ||||
| lastThreeReviews?.map((review, index) => ( | lastThreeReviews?.map((review, index) => ( | ||||
| <UserReviewsCard | <UserReviewsCard | ||||
| showRemoveIcon={props.isAdmin} | |||||
| review={review} | review={review} | ||||
| key={index} | key={index} | ||||
| hasGivenReview={sortRef.current?.hasGivenReview} | hasGivenReview={sortRef.current?.hasGivenReview} |
| ? "450px" | ? "450px" | ||||
| : "350px"}; | : "350px"}; | ||||
| padding: 0; | padding: 0; | ||||
| margin: 0 18px; | |||||
| margin: 0 ${props => props.isAdmin ? "18px" : "0"}; | |||||
| margin-top: 60px; | margin-top: 60px; | ||||
| } | } | ||||
| `; | `; |
| export const REGEXP_FIRST = /^[a-hA-H]/; | |||||
| export const REGEXP_SECOND = /^[i-qI-Q]/; | |||||
| export const REGEXP_THIRD = /^[r-zR-Z]/; |
| import { useEffect, useMemo, 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 selectedCompaniesRedux = useSelector(selectSelectedCompany); | |||||
| const dispatch = useDispatch(); | |||||
| const allCompaniesRedux = useSelector(selectAllProfiles); | |||||
| const [selectedCompaniesLocally, setSelectedCompaniesLocally] = useState([]); | |||||
| useEffect(() => { | |||||
| dispatch(fetchAllProfiles()); | |||||
| }, []); | |||||
| const selectedCompanies = useMemo(() => Array.isArray(selectedCompaniesRedux) ? selectedCompaniesRedux : []) | |||||
| const allCompanies = useMemo(() => Array.isArray(allCompaniesRedux) ? selectedCompaniesRedux : []) | |||||
| 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; |
| import { useEffect, useMemo } from "react"; | import { useEffect, useMemo } from "react"; | ||||
| import useCategoryFilter from "./useCategoryFilter"; | import useCategoryFilter from "./useCategoryFilter"; | ||||
| import useCompaniesFilter from "./useCompanyFilter"; | |||||
| import useLocationsFilter from "./useLocationsFilter"; | import useLocationsFilter from "./useLocationsFilter"; | ||||
| import useSubcategoryFilter from "./useSubcategoryFilter"; | import useSubcategoryFilter from "./useSubcategoryFilter"; | ||||
| const category = useCategoryFilter(); | const category = useCategoryFilter(); | ||||
| const subcategory = useSubcategoryFilter(); | const subcategory = useSubcategoryFilter(); | ||||
| const locations = useLocationsFilter(); | const locations = useLocationsFilter(); | ||||
| const companies = useCompaniesFilter(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (clearAll) { | if (clearAll) { | ||||
| category.selectedCategoryLocally, | category.selectedCategoryLocally, | ||||
| subcategory.selectedSubcategoryLocally, | subcategory.selectedSubcategoryLocally, | ||||
| locations.selectedLocationsLocally, | locations.selectedLocationsLocally, | ||||
| companies.selectedCompaniesLocally, | |||||
| ]); | ]); | ||||
| const apply = (immediatelyApply = false, applyAllFilters) => { | const apply = (immediatelyApply = false, applyAllFilters) => { | ||||
| category.apply(); | category.apply(); | ||||
| subcategory.apply(); | subcategory.apply(); | ||||
| locations.apply(); | locations.apply(); | ||||
| companies.apply(); | |||||
| if (immediatelyApply) applyAllFilters(); | if (immediatelyApply) applyAllFilters(); | ||||
| }; | }; | ||||
| category.clear(); | category.clear(); | ||||
| subcategory.clear(); | subcategory.clear(); | ||||
| locations.clear(); | locations.clear(); | ||||
| companies.clear(); | |||||
| }; | }; | ||||
| return { | return { | ||||
| category, | category, | ||||
| subcategory, | subcategory, | ||||
| locations, | locations, | ||||
| companies, | |||||
| numOfFiltersChosen, | numOfFiltersChosen, | ||||
| apply, | apply, | ||||
| clear, | clear, |
| locations.forEach((locationName) => { | locations.forEach((locationName) => { | ||||
| locationsToPush.push(allLocations.find((p) => p.city === locationName)); | locationsToPush.push(allLocations.find((p) => p.city === locationName)); | ||||
| }); | }); | ||||
| setSelectedLocations([...locationsToPush]) | |||||
| setSelectedLocations([...locationsToPush]); | |||||
| }; | }; | ||||
| const apply = () => { | const apply = () => { |
| labelPassword: "Lozinka", | labelPassword: "Lozinka", | ||||
| labelFirm: "Ime Firme", | labelFirm: "Ime Firme", | ||||
| labelPIB: "PIB", | labelPIB: "PIB", | ||||
| labelPhone: "Telefon", | |||||
| labelPhone: "Telefon (opciono)", | |||||
| labelPhoneNumber: "Broj telefona", | labelPhoneNumber: "Broj telefona", | ||||
| labelLocation: "Lokacija", | |||||
| labelWebsite: "Adresa Websajta", | |||||
| labelLocation: "Lokacija (opciono)", | |||||
| labelWebsite: "Adresa Websajta (opciono)", | |||||
| logout: "Odjavi se", | logout: "Odjavi se", | ||||
| next: "Sledeće", | next: "Sledeće", | ||||
| nextPage: "Sledeća strana", | nextPage: "Sledeća strana", | ||||
| title: "Lokacija", | title: "Lokacija", | ||||
| placeholder: "Pretraži gradove...", | placeholder: "Pretraži gradove...", | ||||
| }, | }, | ||||
| company: { | |||||
| title: "Kompanija", | |||||
| placeholder: "Pretraži kompanije...", | |||||
| firstSort: "A-H", | |||||
| secondSort: "I-Q", | |||||
| thirdSort: "R-Z", | |||||
| }, | |||||
| }, | }, | ||||
| offer: { | offer: { | ||||
| title: "NASLOV", | title: "NASLOV", | ||||
| finishedReviewTitle: "Hvala vam", | finishedReviewTitle: "Hvala vam", | ||||
| finishedReviewAltTitle: "na izdvojenom vremenu i datoj oceni!", | finishedReviewAltTitle: "na izdvojenom vremenu i datoj oceni!", | ||||
| sortBy: "Sortiraj po", | sortBy: "Sortiraj po", | ||||
| offerTitle: "Proizvod:" | |||||
| }, | }, | ||||
| messages: { | messages: { | ||||
| headerTitle: "Moje Ćaskanje", | headerTitle: "Moje Ćaskanje", | ||||
| fieldTitle: "Naslov", | fieldTitle: "Naslov", | ||||
| placeholder: "Naziv kategorije...", | placeholder: "Naziv kategorije...", | ||||
| save: "Izmeni", | save: "Izmeni", | ||||
| next: "Sledeća", | |||||
| next: "Izmeni", | |||||
| }, | }, | ||||
| add: { | add: { | ||||
| title: "Nova Kategorija", | title: "Nova Kategorija", | ||||
| fieldTitle: "Naslov", | fieldTitle: "Naslov", | ||||
| placeholder: "Naziv podkategorije...", | placeholder: "Naziv podkategorije...", | ||||
| save: "Izmeni", | save: "Izmeni", | ||||
| next: "Sledeća" | |||||
| next: "Sledeća", | |||||
| }, | }, | ||||
| add: { | add: { | ||||
| title: "Nova Podkategorija", | title: "Nova Podkategorija", | ||||
| noOfCompanies: "Broj firmi u gradu: ", | noOfCompanies: "Broj firmi u gradu: ", | ||||
| placeholder: "Pretražite lokacije...", | placeholder: "Pretražite lokacije...", | ||||
| addLocation: "Dodaj lokaciju", | addLocation: "Dodaj lokaciju", | ||||
| cancel: "Otkaži", | |||||
| delete: "Obriši", | |||||
| reassuranceDelete: | reassuranceDelete: | ||||
| "Da li ste sigurni da želite da obrišete odabranu lokaciju?", | "Da li ste sigurni da želite da obrišete odabranu lokaciju?", | ||||
| edit: { | edit: { | ||||
| fieldTitle: "Naslov", | fieldTitle: "Naslov", | ||||
| placeholder: "Naziv lokacije...", | placeholder: "Naziv lokacije...", | ||||
| save: "Izmeni", | save: "Izmeni", | ||||
| next: "Izmeni", | |||||
| }, | }, | ||||
| add: { | add: { | ||||
| title: "Nova Lokacija", | title: "Nova Lokacija", | ||||
| }, | }, | ||||
| review: { | review: { | ||||
| title: "Brisanje Komentara", | title: "Brisanje Komentara", | ||||
| confirm: "Obriši komentar" | |||||
| } | |||||
| confirm: "Obriši komentar", | |||||
| }, | |||||
| }, | }, | ||||
| }; | }; |
| setOpenedEditModal={setOpenedAddModal} | setOpenedEditModal={setOpenedAddModal} | ||||
| type={"categories"} | type={"categories"} | ||||
| method="add" | method="add" | ||||
| showSecondButton | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> |
| setOpenedEditModal={setOpenedAddModal} | setOpenedEditModal={setOpenedAddModal} | ||||
| type={"locations"} | type={"locations"} | ||||
| method="add" | method="add" | ||||
| showSecondButton | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> |
| setOpenedEditModal={setOpenedAddModal} | setOpenedEditModal={setOpenedAddModal} | ||||
| type="subcategories" | type="subcategories" | ||||
| method="add" | method="add" | ||||
| showSecondButton | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> |
| export const SET_CATEGORY = createSetType("FILTERS_SET_CATEGORY"); | export const SET_CATEGORY = createSetType("FILTERS_SET_CATEGORY"); | ||||
| export const SET_SUBCATEGORY = createSetType("FILTERS_SET_SUBCATEGORY"); | export const SET_SUBCATEGORY = createSetType("FILTERS_SET_SUBCATEGORY"); | ||||
| export const SET_LOCATIONS = createSetType("FILTERS_SET_LOCATIONS"); | 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_SORT_OPTION = createSetType("FILTERS_SET_SORT_OPTION"); | ||||
| export const SET_IS_APPLIED = createSetType("FILTERS_SET_IS_APPLIED"); | export const SET_IS_APPLIED = createSetType("FILTERS_SET_IS_APPLIED"); | ||||
| export const SET_QUERY_STRING = createSetType("FILTERS_SET_QUERY_STRING"); | export const SET_QUERY_STRING = createSetType("FILTERS_SET_QUERY_STRING"); |
| import { | import { | ||||
| CLEAR_FILTERS, | CLEAR_FILTERS, | ||||
| SET_CATEGORY, | SET_CATEGORY, | ||||
| SET_COMPANY, | |||||
| SET_FILTERS, | SET_FILTERS, | ||||
| SET_HEADER_STRING, | SET_HEADER_STRING, | ||||
| SET_IS_APPLIED, | SET_IS_APPLIED, | ||||
| type: SET_LOCATIONS, | type: SET_LOCATIONS, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const setFilteredCompany = (payload) => ({ | |||||
| type: SET_COMPANY, | |||||
| payload, | |||||
| }); | |||||
| export const setFilteredSortOption = (payload) => ({ | export const setFilteredSortOption = (payload) => ({ | ||||
| type: SET_SORT_OPTION, | type: SET_SORT_OPTION, | ||||
| payload, | payload, |
| import { | import { | ||||
| CLEAR_FILTERS, | CLEAR_FILTERS, | ||||
| SET_CATEGORY, | SET_CATEGORY, | ||||
| SET_COMPANY, | |||||
| SET_FILTERS, | SET_FILTERS, | ||||
| SET_HEADER_STRING, | SET_HEADER_STRING, | ||||
| SET_IS_APPLIED, | SET_IS_APPLIED, | ||||
| category: null, | category: null, | ||||
| subcategory: null, | subcategory: null, | ||||
| locations: [], | locations: [], | ||||
| company: [], | |||||
| sortOption: null, | sortOption: null, | ||||
| isApplied: false, | isApplied: false, | ||||
| queryString: "", | queryString: "", | ||||
| categoryString: "", | categoryString: "", | ||||
| subcategoryString: "", | subcategoryString: "", | ||||
| locationsString: "", | locationsString: "", | ||||
| companyString: "", | |||||
| text: "", | text: "", | ||||
| }, | }, | ||||
| searchString: "", | searchString: "", | ||||
| [SET_CATEGORY]: setFilteredCategory, | [SET_CATEGORY]: setFilteredCategory, | ||||
| [SET_SUBCATEGORY]: setFilteredSubcategory, | [SET_SUBCATEGORY]: setFilteredSubcategory, | ||||
| [SET_LOCATIONS]: setFilteredLocations, | [SET_LOCATIONS]: setFilteredLocations, | ||||
| [SET_COMPANY]: setFilteredCompany, | |||||
| [SET_SORT_OPTION]: setFilteredSortOption, | [SET_SORT_OPTION]: setFilteredSortOption, | ||||
| [SET_IS_APPLIED]: setIsAppliedStatus, | [SET_IS_APPLIED]: setIsAppliedStatus, | ||||
| [SET_HEADER_STRING]: setHeaderString, | [SET_HEADER_STRING]: setHeaderString, | ||||
| }, | }, | ||||
| }; | }; | ||||
| } | } | ||||
| function setFilteredCompany(state, { payload }) { | |||||
| return { | |||||
| ...state, | |||||
| filters: { | |||||
| ...state.filters, | |||||
| company: payload, | |||||
| }, | |||||
| }; | |||||
| } | |||||
| function setFilteredSortOption(state, { payload }) { | function setFilteredSortOption(state, { payload }) { | ||||
| return { | return { | ||||
| ...state, | ...state, |
| function* fetchLocations() { | function* fetchLocations() { | ||||
| try { | try { | ||||
| const { data } = yield call(attemptFetchLocations); | const { data } = yield call(attemptFetchLocations); | ||||
| yield put(setLocations(data)); | |||||
| yield put(setLocations(data.value)); | |||||
| yield put(fetchLocationsSuccess()); | yield put(fetchLocationsSuccess()); | ||||
| } catch (e) { | } catch (e) { | ||||
| yield put(fetchLocationsError()); | yield put(fetchLocationsError()); |
| filtersSelector, | filtersSelector, | ||||
| (state) => state.filters.locations | (state) => state.filters.locations | ||||
| ); | ); | ||||
| export const selectSelectedCompany = createSelector( | |||||
| filtersSelector, | |||||
| (state) => state.filters.company | |||||
| ); | |||||
| export const selectSelectedSortOption = createSelector( | export const selectSelectedSortOption = createSelector( | ||||
| filtersSelector, | filtersSelector, | ||||
| (state) => state.filters.sortOption | (state) => state.filters.sortOption |
| const dayCreated = | const dayCreated = | ||||
| date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); | date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); | ||||
| const monthCreated = | const monthCreated = | ||||
| date.getMonth() < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; | |||||
| date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; | |||||
| const yearCreated = date.getFullYear(); | const yearCreated = date.getFullYear(); | ||||
| const hourCreated = | const hourCreated = | ||||
| date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); | date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); | ||||
| const dayCreated = | const dayCreated = | ||||
| date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); | date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); | ||||
| const monthCreated = | const monthCreated = | ||||
| date.getMonth() < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; | |||||
| date.getMonth() < 9 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; | |||||
| const yearCreated = date.getFullYear(); | const yearCreated = date.getFullYear(); | ||||
| return `${dayCreated}.${monthCreated}.${yearCreated}.`; | return `${dayCreated}.${monthCreated}.${yearCreated}.`; | ||||
| } | } |
| export const filterCompanies = (data, regexp) => { | |||||
| return data.filter((company) => { | |||||
| return regexp.test(company?.company?.name); | |||||
| }); | |||||
| }; |