| @@ -14544,6 +14544,14 @@ | |||
| "react-transition-group": "^4.3.0" | |||
| } | |||
| }, | |||
| "react-toastify": { | |||
| "version": "9.0.3", | |||
| "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.3.tgz", | |||
| "integrity": "sha512-0QZJk0SqYBxouRBGCFU3ymvjlwimRRhVH7SzqGRiVrQ001KSoUNbGKx9Yq42aoPv18n45yJzEFG82zqv3HnASg==", | |||
| "requires": { | |||
| "clsx": "^1.1.1" | |||
| } | |||
| }, | |||
| "react-transition-group": { | |||
| "version": "4.4.2", | |||
| "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", | |||
| @@ -34,6 +34,7 @@ | |||
| "react-router-dom": "^5.2.0", | |||
| "react-scripts": "4.0.3", | |||
| "react-select": "^4.3.1", | |||
| "react-toastify": "^9.0.3", | |||
| "redux": "^4.1.0", | |||
| "redux-persist": "^6.0.0", | |||
| "redux-persist-transform-filter": "0.0.20", | |||
| @@ -8,6 +8,8 @@ import AppRoutes from "./AppRoutes"; | |||
| import Header from "./components/Header/Header"; | |||
| import { StyledEngineProvider } from "@mui/material"; | |||
| import GlobalStyle from "./components/Styles/globalStyles"; | |||
| import { ToastContainer } from "react-toastify"; | |||
| import "react-toastify/dist/ReactToastify.css"; | |||
| // const URL = "http://192.168.88.143:3001"; | |||
| // const socket = io(URL, {autoConnect: true, transports: ['websocket']}); | |||
| @@ -45,7 +47,7 @@ const App = () => { | |||
| // // }); | |||
| // socket.on('povratna', (data) => { | |||
| // console.log(data) | |||
| // }) | |||
| // // socket.open; | |||
| @@ -76,12 +78,11 @@ const App = () => { | |||
| <Router history={history}> | |||
| <Helmet> | |||
| <title>{i18next.t("app.title")}</title> | |||
| </Helmet> | |||
| <StyledEngineProvider injectFirst> | |||
| {/* <button onClick={handleClick}>Kik</button> */} | |||
| <Header /> | |||
| <GlobalStyle /> | |||
| <ToastContainer /> | |||
| {/* <div> | |||
| <p>Connected: {"" + isConnected}</p> | |||
| <br /> | |||
| @@ -91,7 +92,6 @@ const App = () => { | |||
| </div> */} | |||
| <AppRoutes /> | |||
| </StyledEngineProvider> | |||
| {/* </main> */} | |||
| </Router> | |||
| ); | |||
| }; | |||
| @@ -3,7 +3,6 @@ body { | |||
| -webkit-font-smoothing: antialiased; | |||
| -moz-osx-font-smoothing: grayscale; | |||
| overflow-anchor: none; | |||
| background-color: #F5F5F5; | |||
| } | |||
| * { | |||
| @@ -1,7 +1,7 @@ | |||
| @function pxToRem($target, $context: $base-font-size) { | |||
| @return calc($target / $context) * 1rem; | |||
| @return ($target / $context) * 1rem; | |||
| } | |||
| @function pxToRemMd($target, $context: $base-font-size-md) { | |||
| @return calc($target / $context) * 1rem; | |||
| @return ($target / $context) * 1rem; | |||
| } | |||
| @@ -1,8 +1,6 @@ | |||
| import React, { useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import { HOME_PAGE } from "../../../constants/pages"; | |||
| import { | |||
| CreateOfferContainer, | |||
| CreateOfferTitle, | |||
| @@ -17,8 +15,10 @@ import SecondPartCreateOffer from "./SecondPart/SecondPartCreateOffer"; | |||
| import ThirdPartCreateOffer from "./ThirdPart/ThirdPartCreateOffer"; | |||
| import { | |||
| addOffer, | |||
| fetchOffers, | |||
| fetchProfileOffers, | |||
| } from "../../../store/actions/offers/offersActions"; | |||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | |||
| import { editOneOffer } from "../../../store/actions/offers/offersActions"; | |||
| import { ReactComponent as ArrowBack } from "../../../assets/images/svg/arrow-back.svg"; | |||
| // import { ReactComponent as CloseButton } from "../../../assets/images/svg/close-modal.svg"; | |||
| @@ -26,31 +26,17 @@ import { useTranslation } from "react-i18next"; | |||
| import BackdropComponent from "../../MUI/BackdropComponent"; | |||
| import CloseButton from "./CloseButton/CloseButton"; | |||
| const CreateOffer = ({ history, closeCreateOfferModal, editOffer, offer }) => { | |||
| const CreateOffer = ({ closeCreateOfferModal, editOffer, offer }) => { | |||
| const dispatch = useDispatch(); | |||
| const [informations, setInformations] = useState({}); | |||
| const [currentStep, setCurrentStep] = useState(1); | |||
| const categories = useSelector((state) => state.categories.categories); | |||
| const historyRouter = useHistory(); | |||
| // const categories = useSelector((state) => state.categories.categories); | |||
| const userId = useSelector(selectUserId); | |||
| const { t } = useTranslation(); | |||
| const handleApiResponseSuccess = () => { | |||
| if (editOffer === undefined) { | |||
| const userId = historyRouter.location.pathname.slice( | |||
| 9, | |||
| historyRouter.location.pathname.length | |||
| ); | |||
| dispatch(fetchProfileOffers(userId)); | |||
| historyRouter.push({ | |||
| pathname: HOME_PAGE, | |||
| state: { | |||
| from: history.location.pathname, | |||
| }, | |||
| }); | |||
| } else { | |||
| const userId = offer.userId; | |||
| dispatch(fetchProfileOffers(userId)); | |||
| } | |||
| dispatch(fetchOffers({ queryString: "" })); | |||
| dispatch(fetchProfileOffers(userId)); | |||
| }; | |||
| const handleNext = (values) => { | |||
| @@ -69,12 +55,12 @@ const CreateOffer = ({ history, closeCreateOfferModal, editOffer, offer }) => { | |||
| .replace("data:image/png;base64,", "") | |||
| ); | |||
| let subcategories = []; | |||
| for (const element of categories) { | |||
| if (element.name === informations.category) { | |||
| subcategories = element.subcategories.map((item) => item.name); | |||
| } | |||
| } | |||
| // let subcategories = []; | |||
| // for (const element of categories) { | |||
| // if (element.name === informations.category) { | |||
| // subcategories = element.subcategories.map((item) => item.name); | |||
| // } | |||
| // } | |||
| const offerData = { | |||
| name: informations.nameOfProduct, | |||
| @@ -85,7 +71,6 @@ const CreateOffer = ({ history, closeCreateOfferModal, editOffer, offer }) => { | |||
| condition: informations.condition, | |||
| category: { | |||
| name: informations.category, | |||
| subcategories: subcategories, | |||
| }, | |||
| subcategory: informations.subcategory, | |||
| images: newImgs, | |||
| @@ -66,13 +66,7 @@ const CreateReview = (props) => { | |||
| } | |||
| }; | |||
| const goToPrevStep = () => { | |||
| if (currentStep === 2) { | |||
| setInformations({}); | |||
| setCurrentStep(1); | |||
| } | |||
| if (currentStep === 3) { | |||
| setCurrentStep(2); | |||
| } | |||
| setCurrentStep(prevCurrentStep => prevCurrentStep - 1); | |||
| }; | |||
| return ( | |||
| <CreateReviewContainer currentStep={currentStep}> | |||
| @@ -88,6 +82,7 @@ const CreateReview = (props) => { | |||
| <FirstStepCreateReview | |||
| offer={offer} | |||
| interlocutor={props.interlocutor} | |||
| informations={informations} | |||
| goToNextStep={goToNextStep} | |||
| /> | |||
| )} | |||
| @@ -1,4 +1,4 @@ | |||
| import React from "react"; | |||
| import React, { useEffect } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| FirstStepCreateReviewContainer, | |||
| @@ -20,8 +20,6 @@ import { useFormik } from "formik"; | |||
| import * as Yup from "yup"; | |||
| import useScreenDimensions from "../../../hooks/useScreenDimensions"; | |||
| // const selectFieldValidation = Yup.string().oneOf(Object.keys(reviewEnum).map(property => reviewEnum[property].mainText)); | |||
| const FirstStepCreateReview = (props) => { | |||
| const offer = props.offer; | |||
| const interlocutor = props.interlocutor; | |||
| @@ -31,6 +29,20 @@ const FirstStepCreateReview = (props) => { | |||
| props.goToNextStep(values); | |||
| }; | |||
| useEffect(() => { | |||
| if (props.informations?.exchangeSucceed) { | |||
| formik.setFieldValue( | |||
| "exchangeSucceed", | |||
| props.informations?.exchangeSucceed | |||
| ); | |||
| formik.setFieldValue( | |||
| "correctCommunication", | |||
| props.informations?.correctCommunication | |||
| ); | |||
| formik.setFieldValue("comment", props.informations?.comment); | |||
| } | |||
| }, [props.informations]); | |||
| const formik = useFormik({ | |||
| initialValues: { | |||
| exchangeSucceed: reviewEnum.YES.mainText, | |||
| @@ -64,18 +76,15 @@ const FirstStepCreateReview = (props) => { | |||
| leftText={t("reviews.isCorrectCommunication").toUpperCase()} | |||
| /> | |||
| <SelectField | |||
| defaultValue={reviewEnum.YES} | |||
| defaultValue={formik.values.correctCommunication} | |||
| onChange={(event) => | |||
| formik.setFieldValue( | |||
| "correctCommunication", | |||
| event.target.value.mainText | |||
| ) | |||
| formik.setFieldValue("correctCommunication", event.target.value) | |||
| } | |||
| > | |||
| {Object.keys(reviewEnum).map((property) => ( | |||
| <SelectOption | |||
| key={reviewEnum[property].value} | |||
| value={reviewEnum[property]} | |||
| value={reviewEnum[property].mainText} | |||
| > | |||
| {reviewEnum[property].mainText} | |||
| </SelectOption> | |||
| @@ -84,21 +93,22 @@ const FirstStepCreateReview = (props) => { | |||
| <FieldLabel leftText={t("reviews.hasExchangeSucceed").toUpperCase()} /> | |||
| <SelectField | |||
| defaultValue={reviewEnum.YES} | |||
| defaultValue={formik.values.exchangeSucceed} | |||
| onChange={(event) => | |||
| formik.setFieldValue("exchangeSucceed", event.target.value.mainText) | |||
| formik.setFieldValue("exchangeSucceed", event.target.value) | |||
| } | |||
| > | |||
| {Object.keys(reviewEnum).map((property) => { | |||
| if (property === "NOT_BAD") return; | |||
| return ( | |||
| <SelectOption | |||
| key={reviewEnum[property].value} | |||
| value={reviewEnum[property]} | |||
| > | |||
| {reviewEnum[property].mainText} | |||
| </SelectOption> | |||
| )})} | |||
| <SelectOption | |||
| key={reviewEnum[property].value} | |||
| value={reviewEnum[property]} | |||
| > | |||
| {reviewEnum[property].mainText} | |||
| </SelectOption> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <FieldLabel leftText={t("reviews.comment")} /> | |||
| @@ -131,6 +141,11 @@ FirstStepCreateReview.propTypes = { | |||
| offer: PropTypes.any, | |||
| interlocutor: PropTypes.any, | |||
| goToNextStep: PropTypes.func, | |||
| informations: PropTypes.shape({ | |||
| exchangeSucceed: PropTypes.string, | |||
| correctCommunication: PropTypes.string, | |||
| comment: PropTypes.string, | |||
| }), | |||
| }; | |||
| export default FirstStepCreateReview; | |||
| @@ -31,16 +31,25 @@ const DirectChatHeader = (props) => { | |||
| if (exchange.buyer?.givenReview) return true; | |||
| } | |||
| return false; | |||
| }, [exchange, userId]) | |||
| }, [exchange, userId]); | |||
| useEffect(() => { | |||
| if (showReviewModal) { | |||
| document.body.style.overflow = "hidden"; | |||
| } else { | |||
| document.body.style.overflow = "auto"; | |||
| } | |||
| }, [showReviewModal]); | |||
| const makeReview = () => { | |||
| setShowReviewModal(true); | |||
| }; | |||
| const handleGiveReviewSuccess = () => { | |||
| refetchExchange(); | |||
| } | |||
| }; | |||
| const refetchExchange = () => { | |||
| dispatch(fetchExchange(chat.chat.exchangeId)); | |||
| } | |||
| }; | |||
| return ( | |||
| <DirectChatHeaderContainer> | |||
| {showReviewModal && ( | |||
| @@ -9,6 +9,7 @@ import { useTranslation } from "react-i18next"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { | |||
| fetchChats, | |||
| sendMessage, | |||
| startNewChat, | |||
| } from "../../../store/actions/chat/chatActions"; | |||
| @@ -24,6 +25,7 @@ const DirectChatNewMessage = (props) => { | |||
| props.refreshChat(); | |||
| }; | |||
| const handleSend = () => { | |||
| console.log(location.state?.offerId); | |||
| if (location.state?.offerId) { | |||
| initiateNewChat(typedValue); | |||
| } else { | |||
| @@ -39,6 +41,7 @@ const DirectChatNewMessage = (props) => { | |||
| }; | |||
| const handleMessageSendSuccess = (newChatId) => { | |||
| history.replace(`${newChatId}`); | |||
| dispatch(fetchChats()); | |||
| }; | |||
| const initiateNewChat = (typedValue) => { | |||
| const offerId = location.state.offerId; | |||
| @@ -62,7 +62,7 @@ const ImagePicker = (props) => { | |||
| onClick={!image ? handleChange : () => {}} | |||
| hasImage={props.image} | |||
| > | |||
| <AddFile type="file" ref={fileInputRef} onInput={handleImage} /> | |||
| <AddFile type="file" ref={fileInputRef} onInput={handleImage} accept=".jpg, .jpeg, .png" /> | |||
| {image ? ( | |||
| <React.Fragment> | |||
| <ImageUploaded src={image} draggable={false} ref={imageRef} /> | |||
| @@ -5,12 +5,6 @@ import { HeaderContainer, HeaderText, ButtonContainer } from "./Header.styled"; | |||
| import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton"; | |||
| import { useTranslation } from "react-i18next"; | |||
| // const DownArrow = (props) => ( | |||
| // <IconStyled {...props}> | |||
| // <Down /> | |||
| // </IconStyled> | |||
| // ); | |||
| const Header = (props) => { | |||
| const history = useHistory(); | |||
| const { t } = useTranslation(); | |||
| @@ -27,7 +21,6 @@ const Header = (props) => { | |||
| > | |||
| <ButtonContainer> | |||
| <ArrowButton side={"left"}></ArrowButton> | |||
| {/* <HeaderText>{t("profile.back")}</HeaderText> */} | |||
| <HeaderText>{t("itemDetailsCard.headerTitle")}</HeaderText> | |||
| </ButtonContainer> | |||
| </HeaderContainer> | |||
| @@ -144,11 +144,15 @@ const Header = (props) => { | |||
| {/* Select option to choose sorting */} | |||
| <HeaderSelect | |||
| value={sortOption?.value ? sortOption.value : sortEnum.INITIAL.value} | |||
| value={sortOption?.value ? sortOption.value : "default"} | |||
| IconComponent={DownArrow} | |||
| onChange={handleChangeSelect} | |||
| > | |||
| <SelectOption style={{ display: "none" }} value="default"> | |||
| Sortiraj po | |||
| </SelectOption> | |||
| {Object.keys(sortEnum).map((property) => { | |||
| if(sortEnum[property].value === 0) return; | |||
| return ( | |||
| <SelectOption | |||
| value={sortEnum[property].value} | |||
| @@ -4,7 +4,7 @@ import selectedTheme from "../../../themes"; | |||
| import { IconButton } from "../../Buttons/IconButton/IconButton"; | |||
| import Option from "../../Select/Option/Option"; | |||
| import Select from "../../Select/Select"; | |||
| import {ReactComponent as Refresh} from "../../../assets/images/svg/refresh.svg" | |||
| import { ReactComponent as Refresh } from "../../../assets/images/svg/refresh.svg"; | |||
| export const HeaderContainer = styled(Box)` | |||
| margin-top: 20px; | |||
| @@ -19,14 +19,14 @@ export const HeaderLocation = styled(Box)` | |||
| line-height: 22px; | |||
| font-size: 16px; | |||
| flex: 2; | |||
| max-width: ${props => props.initial ? "fit-content" : "50%"}; | |||
| max-width: ${(props) => (props.initial ? "fit-content" : "50%")}; | |||
| white-space: nowrap; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| &:after { | |||
| content: ${props => props.initial ? `":"` : `""`}; | |||
| content: ${(props) => (props.initial ? `":"` : `""`)}; | |||
| @media (max-width: 600px) { | |||
| content: ""; | |||
| content: ""; | |||
| } | |||
| } | |||
| @media (max-width: 600px) { | |||
| @@ -86,14 +86,14 @@ export const HeaderButtons = styled(Box)` | |||
| margin-right: 40px; | |||
| `; | |||
| export const HeaderAltLocation = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryText}; | |||
| margin-left: 5px; | |||
| @media (max-width: 600px) { | |||
| display: none; | |||
| } | |||
| ` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryText}; | |||
| margin-left: 5px; | |||
| @media (max-width: 600px) { | |||
| display: none; | |||
| } | |||
| `; | |||
| export const RefreshIcon = styled(Refresh)` | |||
| width: 18px; | |||
| height: 18px; | |||
| @@ -103,11 +103,11 @@ export const RefreshIcon = styled(Refresh)` | |||
| & path { | |||
| stroke: ${selectedTheme.primaryDarkTextThird}; | |||
| } | |||
| ` | |||
| `; | |||
| export const MySwapsTitle = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryDarkTextThird}; | |||
| position: relative; | |||
| left: 9px; | |||
| ` | |||
| `; | |||
| @@ -41,7 +41,7 @@ export const MyMessages = () => { | |||
| } | |||
| }, [chats]); | |||
| const goToMessages = () => { | |||
| history.push(`messages/${chats[0].chat?._id}`); | |||
| history.push(`/messages/${chats[0].chat?._id}`); | |||
| }; | |||
| return ( | |||
| <HeaderPopover | |||
| @@ -25,9 +25,9 @@ import { | |||
| editMineProfile, | |||
| fetchMineProfile, | |||
| } from "../../../store/actions/profile/profileActions"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | |||
| import useScreenDimensions from "../../../hooks/useScreenDimensions"; | |||
| import { useRouteMatch } from "react-router-dom"; | |||
| import editProfileValidation from "../../../validations/editProfileValidation"; | |||
| const EditProfile = (props) => { | |||
| @@ -37,8 +37,7 @@ const EditProfile = (props) => { | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const dimensions = useScreenDimensions(); | |||
| const routeMatch = useRouteMatch(); | |||
| const userId = routeMatch.params.idProfile; | |||
| const userId = useSelector(selectUserId); | |||
| useEffect(() => { | |||
| if (dimensions.width < 600) { | |||
| @@ -124,6 +123,7 @@ const EditProfile = (props) => { | |||
| <InputFieldLabel leftText={t("common.labelPIB")} /> | |||
| <InputField | |||
| name="firmPIB" | |||
| type="number" | |||
| value={formik.values.firmPIB} | |||
| onChange={formik.handleChange} | |||
| error={formik.touched.firmPIB && formik.errors.firmPIB} | |||
| @@ -96,6 +96,7 @@ export default { | |||
| PIBnoOfCharacters: "PIB mora imati 9 karaktera!", | |||
| welcome: "Dobro došli na trampu, želimo vam uspešno trampovanje!", | |||
| imageError: "Slika je obavezna!", | |||
| serverError: "Greška sa serverom!", | |||
| }, | |||
| forgotPassword: { | |||
| title: "Povrati lozinku", | |||
| @@ -24,10 +24,6 @@ export const RightCard = styled(Grid)` | |||
| margin-top: 34px; | |||
| border-top-right-radius: 4px; | |||
| width: 100%; | |||
| /* @media (max-width: 800px) { | |||
| position: relative; | |||
| bottom: -500px; | |||
| } */ | |||
| `; | |||
| export const Content = styled(Grid)` | |||
| `; | |||
| @@ -25,6 +25,7 @@ import SecondPartOfRegistration from "./SecondPart/SecondPartOfRegistration"; | |||
| import ThirdPartOfRegistration from "./ThirdPart/ThirdPartOfRegistration"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { fetchRegisterUser } from "../../../store/actions/register/registerActions"; | |||
| import { makeErrorToastMessage } from "../../../store/utils/makeToastMessage"; | |||
| const Register = () => { | |||
| const { t } = useTranslation(); | |||
| @@ -50,18 +51,20 @@ const Register = () => { | |||
| setCurrentStep(1); | |||
| setMailError(mail); | |||
| if ( | |||
| error.error.response.data.toString() === | |||
| error?.error?.response?.data?.toString() === | |||
| "User with email already exists" | |||
| ) { | |||
| setMailErrorMessage(t("register.emailTaken")); | |||
| } else { | |||
| setMailErrorMessage(t("register.emailFormat")); | |||
| } | |||
| } else { | |||
| } else if (error?.error?.response?.data?.toString() === "Company with PIB already exists") { | |||
| setInformations({ mail, password, image }); | |||
| setCurrentStep(2); | |||
| setPIBError(PIB.toString()); | |||
| setPIBErrorMessage(t("register.PIBTaken")); | |||
| } else { | |||
| makeErrorToastMessage(t("register.serverError")) | |||
| } | |||
| }; | |||
| @@ -1,6 +1,4 @@ | |||
| import { ERROR_PAGE } from "../../constants/pages"; | |||
| import { attachPostRequestListener } from "../../request"; | |||
| import history from "../utils/history"; | |||
| //Interceptor unique name | |||
| export const serverErrorMiddlewareInterceptorName = | |||
| @@ -11,8 +9,8 @@ export default () => (next) => (action) => { | |||
| if (!error.response) { | |||
| return Promise.reject(error); | |||
| } | |||
| if (error.response.status === 5000) { | |||
| return history.push(ERROR_PAGE); | |||
| if (error.response.status === 500) { | |||
| return "aaa"; | |||
| } | |||
| return Promise.reject(error); | |||
| }, serverErrorMiddlewareInterceptorName); | |||
| @@ -4,8 +4,16 @@ import { CATEGORIES_FETCH } from "../actions/categories/categoriesActionConstant | |||
| import { setCategories } from "../actions/categories/categoriesActions"; | |||
| function* fetchCategories() { | |||
| const { data } = yield call(attemptFetchCategories); | |||
| yield put(setCategories(data)); | |||
| try { | |||
| const { data } = yield call(attemptFetchCategories); | |||
| if (data) { | |||
| yield put(setCategories(data)); | |||
| } | |||
| return true; | |||
| } catch (e) { | |||
| console.log(e); | |||
| return false; | |||
| } | |||
| } | |||
| export default function* categoriesSaga() { | |||
| @@ -4,12 +4,17 @@ import { LOCATIONS_FETCH } from "../actions/locations/locationsActionConstants"; | |||
| import { setLocations } from "../actions/locations/locationsActions"; | |||
| function* fetchLocations() { | |||
| const {data} = yield call(attemptFetchLocations) | |||
| yield put(setLocations(data)); | |||
| try { | |||
| const { data } = yield call(attemptFetchLocations); | |||
| console.log(data); | |||
| if (data) { | |||
| yield put(setLocations(data)); | |||
| } | |||
| } catch (e) { | |||
| console.log(e); | |||
| } | |||
| } | |||
| export default function* locationsSaga() { | |||
| yield all([ | |||
| takeLatest(LOCATIONS_FETCH, fetchLocations) | |||
| ]) | |||
| } | |||
| yield all([takeLatest(LOCATIONS_FETCH, fetchLocations)]); | |||
| } | |||
| @@ -132,9 +132,11 @@ function* refreshUserToken({payload}) { | |||
| yield put(setUserJwtToken({token: payload, exp: newTokenDecoded.exp})); | |||
| yield call(addHeaderToken, payload); | |||
| yield call(authScopeSetHelper, JWT_TOKEN, payload); | |||
| return true; | |||
| } | |||
| catch(e){ | |||
| console.log(e); | |||
| return false; | |||
| } | |||
| } | |||
| @@ -57,7 +57,7 @@ function* fetchOffers(payload) { | |||
| attemptFetchOffers, | |||
| "?" + newQueryString.toString() | |||
| ); | |||
| console.log('data::::::::: ', data.data) | |||
| console.log("data::::::::: ", data.data); | |||
| yield put(setTotalOffers(data.data.total)); | |||
| yield put(setOffers(data.data.items.regularOffers)); | |||
| yield put(setPinnedOffers(data.data.items.pinnedOffers)); | |||
| @@ -113,7 +113,7 @@ function* createOffer(payload) { | |||
| function* fetchOneOffer(payload) { | |||
| try { | |||
| console.log(payload); | |||
| const data = yield call(attemptFetchOneOffer, payload.payload) | |||
| const data = yield call(attemptFetchOneOffer, payload.payload); | |||
| console.log(data.data); | |||
| yield put(setOffer(data.data)); | |||
| } catch (e) { | |||
| @@ -138,7 +138,8 @@ function* fetchMineOffers() { | |||
| function* fetchProfileOffers(payload) { | |||
| try { | |||
| const userId = payload.payload; | |||
| if (!userId || userId?.length === 0) throw new Error("User id is not defined!"); | |||
| if (!userId || userId?.length === 0) | |||
| throw new Error("User id is not defined!"); | |||
| const data = yield call(attemptFetchProfileOffers, userId); | |||
| yield put(setProfileOffers(data.data)); | |||
| } catch (e) { | |||
| @@ -29,9 +29,11 @@ function* fetchProfile(payload) { | |||
| function* fetchMineProfile() { | |||
| try { | |||
| const userId = yield select(selectUserId); | |||
| const data = yield call(attemptFetchProfile, userId); | |||
| console.log(data); | |||
| if (data) yield put(setMineProfile(data.data)); | |||
| if (userId) { | |||
| const data = yield call(attemptFetchProfile, userId); | |||
| console.log(data); | |||
| if (data) yield put(setMineProfile(data.data)); | |||
| } | |||
| } catch (e) { | |||
| console.log(e); | |||
| } | |||
| @@ -7,8 +7,8 @@ import { setQueryStringRedux } from "../actions/queryString/queryStringActions"; | |||
| function* setQueryString(payload) { | |||
| try { | |||
| console.log("trenutni queryString: ", payload.payload); | |||
| console.log(payload); | |||
| // console.log("trenutni queryString: ", payload.payload); | |||
| // console.log(payload); | |||
| // const currentQS = yield select(selectQueryString); | |||
| // let newQueryString = payload.payload | |||
| // if (currentQS?.length > 0) { | |||
| @@ -28,18 +28,21 @@ function* fetchRegisterUser({ payload }) { | |||
| if (payload.values.website?.length === 0) | |||
| delete requestData.company.contacts.web; | |||
| yield call(attemptRegister, requestData); | |||
| console.log('jos nije crash') | |||
| if (payload.handleResponseSuccess) { | |||
| yield call(payload.handleResponseSuccess); | |||
| } | |||
| return true; | |||
| } catch (e) { | |||
| let type; | |||
| console.log(e) | |||
| let type = "server"; | |||
| if ( | |||
| e.response?.data?.toString() === "User with email already exists" || | |||
| e.response?.data?.toString() === '"email" must be a valid email' | |||
| e?.response?.data?.toString() === "User with email already exists" || | |||
| e?.response?.data?.toString() === '"email" must be a valid email' | |||
| ) { | |||
| type = "mail"; | |||
| } else if ( | |||
| e.response?.data?.toString() === "Company with PIB already exists" | |||
| e?.response?.data?.toString() === "Company with PIB already exists" | |||
| ) { | |||
| type = "PIB"; | |||
| } | |||
| @@ -50,6 +53,7 @@ function* fetchRegisterUser({ payload }) { | |||
| if (payload.handleResponseError) { | |||
| yield call(payload.handleResponseError, error); | |||
| } | |||
| return false; | |||
| } | |||
| } | |||
| @@ -0,0 +1,14 @@ | |||
| import { toast } from 'react-toastify'; | |||
| const defaultOptions = { | |||
| position: "top-center", | |||
| autoClose: 2000, | |||
| hideProgressBar: true, | |||
| closeOnClick: true, | |||
| pauseOnHover: true, | |||
| pauseOnFocusLoss: false, | |||
| draggable: true, | |||
| } | |||
| export const makeToastMessage = (text, options = defaultOptions) => toast(text, options); | |||
| export const makeErrorToastMessage = (text, options = defaultOptions) => toast.error(text, options); | |||
| @@ -4,7 +4,8 @@ export default Yup.object().shape({ | |||
| firmName: Yup.string().required(i18n.t("editProfile.labelNameRequired")), | |||
| firmPIB: Yup.string() | |||
| .required(i18n.t("editProfile.labelPIBRequired")) | |||
| .min(9, i18n.t("register.PIBnoOfCharacters")), | |||
| .min(9, i18n.t("register.PIBnoOfCharacters")) | |||
| .max(9, i18n.t("register.PIBnoOfCharacters")), | |||
| firmLocation: Yup.string().required( | |||
| i18n.t("editProfile.labelLocationRequired") | |||
| ), | |||