Explorar el Código

Merge branch 'feature/1467' of https://git.dilig.net/selenaaasi/trampa-frontend into bugfix/1460

bugfix/1460
jovan.cirkovic hace 3 años
padre
commit
41565e31a1
Se han modificado 29 ficheros con 629 adiciones y 417 borrados
  1. 2
    0
      src/App.js
  2. 7
    1
      src/components/Buttons/IconButton/IconButton.js
  3. 41
    31
      src/components/Cards/CategoryCard/CategoryCard.js
  4. 5
    2
      src/components/Cards/CreateOfferCard/CreateOffer.js
  5. 16
    24
      src/components/Cards/ItemDetailsCard/ItemDetailsCard.js
  6. 4
    3
      src/components/Cards/OfferCard/DeleteOffer/DeleteOffer.js
  7. 35
    48
      src/components/Cards/OfferCard/OfferCard.js
  8. 85
    89
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js
  9. 3
    2
      src/components/Cards/ProfileCard/EditProfile/EditProfile.js
  10. 43
    52
      src/components/Cards/ProfileCard/ProfileCard.js
  11. 19
    22
      src/components/Cards/UserReviewsCard/UserReviewsCard.js
  12. 43
    34
      src/components/CreateReview/CreateReview.js
  13. 16
    32
      src/components/DirectChat/DirectChatHeader/DirectChatHeader.js
  14. 4
    1
      src/components/Header/Drawer/Buttons/AddOfferButton/AddOfferButton.js
  15. 0
    2
      src/components/Header/Drawer/Drawer.js
  16. 0
    1
      src/components/Header/DrawerContainer/DrawerContainer.js
  17. 3
    19
      src/components/Header/Header.js
  18. 7
    7
      src/components/Modals/DeleteCategory/DeleteCategory.js
  19. 8
    5
      src/components/Modals/DeleteReview/DeleteReview.js
  20. 9
    3
      src/components/Modals/EditCategory/EditCategory.js
  21. 52
    0
      src/components/Modals/Modal.js
  22. 12
    12
      src/pages/AdminHomePage/AdminCategoriesPage/AdminCategoriesPage.js
  23. 13
    13
      src/pages/AdminHomePage/AdminLocationsPage/AdminLocationsPage.js
  24. 12
    14
      src/pages/AdminHomePage/AdminSubcategoriesPage/AdminSubcategoriesPage.js
  25. 13
    0
      src/store/actions/modal/modalActionConstants.js
  26. 52
    0
      src/store/actions/modal/modalActions.js
  27. 2
    0
      src/store/reducers/index.js
  28. 116
    0
      src/store/reducers/modal/modalReducer.js
  29. 7
    0
      src/store/selectors/modalSelectors.js

+ 2
- 0
src/App.js Ver fichero

import { socketInit } from "./socket/socket"; import { socketInit } from "./socket/socket";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { selectUserId } from "./store/selectors/loginSelectors"; import { selectUserId } from "./store/selectors/loginSelectors";
import Modal from "./components/Modals/Modal";


const App = () => { const App = () => {
const userId = useSelector(selectUserId); const userId = useSelector(selectUserId);
<StyledEngineProvider injectFirst> <StyledEngineProvider injectFirst>
<Header /> <Header />
<GlobalStyle /> <GlobalStyle />
<Modal />
<ToastContainer bodyClassName="ToastBody" /> <ToastContainer bodyClassName="ToastBody" />
<AppRoutes /> <AppRoutes />
</StyledEngineProvider> </StyledEngineProvider>

+ 7
- 1
src/components/Buttons/IconButton/IconButton.js Ver fichero

import React from "react"; import React from "react";
import { IconButtonContainer, IconButtonStyled } from "./IconButton.styled"; import { IconButtonContainer, IconButtonStyled } from "./IconButton.styled";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { useMemo } from "react";


export const IconButton = (props) => { export const IconButton = (props) => {
const disabled = useMemo(() => {
if (props?.customDisabled) return false;
return props?.disabled;
})
return ( return (
<IconButtonContainer <IconButtonContainer
style={props.containerStyle} style={props.containerStyle}
className={props.className} className={props.className}
> >
<IconButtonStyled <IconButtonStyled
disabled={props.disabled}
disabled={disabled}
onClick={props.onClick} onClick={props.onClick}
sx={props.style} sx={props.style}
iconcolor={props.iconColor} iconcolor={props.iconColor}
className: PropTypes.string, className: PropTypes.string,
iconColor: PropTypes.string, iconColor: PropTypes.string,
disabled: PropTypes.bool, disabled: PropTypes.bool,
customDisabled: PropTypes.bool,
}; };

+ 41
- 31
src/components/Cards/CategoryCard/CategoryCard.js Ver fichero

import CategoryEditButton from "./CategoryEditButton/CategoryEditButton"; import CategoryEditButton from "./CategoryEditButton/CategoryEditButton";
import CategoryRemoveButton from "./CategoryRemoveButton/CategoryRemoveButton"; import CategoryRemoveButton from "./CategoryRemoveButton/CategoryRemoveButton";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useState } from "react";
import DeleteCategory from "../../Modals/DeleteCategory/DeleteCategory";
import EditCategory from "../../Modals/EditCategory/EditCategory";
import history from "../../../store/utils/history"; import history from "../../../store/utils/history";
import { replaceInRoute } from "../../../util/helpers/routeHelpers"; import { replaceInRoute } from "../../../util/helpers/routeHelpers";
import { ADMIN_SUBCATEGORIES_PAGE } from "../../../constants/pages"; import { ADMIN_SUBCATEGORIES_PAGE } from "../../../constants/pages";
import { useMemo } from "react"; import { useMemo } from "react";
import { useDispatch } from "react-redux";
import {
toggleDeleteCategoryModal,
toggleEditCategoryModal,
} from "../../../store/actions/modal/modalActions";


const CategoryCard = (props) => { const CategoryCard = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [openedDeleteModal, setOpenedDeleteModal] = useState(false);
const [openedEditModal, setOpenedEditModal] = useState(false);
const dispatch = useDispatch();
const navigateToCategory = () => { const navigateToCategory = () => {
if (!props.hideCheckButton) { if (!props.hideCheckButton) {
history.push( history.push(
); );
} }
}; };
const showEditCategoryModal = () => {
dispatch(
toggleEditCategoryModal({
hideImagePicker: props.type !== "categories",
category: props.category,
categoryId: props.categoryId,
subcategory: props.subcategory,
type: props.type,
method: "edit",
firstOutlined: false,
})
);
};
const showDeleteCategoryModal = () => {
dispatch(
toggleDeleteCategoryModal({
categoryId: props.categoryId,
subcategory: props.subcategory,
category: props.category,
type: props.type,
})
);
};
const isDisabledDelete = useMemo(() => { const isDisabledDelete = useMemo(() => {
return props?.category?.name === "Ostalo" || props?.category?.city === "Ostalo"
}, [props.category])
return (
props?.category?.name === "Ostalo" || props?.category?.city === "Ostalo"
);
}, [props.category]);
return ( return (
<> <>
<CategoryCardContainer className={props.className}> <CategoryCardContainer className={props.className}>
</CategoryCardDetailsContainer> </CategoryCardDetailsContainer>
</CategoryCardLeftContainer> </CategoryCardLeftContainer>
<CategoryCardRightContainer> <CategoryCardRightContainer>
<CategoryRemoveButton disabled={isDisabledDelete} onClick={() => setOpenedDeleteModal(true)} />
<CategoryEditButton disabled={isDisabledDelete} onClick={() => setOpenedEditModal(true)} />
<CategoryRemoveButton
disabled={isDisabledDelete}
onClick={showDeleteCategoryModal}
/>
<CategoryEditButton
disabled={isDisabledDelete}
onClick={showEditCategoryModal}
/>
{!props.hideCheckButton && ( {!props.hideCheckButton && (
<CategoryCheckButton onClick={navigateToCategory} /> <CategoryCheckButton onClick={navigateToCategory} />
)} )}
</CategoryCardRightContainer> </CategoryCardRightContainer>
</CategoryCardContainer> </CategoryCardContainer>
{openedDeleteModal && (
<DeleteCategory
categoryId={props.categoryId}
setOpenedDeleteModal={setOpenedDeleteModal}
subcategory={props.subcategory}
category={props.category}
type={props.type}
/>
)}
{openedEditModal && (
<EditCategory
hideImagePicker={props.type !== "categories"}
setOpenedEditModal={setOpenedEditModal}
category={props.category}
categoryId={props.categoryId}
subcategory={props.subcategory}
type={props.type}
method="edit"
firstOutlined={false}
// showSecondButton
/>
)}
</> </>
); );
}; };

+ 5
- 2
src/components/Cards/CreateOfferCard/CreateOffer.js Ver fichero

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 { routeMatches } from "../../../util/helpers/routeHelpers"; // import { routeMatches } from "../../../util/helpers/routeHelpers";


const CreateOffer = ({ closeCreateOfferModal, editOffer, offer }) => {
const CreateOffer = ({ editOffer, offer }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
// const location = useLocation(); // const location = useLocation();
const history = useHistory(); const history = useHistory();
selectIsLoadingByActionType(editOffer ? OFFER_EDIT_SCOPE : OFFER_ADD_SCOPE) selectIsLoadingByActionType(editOffer ? OFFER_EDIT_SCOPE : OFFER_ADD_SCOPE)
); );


const closeCreateOfferModal = () => dispatch(closeModal());

const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
// if (routeMatches(BASE_PAGE) || routeMatches(HOME_PAGE)) // if (routeMatches(BASE_PAGE) || routeMatches(HOME_PAGE))
// dispatch(fetchOffers({ queryString: "" })); // dispatch(fetchOffers({ queryString: "" }));
idProfile: userId, idProfile: userId,
}) })
); );
closeCreateOfferModal(false);
closeCreateOfferModal();
}; };


