| import ThirdPartCreateOffer from "./ThirdPart/ThirdPartCreateOffer"; | import ThirdPartCreateOffer from "./ThirdPart/ThirdPartCreateOffer"; | ||||
| import { | import { | ||||
| addOffer, | addOffer, | ||||
| // fetchOffers, | |||||
| // fetchOneOffer, | |||||
| fetchOffers, | |||||
| fetchOneOffer, | |||||
| fetchProfileOffers, | fetchProfileOffers, | ||||
| } from "../../../store/actions/offers/offersActions"; | } from "../../../store/actions/offers/offersActions"; | ||||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | import { selectUserId } from "../../../store/selectors/loginSelectors"; | ||||
| import { useMemo } from "react"; | import { useMemo } from "react"; | ||||
| // import { useLocation } from "react-router-dom"; | // import { useLocation } from "react-router-dom"; | ||||
| import { useHistory } from "react-router-dom"; | import { useHistory } from "react-router-dom"; | ||||
| import { PROFILE_PAGE } from "../../../constants/pages"; | |||||
| import { replaceInRoute } from "../../../util/helpers/routeHelpers"; | |||||
| import { | |||||
| ADMIN_ITEM_DETAILS_PAGE, | |||||
| ADMIN_SINGLE_USER_PAGE, | |||||
| BASE_PAGE, | |||||
| HOME_PAGE, | |||||
| ITEM_DETAILS_PAGE, | |||||
| PROFILE_PAGE, | |||||
| } from "../../../constants/pages"; | |||||
| import { dynamicRouteMatches, replaceInRoute } from "../../../util/helpers/routeHelpers"; | |||||
| import { selectIsLoadingByActionType } from "../../../store/selectors/loadingSelectors"; | import { selectIsLoadingByActionType } from "../../../store/selectors/loadingSelectors"; | ||||
| import { | import { | ||||
| OFFER_ADD_SCOPE, | OFFER_ADD_SCOPE, | ||||
| OFFER_EDIT_SCOPE, | OFFER_EDIT_SCOPE, | ||||
| } from "../../../store/actions/offers/offersActionConstants"; | } from "../../../store/actions/offers/offersActionConstants"; | ||||
| import { closeModal } from "../../../store/actions/modal/modalActions"; | import { closeModal } from "../../../store/actions/modal/modalActions"; | ||||
| // import { routeMatches } from "../../../util/helpers/routeHelpers"; | |||||
| import { selectQueryString } from "../../../store/selectors/queryStringSelectors"; | |||||
| import { routeMatches } from "../../../util/helpers/routeHelpers"; | |||||
| const CreateOffer = ({ editOffer, offer }) => { | |||||
| const CreateOffer = ({ editOffer, offer, isAdmin, customUserId }) => { | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| // const location = useLocation(); | // const location = useLocation(); | ||||
| const history = useHistory(); | const history = useHistory(); | ||||
| const queryString = useSelector(selectQueryString); | |||||
| const [informations, setInformations] = useState({}); | const [informations, setInformations] = useState({}); | ||||
| const [currentStep, setCurrentStep] = useState(1); | const [currentStep, setCurrentStep] = useState(1); | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const closeCreateOfferModal = () => dispatch(closeModal()); | const closeCreateOfferModal = () => dispatch(closeModal()); | ||||
| const handleApiResponseSuccess = () => { | const handleApiResponseSuccess = () => { | ||||
| // if (routeMatches(BASE_PAGE) || routeMatches(HOME_PAGE)) | |||||
| // dispatch(fetchOffers({ queryString: "" })); | |||||
| // if (location.pathname.includes("profile")) | |||||
| // dispatch(fetchProfileOffers(userId)); | |||||
| // if (location.pathname.includes("proizvodi")) | |||||
| // dispatch(fetchOneOffer(offer._id)); | |||||
| dispatch(fetchProfileOffers(userId)); | |||||
| history.push( | |||||
| replaceInRoute(PROFILE_PAGE, { | |||||
| idProfile: userId, | |||||
| }) | |||||
| ); | |||||
| if (editOffer) { | |||||
| if (routeMatches(BASE_PAGE) || routeMatches(HOME_PAGE)) | |||||
| dispatch(fetchOffers({ queryString })); | |||||
| if (dynamicRouteMatches(PROFILE_PAGE) || dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE)) | |||||
| if (isAdmin) dispatch(fetchProfileOffers(customUserId)); | |||||
| else dispatch(fetchProfileOffers(userId)); | |||||
| if ( | |||||
| dynamicRouteMatches(ITEM_DETAILS_PAGE) || | |||||
| dynamicRouteMatches(ADMIN_ITEM_DETAILS_PAGE) | |||||
| ) | |||||
| dispatch(fetchOneOffer(offer._id)); | |||||
| } else | |||||
| history.push( | |||||
| replaceInRoute(PROFILE_PAGE, { | |||||
| idProfile: userId, | |||||
| }) | |||||
| ); | |||||
| closeCreateOfferModal(); | closeCreateOfferModal(); | ||||
| }; | }; | ||||
| editOneOffer({ | editOneOffer({ | ||||
| offerId: offer._id, | offerId: offer._id, | ||||
| offerData, | offerData, | ||||
| isAdmin, | |||||
| handleApiResponseSuccess, | handleApiResponseSuccess, | ||||
| }) | }) | ||||
| ); | ); | ||||
| closeCreateOfferModal: PropTypes.func, | closeCreateOfferModal: PropTypes.func, | ||||
| editOffer: PropTypes.bool, | editOffer: PropTypes.bool, | ||||
| offer: PropTypes.object, | offer: PropTypes.object, | ||||
| isAdmin: PropTypes.bool, | |||||
| customUserId: PropTypes.string, | |||||
| }; | }; | ||||
| export default CreateOffer; | export default CreateOffer; |
| RemoveIconContainer, | RemoveIconContainer, | ||||
| RemoveIcon, | RemoveIcon, | ||||
| ButtonContainer, | ButtonContainer, | ||||
| PinIconContainer, | |||||
| PinIcon, | |||||
| UnpinIcon, | |||||
| // EditDeleteButtons, | // EditDeleteButtons, | ||||
| } from "./ItemDetailsCard.styled"; | } from "./ItemDetailsCard.styled"; | ||||
| import selectedTheme from "../../../themes"; | import selectedTheme from "../../../themes"; | ||||
| dispatch( | dispatch( | ||||
| toggleDeleteOfferModal({ | toggleDeleteOfferModal({ | ||||
| offer: offer.offer, | offer: offer.offer, | ||||
| isAdmin: props.isAdmin, | |||||
| }) | }) | ||||
| ); | ); | ||||
| }; | }; | ||||
| const showEditOfferModalHandler = () => { | const showEditOfferModalHandler = () => { | ||||
| dispatch(toggleEditOfferModal({ editOffer: true, offer: offer.offer })); | |||||
| dispatch( | |||||
| toggleEditOfferModal({ | |||||
| editOffer: true, | |||||
| offer: offer?.offer, | |||||
| isAdmin: props.isAdmin, | |||||
| customUserId: offer?.offer?.userId | |||||
| }) | |||||
| ); | |||||
| }; | |||||
| const showPinOfferModalHandler = () => { | |||||
| console.log(offer); | |||||
| dispatch( | |||||
| toggleDeleteOfferModal({ | |||||
| offer: offer?.offer, | |||||
| pin: true, | |||||
| pinnedOffer: offer?.offer?.pinned, | |||||
| deleteOffer: false, | |||||
| }) | |||||
| ); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <DateButtonsContainer> | <DateButtonsContainer> | ||||
| {props.isMyOffer && ( | {props.isMyOffer && ( | ||||
| <ButtonsContainer> | <ButtonsContainer> | ||||
| <PinIconContainer onClick={showPinOfferModalHandler}> | |||||
| {offer?.offer?.pinned ? <UnpinIcon /> : <PinIcon />} | |||||
| </PinIconContainer> | |||||
| <EditIconContainer onClick={showEditOfferModalHandler}> | <EditIconContainer onClick={showEditOfferModalHandler}> | ||||
| <EditIcon /> | <EditIcon /> | ||||
| </EditIconContainer> | </EditIconContainer> | ||||
| isMyOffer: PropTypes.bool, | isMyOffer: PropTypes.bool, | ||||
| previewCard: PropTypes.bool, | previewCard: PropTypes.bool, | ||||
| createOffer: PropTypes.bool, | createOffer: PropTypes.bool, | ||||
| isAdmin: PropTypes.bool, | |||||
| }; | }; | ||||
| ItemDetailsCard.defaultProps = { | ItemDetailsCard.defaultProps = { | ||||
| halfwidth: false, | halfwidth: false, | ||||
| sponsored: false, | sponsored: false, | ||||
| showExchangeButton: true, | showExchangeButton: true, | ||||
| isAdmin: false, | |||||
| }; | }; | ||||
| export default ItemDetailsCard; | export default ItemDetailsCard; |
| import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg"; | import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg"; | ||||
| import { IconButton } from "../../Buttons/IconButton/IconButton"; | import { IconButton } from "../../Buttons/IconButton/IconButton"; | ||||
| import { ReactComponent as Edit } from "../../../assets/images/svg/edit.svg"; | 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 Remove } from "../../../assets/images/svg/trash.svg"; | ||||
| export const ItemDetailsCardContainer = styled(Container)` | export const ItemDetailsCardContainer = styled(Container)` | ||||
| border-radius: 100%; | border-radius: 100%; | ||||
| padding-top: 2px; | padding-top: 2px; | ||||
| text-align: center; | text-align: center; | ||||
| margin-left: 18px; | |||||
| /* margin-left: 18px; */ | |||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 32px; | width: 32px; | ||||
| height: 32px; | height: 32px; | ||||
| } | } | ||||
| `; | `; | ||||
| export const RemoveIcon = styled(Remove)` | export const RemoveIcon = styled(Remove)` | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| width: 16px; | width: 16px; | ||||
| left: -2px; | left: -2px; | ||||
| } | } | ||||
| `; | `; | ||||
| export const PinIconContainer = styled(IconButton)` | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| position: relative; | |||||
| top: 4px; | |||||
| background-color: ${selectedTheme.colors.primaryIconBackgroundColor}; | |||||
| border-radius: 100%; | |||||
| padding-top: 2px; | |||||
| text-align: center; | |||||
| /* margin-left: 18px; */ | |||||
| @media screen and (max-width: 600px) { | |||||
| width: 32px; | |||||
| top: 0; | |||||
| height: 32px; | |||||
| } | |||||
| `; | |||||
| export const PinIcon = styled(Pin)` | |||||
| @media screen and (max-width: 600px) { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| position: relative; | |||||
| top: -4px; | |||||
| left: -2px; | |||||
| } | |||||
| `; | |||||
| export const UnpinIcon = styled(Unpin)` | |||||
| @media screen and (max-width: 600px) { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| position: relative; | |||||
| top: -4px; | |||||
| left: -2px; | |||||
| } | |||||
| `; | |||||
| export const DateButtonsContainer = styled(Box)` | export const DateButtonsContainer = styled(Box)` | ||||
| display: flex; | display: flex; |
| import { useDispatch, useSelector } from "react-redux"; | import { useDispatch, useSelector } from "react-redux"; | ||||
| import { | import { | ||||
| fetchOffers, | fetchOffers, | ||||
| fetchOneOffer, | |||||
| fetchProfileOffers, | fetchProfileOffers, | ||||
| pinOffer, | pinOffer, | ||||
| removeOffer, | removeOffer, | ||||
| import CancelButton from "./CancelButton/CancelButton"; | import CancelButton from "./CancelButton/CancelButton"; | ||||
| import SaveButton from "./SaveButton/SaveButton"; | import SaveButton from "./SaveButton/SaveButton"; | ||||
| import { closeModal } from "../../../../store/actions/modal/modalActions"; | import { closeModal } from "../../../../store/actions/modal/modalActions"; | ||||
| import { | |||||
| dynamicRouteMatches, | |||||
| routeMatches, | |||||
| } from "../../../../util/helpers/routeHelpers"; | |||||
| import { | |||||
| ADMIN_ITEM_DETAILS_PAGE, | |||||
| ADMIN_SINGLE_USER_PAGE, | |||||
| BASE_PAGE, | |||||
| HOME_PAGE, | |||||
| ITEM_DETAILS_PAGE, | |||||
| PROFILE_PAGE, | |||||
| } from "../../../../constants/pages"; | |||||
| const DeleteOffer = (props) => { | const DeleteOffer = (props) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| }; | }; | ||||
| const handleApiResponseSuccess = () => { | const handleApiResponseSuccess = () => { | ||||
| dispatch(fetchProfileOffers(userId)); | |||||
| dispatch(fetchOffers({ queryString })); | |||||
| if ( | |||||
| dynamicRouteMatches(PROFILE_PAGE) || | |||||
| dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE) | |||||
| ) | |||||
| dispatch(fetchProfileOffers(userId)); | |||||
| if (routeMatches(HOME_PAGE) || routeMatches(BASE_PAGE)) | |||||
| dispatch(fetchOffers({ queryString })); | |||||
| if ( | |||||
| dynamicRouteMatches(ITEM_DETAILS_PAGE) || | |||||
| dynamicRouteMatches(ADMIN_ITEM_DETAILS_PAGE) | |||||
| ) { | |||||
| if (props.pin) dispatch(fetchOneOffer(props.offer?._id)); | |||||
| else history.goBack(); | |||||
| } | |||||
| }; | }; | ||||
| const removeOfferHandler = () => { | const removeOfferHandler = () => { | ||||
| pinOffer({ offerId: props.offer?._id, handleApiResponseSuccess }) | pinOffer({ offerId: props.offer?._id, handleApiResponseSuccess }) | ||||
| ); | ); | ||||
| } else { | } else { | ||||
| dispatch(removeOffer({ offerId, handleApiResponseSuccess })); | |||||
| dispatch( | |||||
| removeOffer({ | |||||
| offerId, | |||||
| isAdmin: props.isAdmin, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| } | } | ||||
| closeDeleteModalHandler(); | closeDeleteModalHandler(); | ||||
| if (history.location.pathname.includes("proizvodi")) { | if (history.location.pathname.includes("proizvodi")) { | ||||
| pin: PropTypes.bool, | pin: PropTypes.bool, | ||||
| deleteOffer: PropTypes.bool, | deleteOffer: PropTypes.bool, | ||||
| pinnedOffer: PropTypes.bool, | pinnedOffer: PropTypes.bool, | ||||
| isAdmin: PropTypes.bool, | |||||
| }; | |||||
| DeleteOffer.defaultProps = { | |||||
| isAdmin: false, | |||||
| }; | }; | ||||
| export default DeleteOffer; | export default DeleteOffer; |
| } from "../../../store/actions/modal/modalActions"; | } from "../../../store/actions/modal/modalActions"; | ||||
| import { Tooltip } from "@mui/material"; | import { Tooltip } from "@mui/material"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { replaceInRoute } from "../../../util/helpers/routeHelpers"; | |||||
| import { | |||||
| ADMIN_ITEM_DETAILS_PAGE, | |||||
| ITEM_DETAILS_PAGE, | |||||
| } from "../../../constants/pages"; | |||||
| const OfferCard = (props) => { | const OfferCard = (props) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| }; | }; | ||||
| const routeToItem = (itemId) => { | const routeToItem = (itemId) => { | ||||
| if (!props.disabledCheckButton) { | if (!props.disabledCheckButton) { | ||||
| history.push(`/proizvodi/${itemId}`); | |||||
| if (props.isAdmin) { | |||||
| history.push( | |||||
| replaceInRoute(ADMIN_ITEM_DETAILS_PAGE, { | |||||
| idProizvod: itemId, | |||||
| }) | |||||
| ); | |||||
| } else { | |||||
| history.push( | |||||
| replaceInRoute(ITEM_DETAILS_PAGE, { | |||||
| idProizvod: itemId, | |||||
| }) | |||||
| ); | |||||
| } | |||||
| } | } | ||||
| }; | }; | ||||
| const messageUser = (event) => { | const messageUser = (event) => { | ||||
| toggleEditOfferModal({ | toggleEditOfferModal({ | ||||
| editOffer: true, | editOffer: true, | ||||
| offer: props.offer, | offer: props.offer, | ||||
| isAdmin: props.isAdmin, | |||||
| customUserId: props?.offer?.userId, | |||||
| }) | }) | ||||
| ); | ); | ||||
| }; | }; | ||||
| dispatch( | dispatch( | ||||
| toggleDeleteOfferModal({ | toggleDeleteOfferModal({ | ||||
| offer: props.offer, | offer: props.offer, | ||||
| isAdmin: props.isAdmin, | |||||
| }) | }) | ||||
| ); | ); | ||||
| }; | }; |
| selectIsLoadingByActionType(ONE_OFFER_SCOPE) | selectIsLoadingByActionType(ONE_OFFER_SCOPE) | ||||
| ); | ); | ||||
| let isMyProfile = useMemo(() => { | let isMyProfile = useMemo(() => { | ||||
| if (offer?.offer?.userId?.toString() === userId?.toString()) return true; | |||||
| if ( | |||||
| offer?.offer?.userId?.toString() === userId?.toString() || | |||||
| props.isAdmin | |||||
| ) | |||||
| return true; | |||||
| return false; | return false; | ||||
| }, [offer, userId]); | |||||
| }, [offer, userId, props.isAdmin]); | |||||
| return ( | return ( | ||||
| <ItemDetailsContainer> | <ItemDetailsContainer> | ||||
| <OfferIconText>{t("offer.product")}</OfferIconText> | <OfferIconText>{t("offer.product")}</OfferIconText> | ||||
| </OfferIconContainer> | </OfferIconContainer> | ||||
| )} | )} | ||||
| <ItemDetailsCard offer={offer} isMyOffer={isMyProfile} singleOffer /> | |||||
| <ItemDetailsCard offer={offer} isMyOffer={isMyProfile} isAdmin={props.isAdmin} singleOffer /> | |||||
| </> | </> | ||||
| )} | )} | ||||
| </ItemDetailsContainer> | </ItemDetailsContainer> | ||||
| ItemDetails.propTypes = { | ItemDetails.propTypes = { | ||||
| singleOffer: PropTypes.any, | singleOffer: PropTypes.any, | ||||
| isAdmin: PropTypes.bool, | |||||
| }; | }; | ||||
| export default ItemDetails; | export default ItemDetails; |
| ) : ( | ) : ( | ||||
| <Tooltip title={t("messages.tooltip")}> | <Tooltip title={t("messages.tooltip")}> | ||||
| <TooltipInnerContainer> | <TooltipInnerContainer> | ||||
| <MessageIcon onClick={() => messageUser(offer)}> | |||||
| <MessageIcon disabled onClick={() => messageUser(offer)}> | |||||
| <MessageColor /> | <MessageColor /> | ||||
| </MessageIcon> | </MessageIcon> | ||||
| </TooltipInnerContainer> | </TooltipInnerContainer> |
| import { Box, Typography } from "@mui/material"; | import { Box, Typography } from "@mui/material"; | ||||
| import styled from "styled-components"; | |||||
| import styled, { css } from "styled-components"; | |||||
| import selectedTheme from "../../../themes"; | import selectedTheme from "../../../themes"; | ||||
| import { IconButton } from "../../Buttons/IconButton/IconButton"; | import { IconButton } from "../../Buttons/IconButton/IconButton"; | ||||
| import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | ||||
| background-color: ${selectedTheme.colors.primaryPurple}; | background-color: ${selectedTheme.colors.primaryPurple}; | ||||
| border-radius: 100%; | border-radius: 100%; | ||||
| padding-top: 2px; | padding-top: 2px; | ||||
| ${(props) => | |||||
| props.disabled && | |||||
| css` | |||||
| border: 1px solid ${selectedTheme.colors.borderNormal}; | |||||
| background-color: ${selectedTheme.colors.primaryIconBackgroundColor}; | |||||
| & button svg path { | |||||
| stroke: ${selectedTheme.colors.iconStrokePurpleDisabledColor}; | |||||
| padding-top: 1px; | |||||
| } | |||||
| `} | |||||
| text-align: center; | text-align: center; | ||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| width: 32px; | width: 32px; | ||||
| width: 16px; | width: 16px; | ||||
| height: 16px; | height: 16px; | ||||
| position: relative; | position: relative; | ||||
| top: -4px; | |||||
| left: -2px; | |||||
| top: ${(props) => (props.disabled ? "-5px" : "-4px")}; | |||||
| left: ${(props) => (props.disabled ? "-3px" : "-2px")}; | |||||
| } | } | ||||
| } | } | ||||
| `; | `; |
| export const ADMIN_HOME_PAGE = "/admin"; | export const ADMIN_HOME_PAGE = "/admin"; | ||||
| export const ADMIN_USERS_PAGE = "/admin/users"; | export const ADMIN_USERS_PAGE = "/admin/users"; | ||||
| export const ADMIN_SINGLE_USER_PAGE = "/admin/users/:idProfile"; | export const ADMIN_SINGLE_USER_PAGE = "/admin/users/:idProfile"; | ||||
| export const ADMIN_ITEM_DETAILS_PAGE = "/admin/proizvodi/:idProizvod"; | |||||
| export const ADMIN_CATEGORIES_PAGE = "/admin/categories"; | export const ADMIN_CATEGORIES_PAGE = "/admin/categories"; | ||||
| export const ADMIN_LOCATIONS_PAGE = "/admin/locations"; | export const ADMIN_LOCATIONS_PAGE = "/admin/locations"; | ||||
| export const ADMIN_PAYMENT_PAGE = "/admin/payment"; | export const ADMIN_PAYMENT_PAGE = "/admin/payment"; |
| <AdminLayoutContainer className={props.className}> | <AdminLayoutContainer className={props.className}> | ||||
| {props.children} | {props.children} | ||||
| <Grid container maxHeight="xl"> | <Grid container maxHeight="xl"> | ||||
| <LeftCard item xs={0} sm={0} md={3} lg={3} xl={3}> | |||||
| <LeftCard item xs={0} sm={0} md={3} lg={3} xl={2.4}> | |||||
| {props.leftCard} | {props.leftCard} | ||||
| </LeftCard> | </LeftCard> | ||||
| <Content item xs={12} sm={12} md={9} lg={9} xl={9}> | |||||
| <Content item xs={12} sm={12} md={9} lg={9} xl={9.6}> | |||||
| {props.content} | {props.content} | ||||
| </Content> | </Content> | ||||
| </Grid> | </Grid> |
| import { Switch, useHistory } from "react-router-dom"; | import { Switch, useHistory } from "react-router-dom"; | ||||
| import { | import { | ||||
| ADMIN_CATEGORIES_PAGE, | ADMIN_CATEGORIES_PAGE, | ||||
| ADMIN_ITEM_DETAILS_PAGE, | |||||
| ADMIN_LOCATIONS_PAGE, | ADMIN_LOCATIONS_PAGE, | ||||
| ADMIN_PAYMENT_PAGE, | ADMIN_PAYMENT_PAGE, | ||||
| ADMIN_SINGLE_USER_PAGE, | ADMIN_SINGLE_USER_PAGE, | ||||
| import AdminPaymentPage from "./AdminPaymentPage/AdminPaymentPage"; | import AdminPaymentPage from "./AdminPaymentPage/AdminPaymentPage"; | ||||
| import AdminSingleUserPage from "./AdminUsersPage/AdminSingleUserPage/AdminSingleUserPage"; | import AdminSingleUserPage from "./AdminUsersPage/AdminSingleUserPage/AdminSingleUserPage"; | ||||
| import { AdminLayoutHomePage } from "./AdminHomePage.styled"; | import { AdminLayoutHomePage } from "./AdminHomePage.styled"; | ||||
| import AdminItemDetailsPage from "./AdminItemDetailsPage/AdminItemDetailsPage"; | |||||
| const AdminHomePage = () => { | const AdminHomePage = () => { | ||||
| const profile = useSelector(selectMineProfile); | const profile = useSelector(selectMineProfile); | ||||
| component={AdminSingleUserPage} | component={AdminSingleUserPage} | ||||
| /> | /> | ||||
| <AdminRoute | <AdminRoute | ||||
| path={ADMIN_SUBCATEGORIES_PAGE} | |||||
| component={AdminSubcategoriesPage} | |||||
| path={ADMIN_ITEM_DETAILS_PAGE} | |||||
| component={AdminItemDetailsPage} | |||||
| /> | /> | ||||
| <AdminRoute | <AdminRoute | ||||
| path={ADMIN_SUBCATEGORIES_PAGE} | path={ADMIN_SUBCATEGORIES_PAGE} |
| import React from 'react' | |||||
| import PropTypes from 'prop-types' | |||||
| import { useDispatch, useSelector } from 'react-redux'; | |||||
| import { selectOffer } from '../../../store/selectors/offersSelectors'; | |||||
| import { useState } from 'react'; | |||||
| import { useEffect } from 'react'; | |||||
| import { clearSelectedOffer, fetchOneOffer } from '../../../store/actions/offers/offersActions'; | |||||
| import { AdminItemDetailsPageContainer } from './AdminItemDetailsPage.styled'; | |||||
| import ItemDetailsLayout from '../../../layouts/ItemDetailsLayout/ItemDetailsLayout'; | |||||
| import ItemDetails from '../../../components/ItemDetails/ItemDetails'; | |||||
| import ProfileMini from '../../../components/ProfileMini/ProfileMini'; | |||||
| import UserReviews from '../../../components/UserReviews/UserReviews'; | |||||
| const AdminItemDetailsPage = (props) => { | |||||
| const dispatch = useDispatch(); | |||||
| const selectedOffer = useSelector(selectOffer); | |||||
| const [isInitiallyLoaded, setIsInitiallyLoaded] = useState(false); | |||||
| const offerId = props.match.params.idProizvod; | |||||
| useEffect(() => { | |||||
| dispatch(fetchOneOffer(offerId)); | |||||
| () => dispatch(clearSelectedOffer()); | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| if (!selectedOffer?.offer && isInitiallyLoaded) { | |||||
| dispatch(fetchOneOffer(offerId)); | |||||
| } | |||||
| if (selectedOffer?.offer) { | |||||
| setIsInitiallyLoaded(true); | |||||
| } | |||||
| }, [selectedOffer?.offer]); | |||||
| useEffect(() => { | |||||
| window.scrollTo({ top: 0, behaviour: "smooth" }); | |||||
| }, []); | |||||
| return ( | |||||
| <AdminItemDetailsPageContainer> | |||||
| <ItemDetailsLayout | |||||
| singleOffer | |||||
| content={<ItemDetails singleOffer isAdmin />} | |||||
| rightCard={ | |||||
| <> | |||||
| <ProfileMini /> <UserReviews rightReviews /> | |||||
| </> | |||||
| } | |||||
| /> | |||||
| </AdminItemDetailsPageContainer> | |||||
| ); | |||||
| }; | |||||
| AdminItemDetailsPage.propTypes = { | |||||
| match: PropTypes.shape({ | |||||
| params: PropTypes.shape({ | |||||
| idProizvod: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| }; | |||||
| export default AdminItemDetailsPage |
| import styled from "styled-components"; | |||||
| import { Box, Grid } from "@mui/material"; | |||||
| import selectedTheme from "../../../themes"; | |||||
| export const AdminItemDetailsPageContainer = styled(Box)` | |||||
| padding: 0; | |||||
| margin: 0; | |||||
| height: 100%; | |||||
| width: 100%; | |||||
| max-width: none; | |||||
| flex: 1; | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| background-color: ${selectedTheme.colors.offerBackgroundColor}; | |||||
| @media screen and (max-width: 600px) { | |||||
| margin-top: 65px; | |||||
| } | |||||
| `; | |||||
| export const GridStyled = styled(Grid)``; |
| getFeaturedOffers: "offers/featured", | getFeaturedOffers: "offers/featured", | ||||
| addOffer: "/users/{userId}/offers", | addOffer: "/users/{userId}/offers", | ||||
| editOffer: "/users/{userId}/offers/{offerId}", | editOffer: "/users/{userId}/offers/{offerId}", | ||||
| editOfferAsAdmin: "/admin/offers/{offerId}", | |||||
| categories: "categories", | categories: "categories", | ||||
| locations: "locations", | locations: "locations", | ||||
| mineOffers: "users", | mineOffers: "users", | ||||
| removeOffer: "/users/{userId}/offers/{offerId}", | removeOffer: "/users/{userId}/offers/{offerId}", | ||||
| removeOfferAsAdmin: "/admin/offers/{offerId}", | |||||
| pinOffer: "admin/offers/{id}/pin", | pinOffer: "admin/offers/{id}/pin", | ||||
| }, | }, | ||||
| chat: { | chat: { |
| }) | }) | ||||
| ); | ); | ||||
| }; | }; | ||||
| export const attemptRemoveOfferAsAdmin = (offerId) => { | |||||
| return deleteRequest( | |||||
| replaceInUrl(apiEndpoints.offers.removeOfferAsAdmin, { | |||||
| offerId: offerId, | |||||
| }) | |||||
| ); | |||||
| }; | |||||
| export const attemptEditOffer = (payload, offerId, editedData) => { | export const attemptEditOffer = (payload, offerId, editedData) => { | ||||
| return putRequest( | return putRequest( | ||||
| replaceInUrl(apiEndpoints.offers.editOffer, { | replaceInUrl(apiEndpoints.offers.editOffer, { | ||||
| editedData | editedData | ||||
| ); | ); | ||||
| }; | }; | ||||
| export const attemptEditOfferAsAdmin = (offerId, editedData) => { | |||||
| return putRequest( | |||||
| replaceInUrl(apiEndpoints.offers.editOfferAsAdmin, { | |||||
| offerId: offerId, | |||||
| }), | |||||
| editedData | |||||
| ); | |||||
| }; | |||||
| export const attemptPinOffer = (payload) => { | export const attemptPinOffer = (payload) => { | ||||
| return patchRequest( | return patchRequest( | ||||
| replaceInUrl(apiEndpoints.offers.pinOffer, { id: payload }) | replaceInUrl(apiEndpoints.offers.pinOffer, { id: payload }) |
| import { | import { | ||||
| attemptAddOffer, | attemptAddOffer, | ||||
| attemptEditOffer, | attemptEditOffer, | ||||
| attemptEditOfferAsAdmin, | |||||
| attemptFetchFeaturedOffers, | attemptFetchFeaturedOffers, | ||||
| attemptFetchOffers, | attemptFetchOffers, | ||||
| attemptFetchOneOffer, | attemptFetchOneOffer, | ||||
| attemptPinOffer, | attemptPinOffer, | ||||
| attemptRemoveOffer, | attemptRemoveOffer, | ||||
| attemptRemoveOfferAsAdmin, | |||||
| } from "../../request/offersRequest"; | } from "../../request/offersRequest"; | ||||
| import { | import { | ||||
| // OFFERS_ALL_FETCH, | // OFFERS_ALL_FETCH, | ||||
| function* fetchOneOffer(payload) { | function* fetchOneOffer(payload) { | ||||
| try { | try { | ||||
| const data = yield call(attemptFetchOneOffer, payload.payload); | const data = yield call(attemptFetchOneOffer, payload.payload); | ||||
| if (!data?.data) throw new Error() | |||||
| if (!data?.data) throw new Error(); | |||||
| yield put(fetchOneOfferSuccess(data?.data)); | yield put(fetchOneOfferSuccess(data?.data)); | ||||
| } catch (e) { | } catch (e) { | ||||
| console.log(e?.response?.status); | console.log(e?.response?.status); | ||||
| if (!userId || userId?.length === 0) | if (!userId || userId?.length === 0) | ||||
| throw new Error("User id is not defined!"); | throw new Error("User id is not defined!"); | ||||
| const data = yield call(attemptFetchProfileOffers, userId); | const data = yield call(attemptFetchProfileOffers, userId); | ||||
| yield put(setProfileOffers(data.data)); | |||||
| yield put(setProfileOffers(data.data.offers)); | |||||
| yield put(fetchProfileOffersSuccess()); | yield put(fetchProfileOffersSuccess()); | ||||
| } catch (e) { | } catch (e) { | ||||
| console.dir(e); | console.dir(e); | ||||
| try { | try { | ||||
| const userId = yield select(selectUserId); | const userId = yield select(selectUserId); | ||||
| const offerId = payload.payload.offerId; | const offerId = payload.payload.offerId; | ||||
| yield call(attemptRemoveOffer, userId, offerId); | |||||
| if (payload.payload.isAdmin) yield call(attemptRemoveOfferAsAdmin, offerId); | |||||
| else yield call(attemptRemoveOffer, userId, offerId); | |||||
| yield put(removeOfferSuccess()); | yield put(removeOfferSuccess()); | ||||
| if (payload.payload.handleApiResponseSuccess) { | if (payload.payload.handleApiResponseSuccess) { | ||||
| yield call(payload.payload.handleApiResponseSuccess); | yield call(payload.payload.handleApiResponseSuccess); | ||||
| formData.append("location[city]", offerData.location.city); | formData.append("location[city]", offerData.location.city); | ||||
| formData.append("name", offerData.name); | formData.append("name", offerData.name); | ||||
| formData.append("subcategory", offerData.subcategory); | formData.append("subcategory", offerData.subcategory); | ||||
| yield call(attemptEditOffer, userId, offerId, formData); | |||||
| if (payload.payload.isAdmin) { | |||||
| yield call(attemptEditOfferAsAdmin, offerId, formData); | |||||
| } else { | |||||
| yield call(attemptEditOffer, userId, offerId, formData); | |||||
| } | |||||
| yield put(editOfferSuccess()); | yield put(editOfferSuccess()); | ||||
| if (payload.payload.handleApiResponseSuccess) { | if (payload.payload.handleApiResponseSuccess) { | ||||
| yield call(payload.payload.handleApiResponseSuccess); | yield call(payload.payload.handleApiResponseSuccess); |
| import { | import { | ||||
| ADMIN_CATEGORIES_PAGE, | ADMIN_CATEGORIES_PAGE, | ||||
| ADMIN_HOME_PAGE, | ADMIN_HOME_PAGE, | ||||
| ADMIN_ITEM_DETAILS_PAGE, | |||||
| ADMIN_LOCATIONS_PAGE, | ADMIN_LOCATIONS_PAGE, | ||||
| ADMIN_LOGIN_PAGE, | ADMIN_LOGIN_PAGE, | ||||
| ADMIN_PAYMENT_PAGE, | ADMIN_PAYMENT_PAGE, | ||||
| routeMatches(ADMIN_LOCATIONS_PAGE) || | routeMatches(ADMIN_LOCATIONS_PAGE) || | ||||
| routeMatches(ADMIN_PAYMENT_PAGE) || | routeMatches(ADMIN_PAYMENT_PAGE) || | ||||
| dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE) || | dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE) || | ||||
| dynamicRouteMatches(ADMIN_ITEM_DETAILS_PAGE) || | |||||
| isInRoute(ADMIN_HOME_PAGE) | isInRoute(ADMIN_HOME_PAGE) | ||||
| ) | ) | ||||
| return true; | return true; |