| import React, { useCallback, useRef } from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import { TextField } from "../../../TextFields/TextField/TextField"; | |||||
| import { EndIcon, SearchIcon } from "./HeadersMyOffers.styled"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| const HeadersMyOffers = (props) => { | |||||
| const searchRef = useRef(null); | |||||
| const {t} = useTranslation(); | |||||
| let listener = useCallback((event) => { | |||||
| if (event.keyCode === 13) { | |||||
| event.preventDefault(); | |||||
| handleSearch(); | |||||
| } | |||||
| }, [searchRef.current]) | |||||
| const handleFocusSearch = () => { | |||||
| searchRef.current.addEventListener("keyup", listener); | |||||
| }; | |||||
| const handleBlurSearch = () => { | |||||
| searchRef.current.removeEventListener("keyup", listener); | |||||
| }; | |||||
| const handleSearch = () => { | |||||
| props.searchMyOffers(searchRef.current.value); | |||||
| }; | |||||
| return ( | |||||
| <TextField | |||||
| fullWidth | |||||
| InputProps={{ | |||||
| endAdornment: ( | |||||
| <EndIcon size="36px"> | |||||
| <SearchIcon onClick={() => handleSearch(searchRef.current.value)} /> | |||||
| </EndIcon> | |||||
| ), | |||||
| }} | |||||
| placeholder={t("header.searchOffers")} | |||||
| onFocus={handleFocusSearch} | |||||
| onBlur={handleBlurSearch} | |||||
| ref={searchRef} | |||||
| /> | |||||
| ); | |||||
| }; | |||||
| HeadersMyOffers.propTypes = { | |||||
| children: PropTypes.node, | |||||
| searchMyOffers: PropTypes.func, | |||||
| }; | |||||
| export default HeadersMyOffers; |
| import { Box } from "@mui/material"; | |||||
| import styled from "styled-components"; | |||||
| import { Icon } from "../../../Icon/Icon"; | |||||
| import { ReactComponent as Search } from "../../../../assets/images/svg/magnifying-glass.svg"; | |||||
| import selectedTheme from "../../../../themes"; | |||||
| export const HeadersMyOffersContainer = styled(Box)``; | |||||
| export const EndIcon = styled(Icon)``; | |||||
| export const SearchIcon = styled(Search)` | |||||
| position: relative; | |||||
| top: 11px; | |||||
| left: 4px; | |||||
| cursor: pointer; | |||||
| color: ${selectedTheme.primaryPurple}; | |||||
| & path { | |||||
| width: 18px; | |||||
| height: 18px; | |||||
| } | |||||
| @media (max-width: 600px) { | |||||
| height: 14px; | |||||
| width: 14px; | |||||
| left: 11px; | |||||
| } | |||||
| `; |
| import { startChat } from "../../../util/helpers/chatHelper"; | import { startChat } from "../../../util/helpers/chatHelper"; | ||||
| import useOffers from "../../../hooks/useOffers"; | import useOffers from "../../../hooks/useOffers"; | ||||
| import OffersNotFound from "./OffersNotFound"; | import OffersNotFound from "./OffersNotFound"; | ||||
| import HeadersMyOffers from "./HeaderMyOffers.js/HeadersMyOffers"; | |||||
| const Offers = (props) => { | const Offers = (props) => { | ||||
| const chats = useSelector(selectLatestChats); | const chats = useSelector(selectLatestChats); | ||||
| startChat(chats, offer, userId); | startChat(chats, offer, userId); | ||||
| }; | }; | ||||
| console.log(offers.allOffersToShow); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| {props.myOffers && ( | |||||
| <HeadersMyOffers searchMyOffers={offers.searchMyOffers} /> | |||||
| )} | |||||
| {offers.allOffersToShow.length === 0 ? ( | {offers.allOffersToShow.length === 0 ? ( | ||||
| <OffersNotFound /> | <OffersNotFound /> | ||||
| ) : ( | ) : ( |
| <PopoverNoItemsText>{t("header.noItems")}</PopoverNoItemsText> | <PopoverNoItemsText>{t("header.noItems")}</PopoverNoItemsText> | ||||
| )} | )} | ||||
| </PopoverList> | </PopoverList> | ||||
| <PopoverButtonsContainer> | |||||
| <PopoverButtonsContainer hideButtons={props.hideButtons}> | |||||
| <PopoverButton | <PopoverButton | ||||
| sx={{ | sx={{ | ||||
| mr: 2, | mr: 2, | ||||
| secondButtonIcon: PropTypes.any, | secondButtonIcon: PropTypes.any, | ||||
| buttonOnClick: PropTypes.func, | buttonOnClick: PropTypes.func, | ||||
| secondButtonOnClick: PropTypes.func, | secondButtonOnClick: PropTypes.func, | ||||
| hideButtons: PropTypes.bool, | |||||
| }; | }; | ||||
| export default HeaderPopover; | export default HeaderPopover; |
| `; | `; | ||||
| export const PopoverButtonsContainer = styled(Box)` | export const PopoverButtonsContainer = styled(Box)` | ||||
| flex-direction: column; | flex-direction: column; | ||||
| display: flex; | |||||
| display: ${props => props.hideButtons ? 'none' : 'flex'}; | |||||
| align-items: flex-end; | align-items: flex-end; | ||||
| `; | `; | ||||
| export const PopoverNoItemsText = styled(Typography)` | export const PopoverNoItemsText = styled(Typography)` |
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| import { useHistory } from "react-router-dom"; | import { useHistory } from "react-router-dom"; | ||||
| import { CHAT_PAGE } from "../../../constants/pages"; | |||||
| import { fetchHeaderChats } from "../../../store/actions/chat/chatActions"; | import { fetchHeaderChats } from "../../../store/actions/chat/chatActions"; | ||||
| import { selectLatestChats } from "../../../store/selectors/chatSelectors"; | import { selectLatestChats } from "../../../store/selectors/chatSelectors"; | ||||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | import { selectUserId } from "../../../store/selectors/loginSelectors"; | ||||
| } | } | ||||
| }, [chats]); | }, [chats]); | ||||
| const goToMessages = () => { | const goToMessages = () => { | ||||
| history.push(CHAT_PAGE); | |||||
| history.push(`messages/${chats[0].chat?._id}`); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <HeaderPopover | <HeaderPopover |
| fetchOffers, | fetchOffers, | ||||
| } from "../store/actions/offers/offersActions"; | } from "../store/actions/offers/offersActions"; | ||||
| import { | import { | ||||
| selectAppliedStatus, | |||||
| selectSelectedCategory, | selectSelectedCategory, | ||||
| selectSelectedLocations, | selectSelectedLocations, | ||||
| selectSelectedSortOption, | selectSelectedSortOption, | ||||
| const selectedSubcategory = useSelector(selectSelectedSubcategory); | const selectedSubcategory = useSelector(selectSelectedSubcategory); | ||||
| const selectedLocations = useSelector(selectSelectedLocations); | const selectedLocations = useSelector(selectSelectedLocations); | ||||
| const selectedSortOption = useSelector(selectSelectedSortOption); | const selectedSortOption = useSelector(selectSelectedSortOption); | ||||
| const isApplied = useSelector(selectAppliedStatus); | |||||
| const total = useSelector(selectTotalOffers); | const total = useSelector(selectTotalOffers); | ||||
| const [page, setPage] = useState(1); | const [page, setPage] = useState(1); | ||||
| const [searchQuery, setSearchQuery] = useState(""); | |||||
| const [myOffersLength, setMyOffersLength] = useState(0); | |||||
| //Fetching chats | //Fetching chats | ||||
| useEffect(() => { | useEffect(() => { | ||||
| const allOffersToShow = useMemo(() => { | const allOffersToShow = useMemo(() => { | ||||
| let newOffers = [...pinnedOffersToShow, ...offersToShow]; | let newOffers = [...pinnedOffersToShow, ...offersToShow]; | ||||
| if (myOffers) { | if (myOffers) { | ||||
| // Filtering my offers based on category | |||||
| // Filtering my offers based on category | |||||
| if (selectedCategory && selectedCategory?._id !== 0) { | if (selectedCategory && selectedCategory?._id !== 0) { | ||||
| newOffers = newOffers.filter( | newOffers = newOffers.filter( | ||||
| (item) => item.category.name === selectedCategory.name | (item) => item.category.name === selectedCategory.name | ||||
| ), | ), | ||||
| ]; | ]; | ||||
| } | } | ||||
| newOffers = newOffers.filter((item) => | |||||
| item?.name?.toLowerCase().includes(searchQuery.toLowerCase(), 0) | |||||
| ); | |||||
| setMyOffersLength(newOffers?.length); | |||||
| newOffers = newOffers.slice((page - 1) * 10, page * 10); | newOffers = newOffers.slice((page - 1) * 10, page * 10); | ||||
| } | } | ||||
| return newOffers; | return newOffers; | ||||
| }, [pinnedOffersToShow, offersToShow, myOffers, page]); | |||||
| }, [ | |||||
| pinnedOffersToShow, | |||||
| offersToShow, | |||||
| myOffers, | |||||
| page, | |||||
| searchQuery, | |||||
| isApplied, | |||||
| ]); | |||||
| // Total number of all offers that can be shown | // Total number of all offers that can be shown | ||||
| const totalOffers = useMemo(() => { | const totalOffers = useMemo(() => { | ||||
| if (myOffers) { | if (myOffers) { | ||||
| return mineOffers?.length; | |||||
| return myOffersLength; | |||||
| } | } | ||||
| return total; | return total; | ||||
| }, [mineOffers, total, myOffers]); | |||||
| }, [total, myOffersLength]); | |||||
| const searchMyOffers = (searchValue) => { | |||||
| setSearchQuery(searchValue); | |||||
| }; | |||||
| // Changing page | // Changing page | ||||
| const handleDifferentPage = (pageNum) => { | const handleDifferentPage = (pageNum) => { | ||||
| totalOffers, | totalOffers, | ||||
| allOffersToShow, | allOffersToShow, | ||||
| page, | page, | ||||
| searchMyOffers, | |||||
| }; | }; | ||||
| }; | }; | ||||
| export default useOffers; | export default useOffers; |
| }, [props.informations]) | }, [props.informations]) | ||||
| const handleSubmit = () => { | const handleSubmit = () => { | ||||
| if (!formik.values.website.matches( | |||||
| if (formik.values.website?.length !== 0 && !formik.values.website.match( | |||||
| /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm | /^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm | ||||
| )) { | )) { | ||||
| formik.setFieldError("website"); | formik.setFieldError("website"); | ||||
| } else{ | |||||
| } else { | |||||
| props.handleSubmit(formik.values); | props.handleSubmit(formik.values); | ||||
| } | } | ||||
| fullWidth | fullWidth | ||||
| buttoncolor={selectedTheme.primaryPurple} | buttoncolor={selectedTheme.primaryPurple} | ||||
| textcolor="white" | textcolor="white" | ||||
| disabled={ | |||||
| formik.values.location.length === 0 && | |||||
| formik.values.phoneNumber.length === 0 && | |||||
| formik.values.website.length === 0 | |||||
| } | |||||
| > | > | ||||
| {t("common.continue")} | {t("common.continue")} | ||||
| </PrimaryButton> | </PrimaryButton> |
| function* fetchRegisterUser({ payload }) { | function* fetchRegisterUser({ payload }) { | ||||
| try { | try { | ||||
| const requestData = { | |||||
| let requestData = { | |||||
| email: payload.values.mail.toString(), | email: payload.values.mail.toString(), | ||||
| password: payload.values.password.toString(), | password: payload.values.password.toString(), | ||||
| image: payload.values.image | image: payload.values.image | ||||
| }, | }, | ||||
| }, | }, | ||||
| }; | }; | ||||
| if (payload.values.phoneNumber?.length === 0) | |||||
| delete requestData.company.contacts.telephone; | |||||
| if (payload.values.location?.length === 0) | |||||
| delete requestData.company.contacts.location; | |||||
| if (payload.values.website?.length === 0) | |||||
| delete requestData.company.contacts.web; | |||||
| yield call(attemptRegister, requestData); | yield call(attemptRegister, requestData); | ||||
| if (payload.handleResponseSuccess) { | if (payload.handleResponseSuccess) { | ||||
| yield call(payload.handleResponseSuccess); | yield call(payload.handleResponseSuccess); |