// Go to next step and save typed values // Go to next step and save typed values

+ 16
- 24
src/components/Cards/ItemDetailsCard/ItemDetailsCard.js Ver fichero

import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
CheckButton, CheckButton,
import { startChat } from "../../../util/helpers/chatHelper"; import { startChat } from "../../../util/helpers/chatHelper";
import Information from "./Information/Information"; import Information from "./Information/Information";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import DeleteOffer from "../OfferCard/DeleteOffer/DeleteOffer";
import CreateOffer from "../CreateOfferCard/CreateOffer";
import OfferDetails from "./OfferDetails/OfferDetails"; import OfferDetails from "./OfferDetails/OfferDetails";
import { useRouteMatch } from "react-router-dom"; import { useRouteMatch } from "react-router-dom";
import itemDetailsData from "../../../notFoundData/itemDetailsData"; import itemDetailsData from "../../../notFoundData/itemDetailsData";
import {
toggleDeleteOfferModal,
toggleEditOfferModal,
} from "../../../store/actions/modal/modalActions";


const ItemDetailsCard = (props) => { 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 routeMatch = useRouteMatch();
const chats = useSelector(selectLatestChats); const chats = useSelector(selectLatestChats);
startChat(chats, offer?.offer, userId); startChat(chats, offer?.offer, userId);
}; };


const closeEditModalHandler = () => {
setShowModalEdit(false);
const showDeleteOfferModalHandler = () => {
dispatch(
toggleDeleteOfferModal({
offer: offer.offer,
})
);
}; };


const closeRemoveModalHandler = () => {
setShowModalRemove(false);
const showEditOfferModalHandler = () => {
dispatch(toggleEditOfferModal({ editOffer: true, offer: offer.offer }));
}; };

return ( return (
<> <>
<ItemDetailsCardContainer <ItemDetailsCardContainer
<DateButtonsContainer> <DateButtonsContainer>
{props.isMyOffer && ( {props.isMyOffer && (
<ButtonsContainer> <ButtonsContainer>
<EditIconContainer onClick={() => setShowModalEdit(true)}>
<EditIconContainer onClick={showEditOfferModalHandler}>
<EditIcon /> <EditIcon />
</EditIconContainer> </EditIconContainer>
<RemoveIconContainer onClick={() => setShowModalRemove(true)}>
<RemoveIconContainer onClick={showDeleteOfferModalHandler}>
<RemoveIcon /> <RemoveIcon />
</RemoveIconContainer> </RemoveIconContainer>
</ButtonsContainer> </ButtonsContainer>
</ButtonContainer> </ButtonContainer>
)} )}
</ItemDetailsCardContainer> </ItemDetailsCardContainer>
{showModalRemove && (
<DeleteOffer
offer={offer.offer}
closeModalHandler={closeRemoveModalHandler}
/>
)}
{showModalEdit && (
<CreateOffer
editOffer
offer={offer.offer}
closeCreateOfferModal={closeEditModalHandler}
/>
)}
</> </>
); );
}; };

+ 4
- 3
src/components/Cards/OfferCard/DeleteOffer/DeleteOffer.js Ver fichero

import OfferDescription from "./OfferDescription/OfferDescription"; import OfferDescription from "./OfferDescription/OfferDescription";
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";


