| @@ -24,22 +24,35 @@ import { selectLatestChats } from "../../../store/selectors/chatSelectors"; | |||
| import { increaseCounter } from "../../../store/actions/counter/counterActions"; | |||
| import _ from "lodash"; | |||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | |||
| import { formatDateLocale } from "../../../util/helpers/dateHelpers"; | |||
| import { formatDateLocale, formatDateTimeLocale } from "../../../util/helpers/dateHelpers"; | |||
| import { startChat } from "../../../util/helpers/chatHelper"; | |||
| import Information from "./Information/Information"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import DeleteOffer from "../OfferCard/DeleteOffer/DeleteOffer"; | |||
| import CreateOffer from "../CreateOfferCard/CreateOffer"; | |||
| import OfferDetails from "./OfferDetails/OfferDetails"; | |||
| import { useRouteMatch } from "react-router-dom"; | |||
| import itemDetailsData from "../../../notFoundData/itemDetailsData"; | |||
| const ItemDetailsCard = (props) => { | |||
| const [showModalRemove, setShowModalRemove] = useState(false); | |||
| const [showModalEdit, setShowModalEdit] = useState(false); | |||
| const offer = props.offer; | |||
| // const offer = props.offer; | |||
| const routeMatch = useRouteMatch(); | |||
| const chats = useSelector(selectLatestChats); | |||
| const userId = useSelector(selectUserId); | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| console.log(props.offer) | |||
| console.log(formatDateTimeLocale(new Date())); | |||
| const offer = useMemo(() => { | |||
| if (props.offer) { | |||
| if (props.offer.offer._id === routeMatch.params.idProizvod) { | |||
| return props.offer; | |||
| } | |||
| } | |||
| return itemDetailsData | |||
| }, [props.offer]) | |||
| const increaseOfferCounter = useMemo(() => { | |||
| return _.once(function (id) { | |||
| @@ -11,7 +11,7 @@ import { | |||
| } from "./ItemDetailsHeaderCard.styled"; | |||
| import { ItemDetailsHeaderContainer } from "./ItemDetailsHeaderCard.styled"; | |||
| import { ReactComponent as MessageColor } from "../../../assets/images/svg/mailColor.svg"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import { useHistory, useRouteMatch } from "react-router-dom"; | |||
| import { useSelector } from "react-redux"; | |||
| import { selectLatestChats } from "../../../store/selectors/chatSelectors"; | |||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | |||
| @@ -20,11 +20,21 @@ import PIBDetail from "./OfferDetail/PIB/PIBDetail"; | |||
| import CategoryDetail from "./OfferDetail/Category/CategoryDetail"; | |||
| import useIsMobile from "../../../hooks/useIsMobile"; | |||
| import { getImageUrl, variants } from "../../../util/helpers/imageUrlGetter"; | |||
| import { useMemo } from "react"; | |||
| import itemDetailsData from "../../../notFoundData/itemDetailsData"; | |||
| const ItemDetailsHeaderCard = (props) => { | |||
| const history = useHistory(); | |||
| const chats = useSelector(selectLatestChats); | |||
| const offer = props.offer; | |||
| const routeMatch = useRouteMatch(); | |||
| const offer = useMemo(() => { | |||
| if (props.offer) { | |||
| if (props.offer.offer._id === routeMatch.params.idProizvod) { | |||
| return props.offer; | |||
| } | |||
| } | |||
| return itemDetailsData; | |||
| }, [props.offer]); | |||
| const userId = useSelector(selectUserId); | |||
| const { isMobile } = useIsMobile(); | |||
| @@ -62,8 +72,8 @@ const ItemDetailsHeaderCard = (props) => { | |||
| <OfferTitle isMyProfile={props.isMyProfile} onClick={handleGoProfile}> | |||
| {offer?.companyData?.company?.name} | |||
| </OfferTitle> | |||
| <PIBDetail offer={props.offer} isMyProfile={props.isMyProfile} /> | |||
| <CategoryDetail offer={props.offer} isMyProfile={props.isMyProfile} /> | |||
| <PIBDetail offer={offer} isMyProfile={props.isMyProfile} /> | |||
| <CategoryDetail offer={offer} isMyProfile={props.isMyProfile} /> | |||
| </OfferDetails> | |||
| {props.isMyProfile ? ( | |||
| <UserIconContainer onClick={handleGoProfile}> | |||
| @@ -4,19 +4,19 @@ import { | |||
| DetailContainer, | |||
| DetailIcon, | |||
| DetailText, | |||
| LocationIcon, | |||
| } from "./CategoryDetail.styled"; | |||
| import selectedTheme from "../../../../../themes"; | |||
| import { ReactComponent as Category } from "../../../../../assets/images/svg/category.svg"; | |||
| const CategoryDetail = (props) => { | |||
| const offer = props.offer; | |||
| return ( | |||
| <DetailContainer shouldHideResponsive> | |||
| <DetailIcon color={selectedTheme.iconStrokeColor} size="22px"> | |||
| <Category width={"22px"} /> | |||
| <LocationIcon /> | |||
| </DetailIcon> | |||
| <DetailText ismyprofile={props.isMyProfile}> | |||
| {offer?.companyData?.company?.contacts?.location} | |||
| {offer.offer.location.city} | |||
| </DetailText> | |||
| </DetailContainer> | |||
| ); | |||
| @@ -2,6 +2,8 @@ import { Box, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../../../themes"; | |||
| import { Icon } from "../../../../Icon/Icon"; | |||
| import { ReactComponent as Location } from "../../../../../assets/images/svg/location.svg"; | |||
| export const DetailContainer = styled(Box)` | |||
| display: flex; | |||
| @@ -34,4 +36,7 @@ export const DetailText = styled(Typography)` | |||
| @media (max-width: 600px) { | |||
| font-size: 14px; | |||
| } | |||
| `; | |||
| `; | |||
| export const LocationIcon = styled(Location)` | |||
| ` | |||
| @@ -28,6 +28,8 @@ import { useTranslation } from "react-i18next"; | |||
| import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; | |||
| import { PROFILE_SCOPE } from "../../store/actions/profile/profileActionConstants"; | |||
| import SkeletonProfileCard from "./SkeletonProfileCard/SkeletonProfileCard"; | |||
| import { useMemo } from "react"; | |||
| import companyData from "../../notFoundData/companyData"; | |||
| const ProfileCard = () => { | |||
| const [isMyProfile, setIsMyProfile] = useState(false); | |||
| @@ -35,11 +37,22 @@ const ProfileCard = () => { | |||
| const isLoading = useSelector(selectIsLoadingByActionType(PROFILE_SCOPE)); | |||
| const routeMatch = useRouteMatch(); | |||
| const dispatch = useDispatch(); | |||
| const profile = useSelector(selectProfile); | |||
| const profileFromRedux = useSelector(selectProfile); | |||
| const userId = useSelector(selectUserId); | |||
| const idProfile = routeMatch.params.idProfile; | |||
| const { t } = useTranslation(); | |||
| const profile = useMemo(() => { | |||
| if (profileFromRedux) { | |||
| if (profileFromRedux._id === routeMatch.params.idProfile) { | |||
| return profileFromRedux; | |||
| } | |||
| } | |||
| return companyData; | |||
| }, [profileFromRedux]); | |||
| console.log("profile", profile); | |||
| useEffect(() => { | |||
| if (idProfile?.length > 0) { | |||
| reFetchProfile(); | |||
| @@ -0,0 +1 @@ | |||
| export default "https://imagedelivery.net/DxXj0X9GSRP3KZrHy56BZA/c8305fba-b9bd-46fe-3c67-3dd151da0e00/"; | |||
| @@ -173,6 +173,7 @@ export default { | |||
| }, | |||
| apiErrors: { | |||
| somethingWentWrong: "Greška sa serverom!", | |||
| offerNotFound: "Ponuda nije pronađena!" | |||
| }, | |||
| header: { | |||
| addOffer: "Dodaj proizvod", | |||
| @@ -365,5 +366,16 @@ export default { | |||
| aboutFooter: { | |||
| goStart: "Početak stranice", | |||
| middleText: "Diligent Software © 2022 | Sva prava zadržana" | |||
| }, | |||
| notFoundData: { | |||
| PIB: "PIB broj", | |||
| companyName: "Naziv kompanije", | |||
| categoryName: "Naziv kategorije", | |||
| location: "Naziv grada", | |||
| subcategoryName: "Naziv podkategorije", | |||
| offerName: "Naslov ponude", | |||
| condition: "Stanje", | |||
| description: "Opis", | |||
| email: "Mejl kompanije" | |||
| } | |||
| }; | |||
| @@ -0,0 +1,23 @@ | |||
| import i18next from "i18next"; | |||
| import defaultImage from "../constants/defaultImage"; | |||
| export default { | |||
| company: { | |||
| name: i18next.t("notFoundData.companyName"), | |||
| PIB: i18next.t("notFoundData.PIB") | |||
| }, | |||
| email: i18next.t("notFoundData.email"), | |||
| image: defaultImage, | |||
| statistics: { | |||
| exchanges: { | |||
| failed: 0, | |||
| succeeded: 0, | |||
| total: 0, | |||
| }, | |||
| publishes: { | |||
| count: 0, | |||
| }, | |||
| views: { | |||
| count: 0, | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,47 @@ | |||
| import i18next from "i18next"; | |||
| import defaultImage from "../constants/defaultImage"; | |||
| export default { | |||
| companyData: { | |||
| company: { | |||
| PIB: i18next.t("notFoundData.PIB"), | |||
| name: i18next.t("notFoundData.companyName") | |||
| }, | |||
| image: defaultImage, | |||
| lastThreeReviews: [], | |||
| statistics: { | |||
| exchanges: { | |||
| failed: 0, | |||
| succeeded: 0, | |||
| total: 0, | |||
| }, | |||
| publishes: { | |||
| count: 0, | |||
| }, | |||
| views: { | |||
| count: 0, | |||
| } | |||
| } | |||
| }, | |||
| offer: { | |||
| category: { | |||
| name: i18next.t("notFoundData.categoryName") | |||
| }, | |||
| condition: i18next.t("notFoundData.condition"), | |||
| description: i18next.t("notFoundData.description"), | |||
| images: [defaultImage], | |||
| location: { | |||
| city: i18next.t("notFoundData.location") | |||
| }, | |||
| name: i18next.t("notFoundData.offerName"), | |||
| pinned: false, | |||
| subcategory: i18next.t("notFoundData.subcategoryName"), | |||
| user: { | |||
| company: i18next.t("notFoundData.companyName") | |||
| }, | |||
| views: { | |||
| count: 0 | |||
| }, | |||
| _created: new Date().toString() | |||
| } | |||
| } | |||
| @@ -14,7 +14,7 @@ export default () => (next) => (action) => { | |||
| if (error.response.status === 500) { | |||
| return makeErrorToastMessage(i18next.t("apiErrors.somethingWentWrong")); | |||
| } | |||
| return makeErrorToastMessage(i18next.t("apiErrors.somethingWentWrong")); | |||
| return Promise.reject(error); | |||
| }, serverErrorMiddlewareInterceptorName); | |||
| next(action); | |||
| @@ -72,53 +72,10 @@ import { | |||
| selectPinnedOffers, | |||
| selectTotalOffers, | |||
| } from "../selectors/offersSelectors"; | |||
| import history from "../utils/history"; | |||
| import { NOT_FOUND_PAGE } from "../../constants/pages"; | |||
| // import { KEY_PAGE } from "../../constants/queryStringConstants"; | |||
| // function* fetchAllOffers(payload) { | |||
| // try { | |||
| // yield put(clearOffers()); | |||
| // yield put(clearFeaturedOffers()); | |||
| // const queryString = new URLSearchParams( | |||
| // convertQueryStringForBackend(payload.payload.queryString) | |||
| // ); | |||
| // const page = queryString.get(KEY_PAGE); | |||
| // const offerPage = yield select(selectOfferPage) | |||
| // const featuredOfferPage = yield select(selectFeaturedOfferPage); | |||
| // const featuredOffers = yield call( | |||
| // attemptFetchFeaturedOffers, | |||
| // "?" + removePageAndSizeHelper(queryString.toString()) | |||
| // ); | |||
| // const newQueryString = new URLSearchParams( | |||
| // convertQueryStringForBackend(payload.payload.queryString) | |||
| // ); | |||
| // const regularOffers = yield call( | |||
| // attemptFetchOffers, | |||
| // "?" + queryString.toString() | |||
| // ); | |||
| // const offerIndex = featuredOffers.data.length - page * 10; | |||
| // if (page > Math.floor(featuredOffers.data.length - (page - 1) * 10)) { | |||
| // if (featuredOffers.data.length !== 0) { | |||
| // yield put( | |||
| // setPinnedOffers( | |||
| // featuredOffers.data.slice((page - 1) * 10), | |||
| // featuredOffers.data.length | |||
| // ) | |||
| // ); | |||
| // yield put(setOffers(regularOffers.data.items.slice())); | |||
| // } | |||
| // } | |||
| // yield put( | |||
| // setTotalOffers(regularOffers.data.total + featuredOffers.data.length) | |||
| // ); | |||
| // yield put(setPinnedOffers(featuredOffers.data.items.pinnedOffers)); | |||
| // yield put(fetchAllOffersSuccess()); | |||
| // } catch (e) { | |||
| // yield put(fetchAllOffersError()); | |||
| // yield call(console.log, e); | |||
| // } | |||
| // } | |||
| // import history from "../utils/history"; | |||
| // import { NOT_FOUND_PAGE } from "../../constants/pages"; | |||
| import { makeErrorToastMessage } from "../utils/makeToastMessage"; | |||
| import i18next from "i18next"; | |||
| function* fetchOffers(payload) { | |||
| try { | |||
| @@ -224,9 +181,10 @@ function* fetchOneOffer(payload) { | |||
| yield put(fetchOneOfferSuccess(data.data)); | |||
| } catch (e) { | |||
| console.log(e.response.status); | |||
| if (e.response.status === 400) { | |||
| yield call(history.push, NOT_FOUND_PAGE); | |||
| } | |||
| // if (e.response.status === 400) { | |||
| // yield call(history.push, NOT_FOUND_PAGE); | |||
| // } | |||
| yield call(makeErrorToastMessage, i18next.t("apiErrors.offerNotFound")); | |||
| yield put(fetchOneOfferError()); | |||
| } | |||
| } | |||
| @@ -247,7 +205,6 @@ function* fetchMineHeaderOffers() { | |||
| try { | |||
| const userId = yield select(selectUserId); | |||
| const data = yield call(attemptFetchProfileOffers, userId); | |||
| console.log('povezivanje') | |||
| yield put(setMineHeaderOffers(data.data.slice(0, 2))); | |||
| yield put(fetchMineHeaderOffersSuccess()); | |||
| } catch (e) { | |||
| @@ -266,9 +223,9 @@ function* fetchProfileOffers(payload) { | |||
| yield put(fetchProfileOffersSuccess()); | |||
| } catch (e) { | |||
| console.dir(e); | |||
| if (e.response.status === 400) { | |||
| yield call(history.push, NOT_FOUND_PAGE); | |||
| } | |||
| // if (e.response.status === 400) { | |||
| // yield call(history.push, NOT_FOUND_PAGE); | |||
| // } | |||
| yield put(fetchProfileOffersError()); | |||
| } | |||
| } | |||
| @@ -1,8 +1,8 @@ | |||
| import { format } from 'date-fns'; | |||
| import { enUS } from 'date-fns/locale'; | |||
| // import { enUS } from 'date-fns/locale'; | |||
| import i18next from 'i18next'; | |||
| export function formatDate(date, fmt = 'MM/dd/y', locale = enUS) { | |||
| export function formatDate(date, fmt = 'MM/dd/y', locale) { | |||
| const dt = new Date(date); | |||
| return format(dt, fmt, { locale }); | |||
| } | |||