| @@ -10,7 +10,6 @@ import { | |||
| } from "./AboutSection.styled"; | |||
| const AboutSection = (props) => { | |||
| console.log(props); | |||
| return ( | |||
| <AboutSectionContainer reverse={props.reverse}> | |||
| <AboutSectionTextContainer> | |||
| @@ -23,6 +23,7 @@ const ThirdPartCreateOffer = (props) => { | |||
| ), | |||
| name: props.informations.nameOfProduct, | |||
| description: props.informations.description, | |||
| location: props.informations.location, | |||
| }, | |||
| }), | |||
| [props.informations] | |||
| @@ -20,6 +20,7 @@ import { | |||
| PinIconContainer, | |||
| PinIcon, | |||
| UnpinIcon, | |||
| LocationIcon, | |||
| // EditDeleteButtons, | |||
| } from "./ItemDetailsCard.styled"; | |||
| import selectedTheme from "../../../themes"; | |||
| @@ -33,19 +34,23 @@ import { startChat } from "../../../util/helpers/chatHelper"; | |||
| import Information from "./OfferInformations/SingleInformation/SingleInformation"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import OfferDetails from "./OfferDetails/OfferDetails"; | |||
| import { useRouteMatch } from "react-router-dom"; | |||
| import { useRouteMatch, useHistory } from "react-router-dom"; | |||
| import itemDetailsData from "../../../notFoundData/itemDetailsData"; | |||
| import { | |||
| toggleDeleteOfferModal, | |||
| toggleEditOfferModal, | |||
| } from "../../../store/actions/modal/modalActions"; | |||
| import { getExistChat } from "../../../store/actions/chat/chatActions"; | |||
| import useIsLoggedIn from "../../../hooks/useIsLoggedIn"; | |||
| import { LOGIN_PAGE } from "../../../constants/pages"; | |||
| const ItemDetailsCard = (props) => { | |||
| // const offer = props.offer; | |||
| const routeMatch = useRouteMatch(); | |||
| const chats = useSelector(selectLatestChats); | |||
| const userId = useSelector(selectUserId); | |||
| const history = useHistory(); | |||
| const { isLoggedIn } = useIsLoggedIn(); | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const offer = useMemo(() => { | |||
| @@ -84,13 +89,19 @@ const ItemDetailsCard = (props) => { | |||
| }; | |||
| const startExchange = () => { | |||
| dispatch( | |||
| getExistChat({ | |||
| userId: userId, | |||
| offerId: props.offer._id, | |||
| handleApiResponseSuccess, | |||
| }) | |||
| ); | |||
| if (!isLoggedIn) { | |||
| history.push({ | |||
| pathname: LOGIN_PAGE, | |||
| }); | |||
| } else { | |||
| dispatch( | |||
| getExistChat({ | |||
| userId: userId, | |||
| offerId: props.offer._id, | |||
| handleApiResponseSuccess, | |||
| }) | |||
| ); | |||
| } | |||
| }; | |||
| const showDeleteOfferModalHandler = () => { | |||
| @@ -123,7 +134,6 @@ const ItemDetailsCard = (props) => { | |||
| ); | |||
| }; | |||
| console.log(props); | |||
| return ( | |||
| <> | |||
| <ItemDetailsCardContainer | |||
| @@ -144,6 +154,10 @@ const ItemDetailsCard = (props) => { | |||
| value={offer?.subcategory} | |||
| /> | |||
| <Information icon={<QuantityIcon />} value={offer?.condition} /> | |||
| <Information | |||
| icon={<LocationIcon />} | |||
| value={props.previewCard ? offer?.location : offer?.location.city} | |||
| /> | |||
| {!props.hideViews && ( | |||
| <Information icon={<EyeIcon />} value={offer?.views?.count} /> | |||
| )} | |||
| @@ -13,6 +13,7 @@ import { ReactComponent as Edit } from "../../../assets/images/svg/edit.svg"; | |||
| import { ReactComponent as Pin } from "../../../assets/images/svg/pin-outlined.svg"; | |||
| import { ReactComponent as Unpin } from "../../../assets/images/svg/unpin-outlined.svg"; | |||
| import { ReactComponent as Remove } from "../../../assets/images/svg/trash.svg"; | |||
| import { ReactComponent as Location } from "../../../assets/images/svg/location.svg"; | |||
| export const ItemDetailsCardContainer = styled(Container)` | |||
| display: flex; | |||
| @@ -377,3 +378,7 @@ export const ButtonContainer = styled(Box)` | |||
| position: static; | |||
| } | |||
| `; | |||
| export const LocationIcon = styled(Location)` | |||
| width: 18px; | |||
| `; | |||
| @@ -7,6 +7,9 @@ export const InfoGroup = styled(Box)` | |||
| flex-direction: row; | |||
| align-items: center; | |||
| gap: 4px; | |||
| @media (max-width: 600px) { | |||
| max-width: calc(100% / 5); | |||
| } | |||
| `; | |||
| export const InfoIcon = styled(Box)` | |||
| display: flex; | |||
| @@ -1,6 +1,7 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| AlreadyFinishedExhangeMessage, | |||
| RequestExchangeMessageButton, | |||
| RequestExchangeMessageButtonsContainer, | |||
| RequestExchangeMessageContainer, | |||
| @@ -21,13 +22,18 @@ import { addNewMessage } from "../../../../store/actions/chat/chatActions"; | |||
| import { convertLocalDateToUTCDate } from "../../../../util/helpers/dateHelpers"; | |||
| import requesterStatus from "../../../../constants/requesterStatus"; | |||
| import { selectJwtToken } from "../../../../store/selectors/loginSelectors"; | |||
| import { selectOffers } from "../../../../store/selectors/offersSelectors"; | |||
| const RequestExchangeMessage = (props) => { | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const exchange = useSelector(selectExchange); | |||
| const requester = useSelector(selectRequester); | |||
| const token = useSelector(selectJwtToken) | |||
| const token = useSelector(selectJwtToken); | |||
| const offers = useSelector(selectOffers); | |||
| const isOfferExist = offers.filter( | |||
| (offer) => offer._id === exchange?.offer?._id | |||
| ); | |||
| const handleAcceptExchangeSuccess = () => { | |||
| console.log("accept salje i prima 3 POZVANA RESPONSE FUNKCIJA"); | |||
| @@ -66,28 +72,37 @@ const RequestExchangeMessage = (props) => { | |||
| }) | |||
| ); | |||
| }; | |||
| return ( | |||
| <RequestExchangeMessageContainer> | |||
| <RequestExchangeMessageText> | |||
| {t("messages.requestReceived")} | |||
| </RequestExchangeMessageText> | |||
| <RequestExchangeMessageButtonsContainer> | |||
| {!props.haveIAccepted && ( | |||
| <RequestExchangeMessageButton variant="outlined" white> | |||
| {t("messages.declineRequest")} | |||
| </RequestExchangeMessageButton> | |||
| )} | |||
| <RequestExchangeMessageButton | |||
| variant="contained" | |||
| onClick={handleAcceptExchange} | |||
| disabled={props.haveIAccepted} | |||
| > | |||
| {props.haveIAccepted | |||
| ? t("messages.acceptedRequest") | |||
| : t("messages.acceptRequest")} | |||
| </RequestExchangeMessageButton> | |||
| </RequestExchangeMessageButtonsContainer> | |||
| </RequestExchangeMessageContainer> | |||
| <> | |||
| {isOfferExist.length > 0 ? ( | |||
| <RequestExchangeMessageContainer> | |||
| <RequestExchangeMessageText> | |||
| {t("messages.requestReceived")} | |||
| </RequestExchangeMessageText> | |||
| <RequestExchangeMessageButtonsContainer> | |||
| {!props.haveIAccepted && ( | |||
| <RequestExchangeMessageButton variant="outlined" white> | |||
| {t("messages.declineRequest")} | |||
| </RequestExchangeMessageButton> | |||
| )} | |||
| <RequestExchangeMessageButton | |||
| variant="contained" | |||
| onClick={handleAcceptExchange} | |||
| disabled={props.haveIAccepted} | |||
| > | |||
| {props.haveIAccepted | |||
| ? t("messages.acceptedRequest") | |||
| : t("messages.acceptRequest")} | |||
| </RequestExchangeMessageButton> | |||
| </RequestExchangeMessageButtonsContainer> | |||
| </RequestExchangeMessageContainer> | |||
| ) : ( | |||
| <AlreadyFinishedExhangeMessage> | |||
| {t("messages.notAllowedChat")} | |||
| </AlreadyFinishedExhangeMessage> | |||
| )} | |||
| </> | |||
| ); | |||
| }; | |||
| @@ -50,3 +50,9 @@ export const RequestExchangeMessageButton = styled(PrimaryButton)` | |||
| } | |||
| } | |||
| `; | |||
| export const AlreadyFinishedExhangeMessage = styled(Typography)` | |||
| font-family: ${selectedTheme.fonts.textFont}; | |||
| font-size: 16px; | |||
| line-height: 22px; | |||
| color: ${selectedTheme.colors.primaryText}; | |||
| `; | |||
| @@ -4,7 +4,7 @@ import selectedTheme from "../../../../themes"; | |||
| import { NextButton as NextButtonContainer } from "../../CreateReview.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const NextButton = (props) => { | |||
| const NextButton = () => { | |||
| const { t } = useTranslation(); | |||
| return ( | |||
| <NextButtonContainer | |||
| @@ -13,7 +13,7 @@ const NextButton = (props) => { | |||
| fullWidth | |||
| height="48px" | |||
| type="submit" | |||
| disabled={props.formik.values.comment?.length < 5} | |||
| // disabled={props.formik.values.comment?.length < 5} | |||
| > | |||
| {t("common.continue")} | |||
| </NextButtonContainer> | |||
| @@ -46,6 +46,7 @@ import { useTranslation } from "react-i18next"; | |||
| import useIsTablet from "../../hooks/useIsTablet"; | |||
| import { clearFilters } from "../../store/actions/filters/filtersActions"; | |||
| import { selectLatestChats } from "../../store/selectors/chatSelectors"; | |||
| import useIsLoggedIn from "../../hooks/useIsLoggedIn"; | |||
| const Header = () => { | |||
| const theme = useTheme(); | |||
| @@ -62,6 +63,8 @@ const Header = () => { | |||
| const { isTablet } = useIsTablet(); | |||
| const [logoClicked, setLogoClicked] = useState(false); | |||
| const [badge, setBadge] = useState(0); | |||
| const { isLoggedIn } = useIsLoggedIn(); | |||
| console.log(isLoggedIn); | |||
| const { t } = useTranslation(); | |||
| const allChats = useSelector(selectLatestChats); | |||
| const seenLastChat = allChats[0]?.participants?.filter( | |||
| @@ -129,6 +132,9 @@ const Header = () => { | |||
| // Handling search when user is on marketplace and when he is not | |||
| const handleSearch = (value) => { | |||
| if (!isLoggedIn) { | |||
| search.searchOffersImmediately(value); | |||
| } | |||
| if (isAdminRoute()) { | |||
| search.setSearchStringManually(value); | |||
| } else { | |||
| @@ -13,12 +13,14 @@ import { fetchChats } from "../../store/actions/chat/chatActions"; | |||
| import { selectUserId } from "../../store/selectors/loginSelectors"; | |||
| import { toggleCreateOfferModal } from "../../store/actions/modal/modalActions"; | |||
| import useIsMobile from "../../hooks/useIsMobile"; | |||
| import useIsLoggedIn from "../../hooks/useIsLoggedIn"; | |||
| const MarketPlace = (props) => { | |||
| const [isGrid, setIsGrid] = useState(false); | |||
| const userId = useSelector(selectUserId); | |||
| const dispatch = useDispatch(); | |||
| const { isMobile } = useIsMobile(); | |||
| const { isLoggedIn } = useIsLoggedIn(); | |||
| useEffect(() => { | |||
| console.log("ABG", userId); | |||
| if (userId) | |||
| @@ -55,7 +57,7 @@ const MarketPlace = (props) => { | |||
| isUsers={props.users} | |||
| users={props.allUsers} | |||
| /> | |||
| {isMobile && ( | |||
| {isMobile && isLoggedIn && ( | |||
| <AddOfferButton onClick={addOfferHandler}> | |||
| <AddPlusIcon /> | |||
| </AddOfferButton> | |||
| @@ -264,11 +264,13 @@ export default { | |||
| "Da li želite da prihvatite trampu sa nama za gore navedeni proizvod?", | |||
| acceptRequest: "Prihvati", | |||
| acceptedRequest: "Prihvaćeno", | |||
| declinedRequest: "Odbijeno", | |||
| declineRequest: "Odbij", | |||
| requestSuccessfulLong: "Uspešno ste ostvarili trampu sa ovom kompanijom.", | |||
| requestSuccessfulShort: "Uspešno ste otvarili trampu.", | |||
| requestSentLong: "Ponudili ste trampu kompaniji. Čeka se odgovor...", | |||
| requestSentShort: "Ponudili ste trampu kompaniji.", | |||
| exchangeAlreadyFinished: "Trampa za ovaj proizvod je već završena.", | |||
| }, | |||
| editProfile: { | |||
| website: "Web Sajt", | |||
| @@ -19,7 +19,7 @@ import { | |||
| resetLoginState, | |||
| setUserJwtToken, | |||
| } from "../actions/login/loginActions"; | |||
| import { ADMIN_LOGIN_PAGE, LOGIN_PAGE } from "../../constants/pages"; | |||
| import { ADMIN_LOGIN_PAGE, BASE_PAGE, LOGIN_PAGE } from "../../constants/pages"; | |||
| import { addHeaderToken, removeHeaderToken } from "../../request"; | |||
| import { | |||
| JWT_REFRESH_TOKEN, | |||
| @@ -138,7 +138,7 @@ function* logout(payload) { | |||
| yield call(authScopeClearHelper); | |||
| yield call(removeHeaderToken); | |||
| yield put(resetLoginState()); | |||
| yield call(history.replace, LOGIN_PAGE); | |||
| yield call(history.replace, BASE_PAGE); | |||
| yield put(clearProfile()); | |||
| yield put(clearOffers()); | |||
| yield put(clearChat()); | |||
| @@ -1,6 +1,5 @@ | |||
| import i18next from "i18next"; | |||
| import * as Yup from "yup"; | |||
| export default Yup.object().shape({ | |||
| comment: Yup.string().min(5, i18next.t("reviews.commentError")), | |||
| comment: Yup.string(), | |||
| }); | |||