const DeleteOffer = (props) => { const DeleteOffer = (props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { isMobile } = useIsMobile(); const { isMobile } = useIsMobile();
const offerId = props.offer._id; const offerId = props.offer._id;
const closeDeleteModalHandler = () => { const closeDeleteModalHandler = () => {
props.closeModalHandler();
dispatch(closeModal());
}; };


const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
const removeOfferHandler = () => { const removeOfferHandler = () => {
if (props.pin) dispatch(pinOffer({ offerId: props.offer?._id, handleApiResponseSuccess })); if (props.pin) dispatch(pinOffer({ offerId: props.offer?._id, handleApiResponseSuccess }));
else dispatch(removeOffer({ offerId, handleApiResponseSuccess })); else dispatch(removeOffer({ offerId, handleApiResponseSuccess }));
props.closeModalHandler();
closeDeleteModalHandler();
if (history.location.pathname.includes("proizvodi")) { if (history.location.pathname.includes("proizvodi")) {
history.goBack(); history.goBack();
} }
}; };


DeleteOffer.propTypes = { DeleteOffer.propTypes = {
offer: PropTypes.node,
offer: PropTypes.any,
closeModalHandler: PropTypes.func, closeModalHandler: PropTypes.func,
pin: PropTypes.bool, pin: PropTypes.bool,
}; };

+ 35
- 48
src/components/Cards/OfferCard/OfferCard.js Ver fichero

import React, { useMemo, useState } from "react";
import React, { useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
DetailIcon, DetailIcon,
PinOutlinedIcon, PinOutlinedIcon,
ButtonsContainer, ButtonsContainer,
} from "./OfferCard.styled"; } from "./OfferCard.styled";
import DeleteOffer from "./DeleteOffer/DeleteOffer";
import { ReactComponent as Message } from "../../../assets/images/svg/mail.svg"; import { ReactComponent as Message } from "../../../assets/images/svg/mail.svg";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import CreateOffer from "../CreateOfferCard/CreateOffer";
import { useSelector } from "react-redux";
import { useDispatch, useSelector } from "react-redux";
import { selectUserId } from "../../../store/selectors/loginSelectors"; import { selectUserId } from "../../../store/selectors/loginSelectors";
import useIsMobile from "../../../hooks/useIsMobile"; import useIsMobile from "../../../hooks/useIsMobile";
import { getImageUrl, variants } from "../../../util/helpers/imageUrlGetter"; import { getImageUrl, variants } from "../../../util/helpers/imageUrlGetter";
import OfferDescription from "./OfferDescription/OfferDescription"; import OfferDescription from "./OfferDescription/OfferDescription";
import CheckButton from "./CheckButton/CheckButton"; import CheckButton from "./CheckButton/CheckButton";
import { formatDateLocale } from "../../../util/helpers/dateHelpers"; import { formatDateLocale } from "../../../util/helpers/dateHelpers";
import {
toggleDeleteOfferModal,
toggleEditOfferModal,
} from "../../../store/actions/modal/modalActions";


const OfferCard = (props) => { const OfferCard = (props) => {
const [deleteOfferModal, setDeleteOfferModal] = useState(false);
const [editOfferModal, setEditOfferModal] = useState(false);
const [pinOfferModal, setPinOfferModal] = useState(false);
const dispatch = useDispatch();
const history = useHistory(); const history = useHistory();
const userId = useSelector(selectUserId); const userId = useSelector(selectUserId);
const { isMobile } = useIsMobile(); const { isMobile } = useIsMobile();


const pinOffer = (event) => { const pinOffer = (event) => {
event.stopPropagation(); event.stopPropagation();
setPinOfferModal(true);
dispatch(
toggleDeleteOfferModal({
offer: props.offer,
pin: true,
})
);
}; };
const routeToItem = (itemId) => { const routeToItem = (itemId) => {
if (!props.disabledCheckButton) { if (!props.disabledCheckButton) {
props.messageUser(props.offer); props.messageUser(props.offer);
}; };
const makeReview = (event) => { const makeReview = (event) => {
console.log("EVEEEEEEENT: ", event);
event.stopPropagation(); event.stopPropagation();
if (!props.disabledReviews) { if (!props.disabledReviews) {
props.makeReview(props.offer); props.makeReview(props.offer);
}; };
const openEditOfferModal = (event) => { const openEditOfferModal = (event) => {
event.stopPropagation(); event.stopPropagation();
setEditOfferModal(true);
dispatch(
toggleEditOfferModal({
editOffer: true,
offer: props.offer,
})
);
}; };
const openRemoveModal = (event) => { const openRemoveModal = (event) => {
event.stopPropagation(); event.stopPropagation();
setDeleteOfferModal(true);
};

const closeModalHandler = () => {
setDeleteOfferModal(false);
};
const closePinOfferModal = () => {
setPinOfferModal(false);
};

const closeCreateOfferModal = () => {
setEditOfferModal(false);
dispatch(
toggleDeleteOfferModal({
offer: props.offer,
})
);
}; };


const showMessageIcon = useMemo(() => { const showMessageIcon = useMemo(() => {
return true; return true;
}, [userId, props.offer]); }, [userId, props.offer]);


if (deleteOfferModal || editOfferModal) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}

return ( return (
<React.Fragment> <React.Fragment>
<OfferCardContainer <OfferCardContainer
<OfferTitleAboveImage <OfferTitleAboveImage
vertical={props.vertical} vertical={props.vertical}
noOfButtons={ noOfButtons={
props.isAdmin ? 3 : props.isMyOffer ? (props?.offer?.pinned ? 3 : 2) : (props?.offer?.pinned ? 2 : 1)
props.isAdmin
? 3
: props.isMyOffer
? props?.offer?.pinned
? 3
: 2
: props?.offer?.pinned
? 2
: 1
} }
onClick={() => routeToItem(props?.offer?._id)} onClick={() => routeToItem(props?.offer?._id)}
> >
</> </>
) : props.aboveChat ? ( ) : props.aboveChat ? (
<LikeIconContainer <LikeIconContainer
customDisabled={props.disabledReviews}
disabled={props.disabledReviews} disabled={props.disabledReviews}
onClick={makeReview} onClick={makeReview}
> >
</ButtonsContainer> </ButtonsContainer>
</OfferFlexContainer> </OfferFlexContainer>
</OfferCardContainer> </OfferCardContainer>
{deleteOfferModal && (
<DeleteOffer
offer={props.offer}
closeModalHandler={closeModalHandler}
/>
)}
{pinOfferModal && (
<DeleteOffer
pin
offer={props.offer}
closeModalHandler={closePinOfferModal}
/>
)}
{editOfferModal && (
<CreateOffer
editOffer
closeCreateOfferModal={closeCreateOfferModal}
offer={props.offer}
/>
)}
</React.Fragment> </React.Fragment>
); );
}; };

+ 85
- 89
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js Ver fichero

import React, { useState } from "react";
import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
BlockIcon, BlockIcon,
} from "./BigProfileCard.styled"; } from "./BigProfileCard.styled";
import ProfileMainInfo from "../ProfileMainInfo/ProfileMainInfo"; import ProfileMainInfo from "../ProfileMainInfo/ProfileMainInfo";
import ProfileContact from "../ProfileContact/ProfileContact"; import ProfileContact from "../ProfileContact/ProfileContact";
import EditProfile from "../EditProfile/EditProfile";
import selectedTheme from "../../../../themes"; import selectedTheme from "../../../../themes";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import history from "../../../../store/utils/history"; import history from "../../../../store/utils/history";
import { replaceInRoute } from "../../../../util/helpers/routeHelpers"; import { replaceInRoute } from "../../../../util/helpers/routeHelpers";
import { ADMIN_SINGLE_USER_PAGE } from "../../../../constants/pages"; import { ADMIN_SINGLE_USER_PAGE } from "../../../../constants/pages";
import DeleteCategory from "../../../Modals/DeleteCategory/DeleteCategory";
import UserLabeledCard from "../../LabeledCard/User/UserLabeledCard"; import UserLabeledCard from "../../LabeledCard/User/UserLabeledCard";
import { USERS_BLOCK_TYPE, USERS_DELETE_TYPE, USERS_UNBLOCK_TYPE } from "../../../../constants/adminTypeConstants";
import {
USERS_BLOCK_TYPE,
USERS_DELETE_TYPE,
USERS_UNBLOCK_TYPE,
} from "../../../../constants/adminTypeConstants";
import { useDispatch } from "react-redux";
import {
toggleDeleteCategoryModal,
toggleEditProfileModal,
} from "../../../../store/actions/modal/modalActions";


const BigProfileCard = (props) => { const BigProfileCard = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [editProfileModal, setEditProfileModal] = useState(false);
const [deleteOrEditModal, setDeleteOrEditModal] = useState({
show: false,
type: "",
});
const closeModalHandler = () => {
if (editProfileModal) setEditProfileModal(false);
else setDeleteOrEditModal({ show: false, type: "" });
};
const dispatch = useDispatch();
const removeUser = () => { const removeUser = () => {
setDeleteOrEditModal({
show: true,
type: USERS_DELETE_TYPE,
});
dispatch(
toggleDeleteCategoryModal({
customId: props.profile._id,
type: USERS_DELETE_TYPE,
customLabeledCard: <UserLabeledCard user={props.profile} />,
customLabeledCardHeight: "90px",
})
);
}; };
const blockUser = () => { const blockUser = () => {
setDeleteOrEditModal({
show: true,
type: USERS_BLOCK_TYPE,
});
dispatch(
toggleDeleteCategoryModal({
customId: props.profile._id,
type: USERS_BLOCK_TYPE,
customLabeledCard: <UserLabeledCard user={props.profile} />,
customLabeledCardHeight: "90px",
customLabeledCardIcon: <BlockLabelIcon />,
})
);
}; };
const unblockUser = () => { const unblockUser = () => {
setDeleteOrEditModal({
show: true,
type: USERS_UNBLOCK_TYPE,
});
dispatch(
toggleDeleteCategoryModal({
customId: props.profile._id,
type: USERS_UNBLOCK_TYPE,
customLabeledCard: <UserLabeledCard user={props.profile} />,
customLabeledCardHeight: "90px",
customLabeledCardIcon: <UnblockLabelIcon />,
})
);
};
const editUser = () => {
dispatch(
toggleEditProfileModal({
profile: props.profile,
reFetchProfile: () => {},
isAdmin: true,
userId: props.profile._id,
})
);
}; };
const goToUser = () => { const goToUser = () => {
history.push( history.push(
); );
}; };
return ( return (
<>
<ProfileCardContainer halfwidth={props.halfwidth}>
<ProfileCardWrapper variant="outlined">
<ButtonsContainer>
<EditButton onClick={() => setEditProfileModal(true)}>
<EditIcon />
</EditButton>
<RemoveIconContainer onClick={removeUser}>
<RemoveIcon />
</RemoveIconContainer>
{props.profile?._blocked ? (
<UnblockIconContainer onClick={unblockUser}>
<UnblockIcon />
</UnblockIconContainer>
) : (
<BlockIconContainer onClick={blockUser}>
<BlockIcon />
</BlockIconContainer>
)}
</ButtonsContainer>
<ProfileInfoContainer>
{/* Profile Main Info */}
<ProfileMainInfo profile={props.profile} isAdmin bigProfileCard />
{/* Profile Contact */}
<ProfileContact profile={props.profile} isAdmin />
</ProfileInfoContainer>
<CheckButton
halfwidth={props.halfwidth}
variant={"outlined"}
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={selectedTheme.colors.primaryPurple}
style={{ fontWeight: "600" }}
onClick={goToUser}
>
{t("admin.users.checkProfile")}
</CheckButton>
</ProfileCardWrapper>
</ProfileCardContainer>
{editProfileModal && (
<EditProfile
profile={props.profile}
closeModalHandler={closeModalHandler}
reFetchProfile={() => {}}
isAdmin
userId={props.profile._id}
/>
)}
{deleteOrEditModal.show && (
<DeleteCategory
customId={props.profile._id}
setOpenedDeleteModal={closeModalHandler}
type={deleteOrEditModal.type}
customLabeledCard={<UserLabeledCard user={props.profile} />}
customLabeledCardHeight="90px"
customLabeledCardIcon={
deleteOrEditModal.type === "blockUser" ? (
<BlockLabelIcon />
) : (
<UnblockLabelIcon />
)
}
/>
)}
</>
<ProfileCardContainer halfwidth={props.halfwidth}>
<ProfileCardWrapper variant="outlined">
<ButtonsContainer>
<EditButton onClick={editUser}>
<EditIcon />
</EditButton>
<RemoveIconContainer onClick={removeUser}>
<RemoveIcon />
</RemoveIconContainer>
{props.profile?._blocked ? (
<UnblockIconContainer onClick={unblockUser}>
<UnblockIcon />
</UnblockIconContainer>
) : (
<BlockIconContainer onClick={blockUser}>
<BlockIcon />
</BlockIconContainer>
)}
</ButtonsContainer>
<ProfileInfoContainer>
{/* Profile Main Info */}
<ProfileMainInfo profile={props.profile} isAdmin bigProfileCard />
{/* Profile Contact */}
<ProfileContact profile={props.profile} isAdmin />
</ProfileInfoContainer>
<CheckButton
halfwidth={props.halfwidth}
variant={"outlined"}
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={selectedTheme.colors.primaryPurple}
style={{ fontWeight: "600" }}
onClick={goToUser}
>
{t("admin.users.checkProfile")}
</CheckButton>
</ProfileCardWrapper>
</ProfileCardContainer>
); );
}; };



+ 3
- 2
src/components/Cards/ProfileCard/EditProfile/EditProfile.js Ver fichero

} from "../../../../constants/pages"; } from "../../../../constants/pages";
import { selectIsLoadingByActionType } from "../../../../store/selectors/loadingSelectors"; import { selectIsLoadingByActionType } from "../../../../store/selectors/loadingSelectors";
import { PROFILE_EDIT_ADMIN_SCOPE, PROFILE_EDIT_SCOPE } from "../../../../store/actions/profile/profileActionConstants"; import { PROFILE_EDIT_ADMIN_SCOPE, PROFILE_EDIT_SCOPE } from "../../../../store/actions/profile/profileActionConstants";
import { closeModal } from "../../../../store/actions/modal/modalActions";


const EditProfile = (props) => { const EditProfile = (props) => {
const [profileImage, setProfileImage] = useState(props.profile.image); const [profileImage, setProfileImage] = useState(props.profile.image);
if (routeMatches(ADMIN_USERS_PAGE) || routeMatches(ADMIN_HOME_PAGE)) if (routeMatches(ADMIN_USERS_PAGE) || routeMatches(ADMIN_HOME_PAGE))
dispatch(fetchAllProfilesAsAdmin()); dispatch(fetchAllProfilesAsAdmin());
props.reFetchProfile(); props.reFetchProfile();
props.closeModalHandler();
closeEditModalHandler();
}; };


const handleSubmit = (values) => { const handleSubmit = (values) => {
}); });


const closeEditModalHandler = () => { const closeEditModalHandler = () => {
props.closeModalHandler();
dispatch(closeModal());
}; };


const showDetailsHandler = () => { const showDetailsHandler = () => {

+ 43
- 52
src/components/Cards/ProfileCard/ProfileCard.js Ver fichero

import { useEffect } from "react"; import { useEffect } from "react";
import { selectProfile } from "../../../store/selectors/profileSelectors"; import { selectProfile } from "../../../store/selectors/profileSelectors";
import { selectUserId } from "../../../store/selectors/loginSelectors"; import { selectUserId } from "../../../store/selectors/loginSelectors";
import { useState } from "react";
import { fetchProfileOffers } from "../../../store/actions/offers/offersActions"; import { fetchProfileOffers } from "../../../store/actions/offers/offersActions";
import EditProfile from "./EditProfile/EditProfile";
import ProfileMainInfo from "./ProfileMainInfo/ProfileMainInfo"; import ProfileMainInfo from "./ProfileMainInfo/ProfileMainInfo";
import ProfileContact from "./ProfileContact/ProfileContact"; import ProfileContact from "./ProfileContact/ProfileContact";
import ProfileStats from "./ProfileStats/ProfileStats"; import ProfileStats from "./ProfileStats/ProfileStats";
import SkeletonProfileCard from "./SkeletonProfileCard/SkeletonProfileCard"; import SkeletonProfileCard from "./SkeletonProfileCard/SkeletonProfileCard";
import { useMemo } from "react"; import { useMemo } from "react";
import companyData from "../../../notFoundData/companyData"; import companyData from "../../../notFoundData/companyData";
import DeleteCategory from "../../Modals/DeleteCategory/DeleteCategory";
import UserLabeledCard from "../LabeledCard/User/UserLabeledCard"; import UserLabeledCard from "../LabeledCard/User/UserLabeledCard";
import history from "../../../store/utils/history"; import history from "../../../store/utils/history";
import { HOME_PAGE } from "../../../constants/pages"; import { HOME_PAGE } from "../../../constants/pages";
import useIsMobile from "../../../hooks/useIsMobile"; import useIsMobile from "../../../hooks/useIsMobile";
import BlockedProfile from "./BlockedProfile/BlockedProfile"; import BlockedProfile from "./BlockedProfile/BlockedProfile";
import {
toggleDeleteCategoryModal,
toggleEditProfileModal,
} from "../../../store/actions/modal/modalActions";
import {
USERS_BLOCK_TYPE,
USERS_DELETE_TYPE,
USERS_UNBLOCK_TYPE,
} from "../../../constants/adminTypeConstants";


const ProfileCard = (props) => { const ProfileCard = (props) => {
const [editProfileModal, setEditProfileModal] = useState(false);
const [deleteOrEditModal, setDeleteOrEditModal] = useState({
show: false,
type: "",
});
const isLoading = useSelector(selectIsLoadingByActionType(PROFILE_SCOPE)); const isLoading = useSelector(selectIsLoadingByActionType(PROFILE_SCOPE));
const routeMatch = useRouteMatch(); const routeMatch = useRouteMatch();
const dispatch = useDispatch(); const dispatch = useDispatch();
100 100
); );
} }

const closeModalHandler = () => {
if (editProfileModal) setEditProfileModal(false);
else setDeleteOrEditModal({ show: false, type: "" });
};
const removeUser = () => { const removeUser = () => {
setDeleteOrEditModal({
show: true,
type: "deleteUser",
});
dispatch(
toggleDeleteCategoryModal({
customId: profile?._id,
type: USERS_DELETE_TYPE,
customLabeledCard: <UserLabeledCard user={profile} />,
customLabeledCardHeight: "90px",
})
);
}; };
const blockUser = () => { const blockUser = () => {
setDeleteOrEditModal({
show: true,
type: "blockUser",
});
dispatch(
toggleDeleteCategoryModal({
customId: profile?._id,
type: USERS_BLOCK_TYPE,
customLabeledCard: <UserLabeledCard user={profile} />,
customLabeledCardHeight: "90px",
customLabeledCardIcon: <BlockLabelIcon />,
})
);
}; };
const unblockUser = () => { const unblockUser = () => {
setDeleteOrEditModal({
show: true,
type: "unblockUser",
});
dispatch(
toggleDeleteCategoryModal({
customId: profile?._id,
type: USERS_UNBLOCK_TYPE,
customLabeledCard: <UserLabeledCard user={profile} />,
customLabeledCardHeight: "90px",
})
);
}; };
const handleEditProfile = () => { const handleEditProfile = () => {
if (!profile?._blocked) setEditProfileModal(true);
if (!profile?._blocked) {
dispatch(
toggleEditProfileModal({
profile: profile,
isAdmin: props.isAdmin,
reFetchProfile: reFetchProfile,
})
);
}
}; };


if (editProfileModal) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}

return ( return (
<> <>
{isLoading ? ( {isLoading ? (
</ProfileCardContainer> </ProfileCardContainer>
</> </>
)} )}
{editProfileModal && (
<EditProfile
profile={profile}
isAdmin={props.isAdmin}
closeModalHandler={closeModalHandler}
reFetchProfile={reFetchProfile}
/>
)}
{deleteOrEditModal.show && (
<DeleteCategory
customId={profile?._id}
setOpenedDeleteModal={closeModalHandler}
type={deleteOrEditModal.type}
customLabeledCard={<UserLabeledCard user={profile} />}
customLabeledCardHeight="90px"
customLabeledCardIcon={
deleteOrEditModal.type === "blockUser" && <BlockLabelIcon />
}
/>
)}
</> </>
); );
}; };

+ 19
- 22
src/components/Cards/UserReviewsCard/UserReviewsCard.js Ver fichero

import React, { useMemo, useState } from "react";
import React, { useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { reviewEnum } from "../../../enums/reviewEnum"; import { reviewEnum } from "../../../enums/reviewEnum";
import UserReviewsSingleCard from "./UserReviewsSingleCard/UserReviewsSingleCard"; import UserReviewsSingleCard from "./UserReviewsSingleCard/UserReviewsSingleCard";
import DeleteReview from "../../Modals/DeleteReview/DeleteReview";
import { useDispatch } from "react-redux";
import { toggleDeleteReviewModal } from "../../../store/actions/modal/modalActions";


const UserReviewsCard = (props) => { const UserReviewsCard = (props) => {
const [removeModalOpened, setRemoveModalOpened] = useState();
const handleRemove = () => {
setRemoveModalOpened(true);
};
const dispatch = useDispatch();
const review = useMemo(() => { const review = useMemo(() => {
if (props.givingReview) { if (props.givingReview) {
return { return {
props?.review?.reviewAdditionalData?.userWhoReceived?.company?.name, props?.review?.reviewAdditionalData?.userWhoReceived?.company?.name,
}; };
}, [props.review]); }, [props.review]);
const handleRemove = () => {
dispatch(
toggleDeleteReviewModal({
review: review,
})
);
};
return ( return (
<>
<UserReviewsSingleCard
review={review}
showRemoveIcon={props.showRemoveIcon}
handleRemove={handleRemove}
hasGivenReview={props.hasGivenReview}
rightReviews={props.rightReviews}
isAdmin={props.isAdmin}
/>
{removeModalOpened && (
<DeleteReview
review={review}
setOpenedDeleteModal={setRemoveModalOpened}
/>
)}
</>
<UserReviewsSingleCard
review={review}
showRemoveIcon={props.showRemoveIcon}
handleRemove={handleRemove}
hasGivenReview={props.hasGivenReview}
rightReviews={props.rightReviews}
isAdmin={props.isAdmin}
/>
); );
}; };



+ 43
- 34
src/components/CreateReview/CreateReview.js Ver fichero

} from "./CreateReview.styled"; } from "./CreateReview.styled";
import FirstStepCreateReview from "./FirstStep/FirstStepCreateReview"; import FirstStepCreateReview from "./FirstStep/FirstStepCreateReview";
import SecondStepCreateReview from "./SecondStep/SecondStepCreateReview"; import SecondStepCreateReview from "./SecondStep/SecondStepCreateReview";
import ThirdStepCreateReview from "./ThirdStep/ThirdStepCreateReview";
import ThirdStepCreateReview from "./ThirdStep/ThirdStepCreateReview";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { giveReview } from "../../store/actions/review/reviewActions"; import { giveReview } from "../../store/actions/review/reviewActions";
import { selectUserId } from "../../store/selectors/loginSelectors"; import { selectUserId } from "../../store/selectors/loginSelectors";
import { reviewEnum } from "../../enums/reviewEnum"; import { reviewEnum } from "../../enums/reviewEnum";
import { fetchExchange } from "../../store/actions/exchange/exchangeActions";
import { closeModal } from "../../store/actions/modal/modalActions";
import BackdropComponent from "../MUI/BackdropComponent";


const CreateReview = (props) => { const CreateReview = (props) => {
const offer = props.offer; const offer = props.offer;
const [currentStep, setCurrentStep] = useState(1); const [currentStep, setCurrentStep] = useState(1);
const dispatch = useDispatch(); const dispatch = useDispatch();
const userId = useSelector(selectUserId); const userId = useSelector(selectUserId);
const closeModal = () => {
props.closeModal();
const closeModalHandler = () => {
dispatch(closeModal());
}; };
const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
props.handleGiveReviewSuccess();
dispatch(fetchExchange(props.exchange._id));
}; };
const submitForm = () => { const submitForm = () => {
let communication = "yes"; let communication = "yes";
}; };
}); });
if (currentStep === 3) { if (currentStep === 3) {
closeModal();
closeModalHandler();
} else { } else {
if (currentStep === 2) { if (currentStep === 2) {
submitForm(); submitForm();
} }
}; };
const goToPrevStep = () => { const goToPrevStep = () => {
setCurrentStep(prevCurrentStep => prevCurrentStep - 1);
setCurrentStep((prevCurrentStep) => prevCurrentStep - 1);
}; };
return ( return (
<CreateReviewContainer currentStep={currentStep}>
<CloseButton onClick={closeModal}>
<CloseIcon />
</CloseButton>
{currentStep === 2 && (
<BackIcon onClick={goToPrevStep}>
<ArrowBackIcon />
</BackIcon>
)}
{currentStep === 1 && (
<FirstStepCreateReview
offer={offer}
interlocutor={props.interlocutor}
informations={informations}
goToNextStep={goToNextStep}
/>
)}
{currentStep === 2 && (
<SecondStepCreateReview
review={informations}
offer={offer}
interlocutor={props.interlocutor}
goToNextStep={goToNextStep}
/>
)}
{currentStep === 3 && <ThirdStepCreateReview />}
</CreateReviewContainer>
<>
<BackdropComponent
isLoading
handleClose={closeModalHandler}
position="fixed"
/>
<CreateReviewContainer currentStep={currentStep}>
<CloseButton onClick={closeModalHandler}>
<CloseIcon />
</CloseButton>
{currentStep === 2 && (
<BackIcon onClick={goToPrevStep}>
<ArrowBackIcon />
</BackIcon>
)}
{currentStep === 1 && (
<FirstStepCreateReview
offer={offer}
interlocutor={props.interlocutor}
informations={informations}
goToNextStep={goToNextStep}
/>
)}
{currentStep === 2 && (
<SecondStepCreateReview
review={informations}
offer={offer}
interlocutor={props.interlocutor}
goToNextStep={goToNextStep}
/>
)}
{currentStep === 3 && <ThirdStepCreateReview />}
</CreateReviewContainer>
</>
); );
}; };


children: PropTypes.node, children: PropTypes.node,
offer: PropTypes.any, offer: PropTypes.any,
interlocutor: PropTypes.any, interlocutor: PropTypes.any,
closeModal: PropTypes.func,
exchange: PropTypes.any, exchange: PropTypes.any,
handleGiveReviewSuccess: PropTypes.func, handleGiveReviewSuccess: PropTypes.func,
}; };

+ 16
- 32
src/components/DirectChat/DirectChatHeader/DirectChatHeader.js Ver fichero

import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { DirectChatHeaderContainer } from "./DirectChatHeader.styled"; import { DirectChatHeaderContainer } from "./DirectChatHeader.styled";
import OfferCard from "../../Cards/OfferCard/OfferCard"; import OfferCard from "../../Cards/OfferCard/OfferCard";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { fetchExchange } from "../../../store/actions/exchange/exchangeActions"; import { fetchExchange } from "../../../store/actions/exchange/exchangeActions";
import { selectSelectedChat } from "../../../store/selectors/chatSelectors"; import { selectSelectedChat } from "../../../store/selectors/chatSelectors";
import BackdropComponent from "../../MUI/BackdropComponent";
import CreateReview from "../../CreateReview/CreateReview";
import { selectUserId } from "../../../store/selectors/loginSelectors"; import { selectUserId } from "../../../store/selectors/loginSelectors";
import { toggleCreateReviewModal } from "../../../store/actions/modal/modalActions";


const DirectChatHeader = (props) => { const DirectChatHeader = (props) => {
const exchange = useSelector(selectExchange); const exchange = useSelector(selectExchange);
const userId = useSelector(selectUserId); const userId = useSelector(selectUserId);
const dispatch = useDispatch(); const dispatch = useDispatch();
const chat = useSelector(selectSelectedChat); const chat = useSelector(selectSelectedChat);
const [showReviewModal, setShowReviewModal] = useState(false);


useEffect(() => { useEffect(() => {
if (chat?.chat?.exchangeId) refetchExchange(); if (chat?.chat?.exchangeId) refetchExchange();
return false; 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 showReviewModal = (event) => {
event.stopPropagation();
dispatch(
toggleCreateReviewModal({
offer: props.offer,
interlocutor: props.interlocutor,
exchange: exchange,
})
);
}; };

const refetchExchange = () => { const refetchExchange = () => {
dispatch(fetchExchange(chat.chat.exchangeId)); dispatch(fetchExchange(chat.chat.exchangeId));
}; };
return ( return (
<DirectChatHeaderContainer> <DirectChatHeaderContainer>
{showReviewModal && (
<>
<BackdropComponent
isLoading
handleClose={() => setShowReviewModal(false)}
position="fixed"
/>
<CreateReview
offer={props.offer}
interlocutor={props.interlocutor}
closeModal={() => setShowReviewModal()}
handleGiveReviewSuccess={handleGiveReviewSuccess}
exchange={exchange}
/>
</>
)}
<OfferCard <OfferCard
offer={props.offer} offer={props.offer}
aboveChat aboveChat
disabledReviews={props.interlocutor?._blocked || isDisabledReviews} disabledReviews={props.interlocutor?._blocked || isDisabledReviews}
makeReview={makeReview}
makeReview={showReviewModal}
dontShowViews dontShowViews
disabledCheckButton={props.interlocutor?._blocked || props?.offer?._deleted}
disabledCheckButton={
props.interlocutor?._blocked || props?.offer?._deleted
}
/> />
</DirectChatHeaderContainer> </DirectChatHeaderContainer>
); );

+ 4
- 1
src/components/Header/Drawer/Buttons/AddOfferButton/AddOfferButton.js Ver fichero

import { AddOfferButtonContainer } from "./AddOfferButton.styled"; import { AddOfferButtonContainer } from "./AddOfferButton.styled";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import selectedTheme from "../../../../../themes"; import selectedTheme from "../../../../../themes";
import { useDispatch } from "react-redux";
import { toggleCreateOfferModal } from "../../../../../store/actions/modal/modalActions";


const AddOfferButton = (props) => { const AddOfferButton = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useDispatch();
const handleClick = () => { const handleClick = () => {
props.toggleDrawer(); props.toggleDrawer();
props.addOffer();
dispatch(toggleCreateOfferModal({}))
}; };
return ( return (
<AddOfferButtonContainer <AddOfferButtonContainer

+ 0
- 2
src/components/Header/Drawer/Drawer.js Ver fichero

) : ( ) : (
<AddOfferButton <AddOfferButton
toggleDrawer={props.toggleDrawer} toggleDrawer={props.toggleDrawer}
addOffer={props.addOffer}
/> />
)} )}
<LogoutButton toggleDrawer={props.toggleDrawer} /> <LogoutButton toggleDrawer={props.toggleDrawer} />
Drawer.propTypes = { Drawer.propTypes = {
children: PropTypes.node, children: PropTypes.node,
toggleDrawer: PropTypes.func, toggleDrawer: PropTypes.func,
addOffer: PropTypes.func,
}; };

+ 0
- 1
src/components/Header/DrawerContainer/DrawerContainer.js Ver fichero

content={ content={
<HeaderDrawer <HeaderDrawer
toggleDrawer={handleToggleDrawer} toggleDrawer={handleToggleDrawer}
addOffer={() => props.showCreateOfferModal(true)}
/> />
} }
/> />

+ 3
- 19
src/components/Header/Header.js Ver fichero

HOME_PAGE, HOME_PAGE,
} from "../../constants/pages"; } from "../../constants/pages";
import { fetchMineProfile } from "../../store/actions/profile/profileActions"; import { fetchMineProfile } from "../../store/actions/profile/profileActions";
import CreateOffer from "../Cards/CreateOfferCard/CreateOffer";
import useSearch from "../../hooks/useOffers/useSearch"; import useSearch from "../../hooks/useOffers/useSearch";
import { import {
isAdminRoute, isAdminRoute,
import LoginButton from "./LoginButton/LoginButton"; import LoginButton from "./LoginButton/LoginButton";
import RegisterButton from "./RegisterButton/RegisterButton"; import RegisterButton from "./RegisterButton/RegisterButton";
import useIsMobile from "../../hooks/useIsMobile"; import useIsMobile from "../../hooks/useIsMobile";
import { toggleCreateOfferModal } from "../../store/actions/modal/modalActions";


const Header = () => { const Header = () => {
const [showCreateOfferModal, setShowCreateOfferModal] = useState(false);
const theme = useTheme(); const theme = useTheme();
const searchRef = useRef(null); const searchRef = useRef(null);
const matches = useMediaQuery(theme.breakpoints.down("md")); const matches = useMediaQuery(theme.breakpoints.down("md"));
} }
}, [search.searchString, searchRef.current]); }, [search.searchString, searchRef.current]);


// Removes scroll when modal is open
if (showCreateOfferModal) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}
// Handling search when user is on marketplace and when he is not // Handling search when user is on marketplace and when he is not
const handleSearch = (value) => { const handleSearch = (value) => {
if (isAdminRoute()) { if (isAdminRoute()) {
}; };


const handleAddOfferClick = () => { const handleAddOfferClick = () => {
setShowCreateOfferModal(true);
};
const closeCreateOfferModal = () => {
setShowCreateOfferModal(false);
dispatch(toggleCreateOfferModal());
}; };


if (!shouldShow) { if (!shouldShow) {
</Toolbar> </Toolbar>
</AppBar> </AppBar>


<DrawerContainer
ref={drawerRef}
showCreateOfferModal={setShowCreateOfferModal}
/>
{showCreateOfferModal && (
<CreateOffer closeCreateOfferModal={closeCreateOfferModal} />
)}
<DrawerContainer ref={drawerRef} />
</HeaderContainer> </HeaderContainer>
); );
}; };

+ 7
- 7
src/components/Modals/DeleteCategory/DeleteCategory.js Ver fichero

import { dynamicRouteMatches } from "../../../util/helpers/routeHelpers"; import { dynamicRouteMatches } from "../../../util/helpers/routeHelpers";
import { ADMIN_SINGLE_USER_PAGE } from "../../../constants/pages"; import { ADMIN_SINGLE_USER_PAGE } from "../../../constants/pages";
import { fetchProfile } from "../../../store/actions/profile/profileActions"; import { fetchProfile } from "../../../store/actions/profile/profileActions";
import { closeModal } from "../../../store/actions/modal/modalActions";


const DeleteCategory = (props) => { const DeleteCategory = (props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { t } = useTranslation(); const { t } = useTranslation();
const handleCancel = () => {
props.setOpenedDeleteModal(false);
const closeModalHandler = () => {
dispatch(closeModal());
}; };
const reassuranceText = useMemo(() => { const reassuranceText = useMemo(() => {
return t(`admin.${props.type}.reassuranceDelete`); return t(`admin.${props.type}.reassuranceDelete`);


const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
if (dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE)) { if (dynamicRouteMatches(ADMIN_SINGLE_USER_PAGE)) {
dispatch(fetchProfile(props.customId))
dispatch(fetchProfile(props.customId));
} }
handleCancel();
closeModalHandler();
}; };


const handleSubmit = () => { const handleSubmit = () => {
<> <>
<BackdropComponent <BackdropComponent
isLoading isLoading
handleClose={() => props.setOpenedDeleteModal(false)}
handleClose={closeModalHandler}
position="fixed" position="fixed"
/> />
<DeleteCategoryContainer type={props.type}> <DeleteCategoryContainer type={props.type}>
<ReassuranceText>{reassuranceText}</ReassuranceText> <ReassuranceText>{reassuranceText}</ReassuranceText>
<ButtonsContainer> <ButtonsContainer>
<CancelButton <CancelButton
onClick={handleCancel}
onClick={closeModalHandler}
variant="contained" variant="contained"
buttoncolor={selectedTheme.colors.primaryPurple} buttoncolor={selectedTheme.colors.primaryPurple}
> >
}; };


DeleteCategory.propTypes = { DeleteCategory.propTypes = {
setOpenedDeleteModal: PropTypes.func,
category: PropTypes.object, category: PropTypes.object,
subcategory: PropTypes.bool, subcategory: PropTypes.bool,
type: PropTypes.string, type: PropTypes.string,

+ 8
- 5
src/components/Modals/DeleteReview/DeleteReview.js Ver fichero

import DeleteButton from "./DeleteButton/DeleteButton"; import DeleteButton from "./DeleteButton/DeleteButton";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { removeReview } from "../../../store/actions/review/reviewActions"; import { removeReview } from "../../../store/actions/review/reviewActions";
import { closeModal } from "../../../store/actions/modal/modalActions";


const DeleteReview = (props) => { const DeleteReview = (props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const reviewId = props.review._id; const reviewId = props.review._id;
const { t } = useTranslation(); const { t } = useTranslation();


const closeModalHandler = () => {
dispatch(closeModal());
};

const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
console.log("Succes");
closeModalHandler();
}; };


const deleteReviewHandler = () => { const deleteReviewHandler = () => {
dispatch(removeReview({ reviewId, handleApiResponseSuccess })); dispatch(removeReview({ reviewId, handleApiResponseSuccess }));
props.setOpenedDeleteModal(false);
}; };
return ( return (
<> <>
<BackdropComponent <BackdropComponent
isLoading isLoading
handleClose={() => props.setOpenedDeleteModal(false)}
handleClose={closeModalHandler}
position="fixed" position="fixed"
/> />
<DeleteReviewContainer> <DeleteReviewContainer>
deleteModal deleteModal
review={props.review} review={props.review}
/> />
<XIcon onClick={() => props.setOpenedDeleteModal(false)} />
<XIcon onClick={closeModalHandler} />
<DeleteButton onClick={deleteReviewHandler} /> <DeleteButton onClick={deleteReviewHandler} />
</DeleteReviewContainer> </DeleteReviewContainer>
</> </>


DeleteReview.propTypes = { DeleteReview.propTypes = {
review: PropTypes.any, review: PropTypes.any,
setOpenedDeleteModal: PropTypes.func,
cardComponent: PropTypes.any, cardComponent: PropTypes.any,
}; };



+ 9
- 3
src/components/Modals/EditCategory/EditCategory.js Ver fichero

import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { fetchAdminMethod } from "../../../store/actions/admin/adminActions"; import { fetchAdminMethod } from "../../../store/actions/admin/adminActions";
import { useRef } from "react"; import { useRef } from "react";
import { closeModal } from "../../../store/actions/modal/modalActions";


const EditCategory = (props) => { const EditCategory = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
setImage(image); setImage(image);
formik.setFieldValue("image", image); formik.setFieldValue("image", image);
}; };

const closeModalHandler = () => {
dispatch(closeModal());
};

const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
if (clickedOnNext) { if (clickedOnNext) {
formik.resetForm(); formik.resetForm();
inputRef.current.focus(); inputRef.current.focus();
} else props.setOpenedEditModal(false);
} else closeModalHandler();
}; };
const handleSubmit = (values) => { const handleSubmit = (values) => {
dispatch( dispatch(
<> <>
<BackdropComponent <BackdropComponent
isLoading isLoading
handleClose={() => props.setOpenedEditModal(false)}
handleClose={closeModalHandler}
position="fixed" position="fixed"
/> />
<EditCategoryContainer hideImagePicker={props.hideImagePicker}> <EditCategoryContainer hideImagePicker={props.hideImagePicker}>
<XIcon onClick={() => props.setOpenedEditModal(false)} />
<XIcon onClick={closeModalHandler} />
<EditCategoryTitle>{title}</EditCategoryTitle> <EditCategoryTitle>{title}</EditCategoryTitle>
{!props.hideImagePicker && ( {!props.hideImagePicker && (
<> <>

+ 52
- 0
src/components/Modals/Modal.js Ver fichero

import React, { useMemo } from "react";
import PropTypes from "prop-types";
import { useSelector } from "react-redux";
import { selectModalValues } from "../../store/selectors/modalSelectors";
import CreateOffer from "../Cards/CreateOfferCard/CreateOffer";
import EditCategory from "./EditCategory/EditCategory";
import DeleteCategory from "./DeleteCategory/DeleteCategory";
import CreateReview from "../CreateReview/CreateReview";
import EditProfile from "../Cards/ProfileCard/EditProfile/EditProfile";
import DeleteReview from "./DeleteReview/DeleteReview";
import DeleteOffer from "../Cards/OfferCard/DeleteOffer/DeleteOffer";

const Modal = () => {
const modals = useSelector(selectModalValues);
const isModalShown = useMemo(() => {
const properties = Object.getOwnPropertyNames(modals);
let isModalShownLocal = false;
properties.forEach((singleModal) => {
if (modals[singleModal] === true) isModalShownLocal = true;
});
return isModalShownLocal;
}, [modals]);
if (isModalShown) {
document.body.style.overflow = "hidden";
} else {
document.body.style.overflow = "auto";
}
console.log("MODALS: ", modals);
return (
<>
{modals?.createOfferModal && <CreateOffer {...modals?.props} />}
{modals?.editOfferModal && <CreateOffer editOffer {...modals?.props} />}
{modals?.deleteOfferModal && <DeleteOffer {...modals?.props} />}
{modals?.createCategoryModal && (
<EditCategory method="add" {...modals?.props} />
)}
{modals?.editCategoryModal && (
<EditCategory method="edit" {...modals?.props} />
)}
{modals?.deleteCategoryModal && <DeleteCategory {...modals?.props} />}
{modals?.createReviewModal && <CreateReview {...modals?.props} />}
{modals?.deleteReviewModal && <DeleteReview {...modals?.props} />}
{modals?.editProfileModal && <EditProfile {...modals?.props} />}
</>
);
};

Modal.propTypes = {
children: PropTypes.node,
};

export default Modal;

+ 12
- 12
src/pages/AdminHomePage/AdminCategoriesPage/AdminCategoriesPage.js Ver fichero

import { useMemo } from "react"; import { useMemo } from "react";
import { setManualSearchString } from "../../../store/actions/filters/filtersActions"; import { setManualSearchString } from "../../../store/actions/filters/filtersActions";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import { useState } from "react";
import EditCategory from "../../../components/Modals/EditCategory/EditCategory";
import useSorting from "../../../hooks/useOffers/useSorting"; import useSorting from "../../../hooks/useOffers/useSorting";
import { sortCategoriesEnum } from "../../../enums/sortEnum"; import { sortCategoriesEnum } from "../../../enums/sortEnum";
import { adminSortMethod } from "../../../util/helpers/adminSortHelper"; import { adminSortMethod } from "../../../util/helpers/adminSortHelper";
import { toggleCreateCategoryModal } from "../../../store/actions/modal/modalActions";


const AdminCategoriesPage = () => { const AdminCategoriesPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const sorting = useSorting(() => {}, sortCategoriesEnum); const sorting = useSorting(() => {}, sortCategoriesEnum);
const categories = useSelector(selectCategories); const categories = useSelector(selectCategories);
const manualSearchString = useSelector(selectManualSearchString); const manualSearchString = useSelector(selectManualSearchString);
const [openedAddModal, setOpenedAddModal] = useState(false);
useEffect(() => { useEffect(() => {
dispatch(fetchCategories()); dispatch(fetchCategories());
return () => { return () => {
} }
return []; return [];
}, [categories, manualSearchString, sorting.selectedSortOptionLocally]); }, [categories, manualSearchString, sorting.selectedSortOptionLocally]);

const showAddCategoryModal = () => {
dispatch(
toggleCreateCategoryModal({
type: "categories",
method: "add",
showSecondButton: true,
})
);
};
return ( return (
<> <>
<AdminCategoriesPageContainer> <AdminCategoriesPageContainer>
variant="contained" variant="contained"
buttoncolor={selectedTheme.colors.iconYellowColor} buttoncolor={selectedTheme.colors.iconYellowColor}
textcolor={selectedTheme.colors.messageText} textcolor={selectedTheme.colors.messageText}
onClick={() => setOpenedAddModal(true)}
onClick={showAddCategoryModal}
> >
{t("admin.categories.addCategory")} {t("admin.categories.addCategory")}
</NewCategoryButton> </NewCategoryButton>
</AdminCategoriesPageContainer> </AdminCategoriesPageContainer>
{openedAddModal && (
<EditCategory
setOpenedEditModal={setOpenedAddModal}
type={"categories"}
method="add"
showSecondButton
/>
)}
</> </>
); );
}; };

+ 13
- 13
src/pages/AdminHomePage/AdminLocationsPage/AdminLocationsPage.js Ver fichero

import React, { useEffect, useMemo, useState } from "react";
import React, { useEffect, useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
AdminLocationsHeader, AdminLocationsHeader,
import { fetchLocations } from "../../../store/actions/locations/locationsActions"; import { fetchLocations } from "../../../store/actions/locations/locationsActions";
import CategoryCard from "../../../components/Cards/CategoryCard/CategoryCard"; import CategoryCard from "../../../components/Cards/CategoryCard/CategoryCard";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import EditCategory from "../../../components/Modals/EditCategory/EditCategory";
import { setManualSearchString } from "../../../store/actions/filters/filtersActions"; import { setManualSearchString } from "../../../store/actions/filters/filtersActions";
import { selectManualSearchString } from "../../../store/selectors/filtersSelectors"; import { selectManualSearchString } from "../../../store/selectors/filtersSelectors";
import useSorting from "../../../hooks/useOffers/useSorting"; import useSorting from "../../../hooks/useOffers/useSorting";
import { sortCategoriesEnum } from "../../../enums/sortEnum"; import { sortCategoriesEnum } from "../../../enums/sortEnum";
import { adminSortMethod } from "../../../util/helpers/adminSortHelper"; import { adminSortMethod } from "../../../util/helpers/adminSortHelper";
import { toggleCreateCategoryModal } from "../../../store/actions/modal/modalActions";


const AdminLocationsPage = () => { const AdminLocationsPage = () => {
const [openedAddModal, setOpenedAddModal] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const dispatch = useDispatch(); const dispatch = useDispatch();
const sorting = useSorting(() => {}, sortCategoriesEnum); const sorting = useSorting(() => {}, sortCategoriesEnum);
return adminSortMethod(locations, manualSearchString, sorting); return adminSortMethod(locations, manualSearchString, sorting);
} }
}, [locations, manualSearchString, sorting.selectedSortOptionLocally]); }, [locations, manualSearchString, sorting.selectedSortOptionLocally]);
const showAddCategoryModal = () => {
dispatch(
toggleCreateCategoryModal({
hideImagePicker: true,
type: "locations",
method: "add",
showSecondButton: true,
})
);
};
return ( return (
<> <>
<AdminLocationsPageContainer> <AdminLocationsPageContainer>
variant="contained" variant="contained"
buttoncolor={selectedTheme.colors.iconYellowColor} buttoncolor={selectedTheme.colors.iconYellowColor}
textcolor={selectedTheme.colors.messageText} textcolor={selectedTheme.colors.messageText}
onClick={() => setOpenedAddModal(true)}
onClick={showAddCategoryModal}
> >
{t("admin.locations.addLocation")} {t("admin.locations.addLocation")}
</NewLocationButton> </NewLocationButton>
</AdminLocationsPageContainer> </AdminLocationsPageContainer>
{openedAddModal && (
<EditCategory
hideImagePicker
setOpenedEditModal={setOpenedAddModal}
type={"locations"}
method="add"
showSecondButton
/>
)}
</> </>
); );
}; };

+ 12
- 14
src/pages/AdminHomePage/AdminSubcategoriesPage/AdminSubcategoriesPage.js Ver fichero

import { useRouteMatch } from "react-router-dom"; import { useRouteMatch } from "react-router-dom";
import CategoryCard from "../../../components/Cards/CategoryCard/CategoryCard"; import CategoryCard from "../../../components/Cards/CategoryCard/CategoryCard";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import { useState } from "react";
import EditCategory from "../../../components/Modals/EditCategory/EditCategory";
import useSorting from "../../../hooks/useOffers/useSorting"; import useSorting from "../../../hooks/useOffers/useSorting";
import { sortCategoriesEnum } from "../../../enums/sortEnum"; import { sortCategoriesEnum } from "../../../enums/sortEnum";
import { adminSortMethod } from "../../../util/helpers/adminSortHelper"; import { adminSortMethod } from "../../../util/helpers/adminSortHelper";
import { ArrowButton } from "../../../components/Buttons/ArrowButton/ArrowButton"; import { ArrowButton } from "../../../components/Buttons/ArrowButton/ArrowButton";
import history from "../../../store/utils/history"; import history from "../../../store/utils/history";
import { toggleCreateCategoryModal } from "../../../store/actions/modal/modalActions";


const AdminSubcategoriesPage = () => { const AdminSubcategoriesPage = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const routeMatch = useRouteMatch(); const routeMatch = useRouteMatch();
const sorting = useSorting(() => {}, sortCategoriesEnum); const sorting = useSorting(() => {}, sortCategoriesEnum);
const manualSearchString = useSelector(selectManualSearchString); const manualSearchString = useSelector(selectManualSearchString);
const [openedAddModal, setOpenedAddModal] = useState(false);


useEffect(() => { useEffect(() => {
dispatch(fetchCategories()); dispatch(fetchCategories());
const goBack = () => { const goBack = () => {
history.goBack(); history.goBack();
}; };
const showAddSubcategoryModal = () => {
dispatch(
toggleCreateCategoryModal({
hideImagePicker: true,
type: "locations",
method: "add",
showSecondButton: true,
})
);
};


return ( return (
<> <>
variant="contained" variant="contained"
buttoncolor={selectedTheme.colors.iconYellowColor} buttoncolor={selectedTheme.colors.iconYellowColor}
textcolor={selectedTheme.colors.messageText} textcolor={selectedTheme.colors.messageText}
onClick={() => setOpenedAddModal(true)}
onClick={showAddSubcategoryModal}
> >
{t("admin.subcategories.addSubcategory")} {t("admin.subcategories.addSubcategory")}
</NewSubcategoryButton> </NewSubcategoryButton>
</AdminSubcategoriesPageContainer> </AdminSubcategoriesPageContainer>
{openedAddModal && (
<EditCategory
hideImagePicker
categoryId={category._id}
setOpenedEditModal={setOpenedAddModal}
type="subcategories"
method="add"
showSecondButton
/>
)}
</> </>
); );
}; };

+ 13
- 0
src/store/actions/modal/modalActionConstants.js Ver fichero

import { createClearType, createSetType } from "../actionHelpers";

export const TOGGLE_CREATE_OFFER = createSetType("TOGGLE_CREATE_OFFER");
export const TOGGLE_EDIT_OFFER = createSetType("TOGGLE_EDIT_OFFER");
export const TOGGLE_DELETE_OFFER = createSetType("TOGGLE_DELETE_OFFER");
export const TOGGLE_CREATE_CATEGORY = createSetType("TOGGLE_CREATE_CATEGORY");
export const TOGGLE_EDIT_CATEOGRY = createSetType("TOGGLE_EDIT_CATEOGRY");
export const TOGGLE_DELETE_CATEGORY = createSetType("TOGGLE_DELETE_CATEGORY");
export const TOGGLE_CREATE_REVIEW = createSetType("TOGGLE_CREATE_REVIEW");
export const TOGGLE_DELETE_REVIEW = createSetType("TOGGLE_DELETE_REVIEW");
export const TOGGLE_EDIT_PROFILE = createSetType("TOGGLE_EDIT_PROFILE");
export const SET_MODAL_TYPE = createSetType("SET_MODAL_TYPE");
export const CLOSE_MODAL = createClearType("CLOSE_MODAL");

+ 52
- 0
src/store/actions/modal/modalActions.js Ver fichero

import {
CLOSE_MODAL,
TOGGLE_CREATE_CATEGORY,
TOGGLE_CREATE_OFFER,
TOGGLE_CREATE_REVIEW,
TOGGLE_DELETE_CATEGORY,
TOGGLE_DELETE_OFFER,
TOGGLE_DELETE_REVIEW,
TOGGLE_EDIT_CATEOGRY,
TOGGLE_EDIT_OFFER,
TOGGLE_EDIT_PROFILE,
} from "./modalActionConstants";

export const toggleCreateOfferModal = (payload) => ({
type: TOGGLE_CREATE_OFFER,
payload,
});
export const toggleEditOfferModal = (payload) => ({
type: TOGGLE_EDIT_OFFER,
payload,
});
export const toggleDeleteOfferModal = (payload) => ({
type: TOGGLE_DELETE_OFFER,
payload,
});
export const toggleCreateCategoryModal = (payload) => ({
type: TOGGLE_CREATE_CATEGORY,
payload,
});
export const toggleEditCategoryModal = (payload) => ({
type: TOGGLE_EDIT_CATEOGRY,
payload,
});
export const toggleDeleteCategoryModal = (payload) => ({
type: TOGGLE_DELETE_CATEGORY,
payload,
});
export const toggleCreateReviewModal = (payload) => ({
type: TOGGLE_CREATE_REVIEW,
payload,
});
export const toggleDeleteReviewModal = (payload) => ({
type: TOGGLE_DELETE_REVIEW,
payload,
});
export const toggleEditProfileModal = (payload) => ({
type: TOGGLE_EDIT_PROFILE,
payload,
});
export const closeModal = () => ({
type: CLOSE_MODAL,
});

+ 2
- 0
src/store/reducers/index.js Ver fichero

import exchangeReducer from "./exchange/exchangeReducer"; import exchangeReducer from "./exchange/exchangeReducer";
import reviewReducer from "./review/reviewReducer"; import reviewReducer from "./review/reviewReducer";
import appReducer from "./app/appReducer"; import appReducer from "./app/appReducer";
import modalReducer from "./modal/modalReducer";


const loginPersistConfig = { const loginPersistConfig = {
key: "login", key: "login",
exchange: exchangeReducer, exchange: exchangeReducer,
review: reviewReducer, review: reviewReducer,
app: appReducer, app: appReducer,
modal: modalReducer,
}); });

+ 116
- 0
src/store/reducers/modal/modalReducer.js Ver fichero

import {
CLOSE_MODAL,
SET_MODAL_TYPE,
TOGGLE_CREATE_CATEGORY,
TOGGLE_CREATE_OFFER,
TOGGLE_CREATE_REVIEW,
TOGGLE_DELETE_CATEGORY,
TOGGLE_DELETE_OFFER,
TOGGLE_DELETE_REVIEW,
TOGGLE_EDIT_CATEOGRY,
TOGGLE_EDIT_OFFER,
TOGGLE_EDIT_PROFILE,
} from "../../actions/modal/modalActionConstants";
import createReducer from "../../utils/createReducer";

const initialState = {
createOfferModal: false,
editOfferModal: false,
deleteOfferModal: false,
createCategoryModal: false,
editCategoryModal: false,
deleteCategoryModal: false,
createReviewModal: false,
editProfile: false,
toggleDeleteReview: false,
props: {},
};

export default createReducer(
{
[TOGGLE_CREATE_OFFER]: toggleCreateOffer,
[TOGGLE_EDIT_OFFER]: toggleEditOffer,
[TOGGLE_DELETE_OFFER]: toggleDeleteOffer,
[TOGGLE_CREATE_CATEGORY]: toggleCreateCategory,
[TOGGLE_EDIT_CATEOGRY]: toggleEditCategory,
[TOGGLE_DELETE_CATEGORY]: toggleDeleteCategory,
[TOGGLE_CREATE_REVIEW]: toggleCreateReview,
[TOGGLE_DELETE_REVIEW]: toggleDeleteReview,
[TOGGLE_EDIT_PROFILE]: toggleEditProfile,
[SET_MODAL_TYPE]: setModalType,
[CLOSE_MODAL]: closeModal,
},
initialState
);
function toggleCreateOffer(state, { payload }) {
return {
...state,
createOfferModal: !state.createOfferModal,
props: payload,
};
}
function toggleEditOffer(state, { payload }) {
return {
...state,
editOfferModal: !state.editOfferModal,
props: payload,
};
}
function toggleDeleteOffer(state, { payload }) {
return {
...state,
deleteOfferModal: !state.deleteOfferModal,
props: payload,
};
}
function toggleCreateCategory(state, { payload }) {
return {
...state,
createCategoryModal: !state.createCategoryModal,
props: payload,
};
}
function toggleEditCategory(state, { payload }) {
return {
...state,
editCategoryModal: !state.editCategoryModal,
props: payload,
};
}
function toggleDeleteCategory(state, { payload }) {
return {
...state,
deleteCategoryModal: !state.deleteCategoryModal,
props: payload,
};
}
function toggleCreateReview(state, { payload }) {
return {
...state,
createReviewModal: !state.createReviewModal,
props: payload,
};
}
function toggleDeleteReview(state, { payload }) {
return {
...state,
deleteReviewModal: !state.deleteReviewModal,
props: payload,
};
}
function toggleEditProfile(state, { payload }) {
return {
...state,
editProfileModal: !state.editProfileModal,
props: payload,
};
}
function setModalType(state, { payload }) {
return {
...state,
type: payload,
};
}
function closeModal() {
return initialState;
}

+ 7
- 0
src/store/selectors/modalSelectors.js Ver fichero

import { createSelector } from "reselect";

const modalSelector = (state) => state.modal;
export const selectModalValues = createSelector(
modalSelector,
(state) => state
);

Cargando…
Cancelar
Guardar