Przeglądaj źródła

Partly finished feature 649

feature/649
djordjemitrovic00 3 lat temu
rodzic
commit
d771aa9d9b
30 zmienionych plików z 713 dodań i 84 usunięć
  1. 11
    0
      src/assets/images/svg/block.svg
  2. 75
    0
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js
  3. 313
    0
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js
  4. 19
    2
      src/components/Cards/ProfileCard/EditProfile/EditProfile.js
  5. 2
    0
      src/components/Cards/ProfileCard/ProfileContact/ProfileContact.js
  6. 1
    1
      src/components/Cards/ProfileCard/ProfileContact/ProfileContact.styled.js
  7. 7
    1
      src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.js
  8. 5
    4
      src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.styled.js
  9. 2
    2
      src/components/MarketPlace/Header/Header.js
  10. 10
    1
      src/components/MarketPlace/Header/Header.styled.js
  11. 3
    0
      src/components/MarketPlace/MarketPlace.js
  12. 6
    1
      src/components/MarketPlace/Offers/HeaderMyOffers.js/HeadersMyOffers.js
  13. 21
    12
      src/components/MarketPlace/Offers/Offers.js
  14. 4
    21
      src/components/Popovers/MyProfile/MyProfile.js
  15. 5
    1
      src/components/Popovers/MyProfile/MyProfile.styled.js
  16. 45
    0
      src/components/Popovers/MyProfile/PricesButton/PricesButton.js
  17. 8
    0
      src/components/Popovers/MyProfile/PricesButton/PricesButton.styled.js
  18. 6
    4
      src/i18n/resources/rs.js
  19. 18
    2
      src/pages/AdminUsersPage/AdminUsersPage.js
  20. 2
    1
      src/request/apiEndpoints.js
  21. 19
    6
      src/request/offersRequest.js
  22. 3
    0
      src/request/profileRequest.js
  23. 5
    0
      src/store/actions/offers/offersActionConstants.js
  24. 15
    0
      src/store/actions/offers/offersActions.js
  25. 6
    0
      src/store/actions/profile/profileActionConstants.js
  26. 24
    3
      src/store/actions/profile/profileActions.js
  27. 16
    3
      src/store/reducers/profile/profileReducer.js
  28. 18
    0
      src/store/saga/offersSaga.js
  29. 27
    6
      src/store/saga/profileSaga.js
  30. 17
    13
      src/store/selectors/profileSelectors.js

+ 11
- 0
src/assets/images/svg/block.svg Wyświetl plik

<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1412_9649)">
<path d="M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.69727 3.69727L14.3023 14.3023" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1412_9649">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
</svg>

+ 75
- 0
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js Wyświetl plik

import React, { useState } from "react";
import PropTypes from "prop-types";
import {
BlockIcon,
BlockIconContainer,
CheckButton,
EditButton,
EditIcon,
ProfileCardContainer,
ProfileCardWrapper,
ProfileInfoContainer,
RemoveIcon,
RemoveIconContainer,
} from "./BigProfileCard.styled";
import ProfileMainInfo from "../ProfileMainInfo/ProfileMainInfo";
import ProfileContact from "../ProfileContact/ProfileContact";
import EditProfile from "../EditProfile/EditProfile";
import selectedTheme from "../../../../themes";
import { useTranslation } from "react-i18next";

const BigProfileCard = (props) => {
const { t } = useTranslation();
const [editProfileModal, setEditProfileModal] = useState(false);
const closeModalHandler = () => {
setEditProfileModal(false);
};
const removeUser = () => {};
const blockUser = () => {};
return (
<>
<ProfileCardContainer>
<ProfileCardWrapper variant="outlined">
<EditButton onClick={() => setEditProfileModal(true)}>
<EditIcon />
</EditButton>
<RemoveIconContainer onClick={removeUser}>
<RemoveIcon />
</RemoveIconContainer>
<BlockIconContainer onClick={blockUser}>
<BlockIcon />
</BlockIconContainer>
<ProfileInfoContainer>
{/* Profile Main Info */}
<ProfileMainInfo profile={props.profile} isAdmin />
{/* Profile Contact */}
<ProfileContact profile={props.profile} isAdmin />
</ProfileInfoContainer>
<CheckButton
variant={"outlined"}
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={selectedTheme.colors.primaryPurple}
style={{ fontWeight: "600" }}
>
{t("admin.users.checkProfile")}
</CheckButton>
</ProfileCardWrapper>
</ProfileCardContainer>
{editProfileModal && (
<EditProfile
profile={props.profile}
closeModalHandler={closeModalHandler}
reFetchProfile={() => {}}
isAdmin
userId={props.profile._id}
/>
)}
</>
);
};

BigProfileCard.propTypes = {
profile: PropTypes.any,
};

export default BigProfileCard;

+ 313
- 0
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js Wyświetl plik

import styled from "styled-components";
import { Card, Typography, Grid, Box } from "@mui/material";
import selectedTheme from "../../../../themes";
import { ReactComponent as Edit } from "../../../../assets/images/svg/edit.svg";
// import { ReactComponent as Pocket } from "../../../assets/images/svg/pocket.svg";
// import { ReactComponent as Globe } from "../../../assets/images/svg/globe.svg";
import { ReactComponent as Mail } from "../../../../assets/images/svg/mail.svg";
import { ReactComponent as Remove } from "../../../../assets/images/svg/trash.svg";
import { ReactComponent as Block } from "../../../../assets/images/svg/block.svg";
import { IconButton } from "../../../Buttons/IconButton/IconButton";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
// import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";

export const ProfileCardContainer = styled(Box)`
width: 100%;
box-sizing: border-box;
max-height: 184px;
margin-top: 34px;
overflow: hidden;

@media (max-width: 1200px) {
padding: 0;
}
`;
export const EditIcon = styled(Edit)`
width: 18px;
height: 18px;
& path {
stroke: ${selectedTheme.colors.primaryPurple};
}
`;


export const MessageButton = styled(IconButton)`
width: 40px;
height: 40px;
position: absolute;
top: 18px;
right: 18px;
background-color: ${selectedTheme.colors.primaryIconBackgroundColor};
border-radius: 100%;
padding-top: 2px;
text-align: center;
@media (max-width: 600px) {
width: 30px;
height: 30px;
top: 16px;
right: 16px;
padding: 0;
${(props) =>
props.vertical &&
`
display: none;
`}
& button svg {
width: 16px;
height: 16px;
position: relative;
top: -3px;
left: -3.5px;
}
}
`;
export const EditButton = styled(MessageButton)`
right: 76px;
`;
export const ProfileCardWrapper = styled(Card)`
border: 1px solid ${selectedTheme.colors.borderNormal};
background: ${(props) =>
props.isMyProfile ? selectedTheme.colors.primaryPurple : "white"};
width: 100%;
min-width: fit-content;
padding: 1rem;
position: relative;
border-radius: 0 0 4px 4px;
`;
export const RemoveIconContainer = styled(MessageButton)`
display: block;
top: 18px;
right: 18px;
`;
export const RemoveIcon = styled(Remove)``;
export const BlockIconContainer = styled(MessageButton)`
display: block;
top: 18px;
right: 134px;
`;
export const BlockIcon = styled(Block)``;
export const CheckButton = styled(PrimaryButton)`
width: 180px;
height: 48px;
position: absolute;
bottom: 25px;
right: 9px;
& button:hover {
background-color: ${selectedTheme.colors.primaryPurple} !important;
color: white !important;
}
@media (max-width: 850px) {
display: none;
}
`;

// export const ProfileName = styled(Typography)`
// color: ${(props) =>
// props.isMyProfile
// ? selectedTheme.colors.primaryYellow
// : selectedTheme.colors.primaryPurple};
// font-weight: 700;
// font-size: 24px;
// font-family: ${selectedTheme.fonts.textFont};
// margin-bottom: 5px;
// @media (max-width: 600px) {
// font-size: 18px;
// }
// `;

// export const ProfilePIB = styled(Typography)`
// color: ${(props) =>
// props.isMyProfile ? "white" : selectedTheme.colors.primaryDarkText};
// margin-top: 0.18rem;
// font-family: ${selectedTheme.fonts.textFont};
// font-size: 16px;
// padding-top: 1px;
// @media (max-width: 600px) {
// font-size: 14px;
// }
// `;
// export const ProfilePIBContainer = styled(Grid)`
// display: flex;
// justify-content: center;
// align-items: center;
// position: relative;
// left: 5px;
// `;

// export const ProfileMainInfo = styled(Grid)`
// display: flex;
// justify-content: start;
// align-items: start;
// `;

// export const AvatarImageContainer = styled(Grid)`
// display: flex;
// justify-content: start;
// align-items: center;
// `;

// export const ProfileMainInfoGrid = styled(Grid)`
// display: flex;
// flex-direction: column;
// align-items: start;
// margin-left: 16px;
// `;

// export const ProfileContact = styled(Grid)`
// padding-top: 2rem;
// padding-bottom: 2rem;
// @media (max-width: 600px) {
// padding-bottom: 1rem;
// }
// `;

// export const ContactItem = styled(Typography)`
// margin-right: 2rem;
// margin-left: 0.4rem;
// color: ${(props) =>
// props.isMyProfile ? "white" : selectedTheme.colors.primaryDarkText};
// display: unset;
// font-family: ${selectedTheme.fonts.textFont};
// letter-spacing: 0.02em;
// font-size: 16px;
// position: relative;
// bottom: 1px;
// @media (max-width: 600px) {
// font-size: 14px;
// bottom: 4px;
// }
// `;

// export const StatsItem = styled(Typography)`
// margin-right: 2rem;
// display: unset;
// margin-left: 1rem;
// font-family: ${selectedTheme.fonts.textFont};
// font-size: 16px;
// margin-bottom: 2px;
// @media (max-width: 600px) {
// font-size: 12px;
// }
// `;

// export const ProfileStats = styled(Grid)`
// display: flex;
// justify-content: start;
// align-items: center;
// background: ${selectedTheme.colors.primaryDarkTextSecond};
// width: calc(100% + 2rem);
// padding-top: 1.3rem;
// padding-bottom: 1.3rem;
// margin-bottom: -1rem;
// margin-left: -1rem;
// border-radius: 0 0 4px 4px;
// `;
// export const AvatarImage = styled.img`
// min-height: 144px;
// min-width: 144px;
// width: 144px;
// height: 144px;
// border-radius: 100%;
// @media (max-width: 600px) {
// min-height: 90px;
// min-width: 90px;
// width: 90px;
// height: 90px;
// }
// `;

export const ProfileCardHeader = styled(Grid)`
display: flex;
justify-content: start;
align-items: center;
margin-bottom: 11px;
`;

export const HeaderTitle = styled(Typography)`
font-size: 16px;
font-family: ${selectedTheme.fonts.textFont};
color: ${selectedTheme.colors.primaryText};
position: relative;
@media (max-width: 600px) {
font-size: 12px;
}
`;
// export const PocketIcon = styled(Pocket)`
// width: 22px;
// height: 22px;
// position: relative;
// left: -5px;
// top: 2px;
// & path {
// stroke: #b4b4b4;
// }
// @media (max-width: 600px) {
// width: 14px;
// height: 14px;
// }
// `;
// export const MailIcon = styled(Mail)`
// height: 24px;
// width: 24px;
// & path {
// stroke: ${(props) =>
// props.isMyProfile
// ? selectedTheme.colors.iconMineProfileColor
// : selectedTheme.colors.iconProfileColor};
// }
// @media (max-width: 600px) {
// width: 14px;
// height: 14px;
// }
// `;
// export const GlobeIcon = styled(Globe)`
// height: 22px;
// width: 22px;
// & path {
// stroke: ${(props) =>
// props.isMyProfile
// ? selectedTheme.colors.iconMineProfileColor
// : selectedTheme.colors.iconProfileColor};
// }
// @media (max-width: 600px) {
// width: 14px;
// height: 14px;
// }
// `;
// export const LocationIcon = styled(Location)`
// height: 22px;
// width: 22px;
// & path {
// stroke: ${(props) =>
// props.isMyProfile
// ? selectedTheme.colors.iconMineProfileColor
// : selectedTheme.colors.iconProfileColor};
// }
// @media (max-width: 600px) {
// width: 14px;
// height: 14px;
// }
// `;
export const MessageIcon = styled(Mail)`
width: 19.5px;
height: 19.5px;
position: relative;
left: 1px;
top: 3px;
& path {
stroke: ${selectedTheme.colors.primaryYellow};
}
@media (max-width: 600px) {
width: 16px;
height: 16px;
left: -1px;
top: 1px;
}
`;

export const ProfileInfoContainer = styled(Grid)`
display: flex;
flex-direction: column;
justify-content: center;
align-items: start;
`;

+ 19
- 2
src/components/Cards/ProfileCard/EditProfile/EditProfile.js Wyświetl plik

import { ReactComponent as CloseIcon } from "../../../../assets/images/svg/close-modal.svg"; import { ReactComponent as CloseIcon } from "../../../../assets/images/svg/close-modal.svg";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { import {
editMineProfile,
editProfile,
fetchMineProfile, fetchMineProfile,
} from "../../../../store/actions/profile/profileActions"; } from "../../../../store/actions/profile/profileActions";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
}; };


const handleSubmit = (values) => { const handleSubmit = (values) => {
dispatch(editMineProfile({ ...values, handleApiResponseSuccess }));
if (props.isAdmin) {
dispatch(
editProfile({
userId: props.userId,
...values,
handleApiResponseSuccess,
})
);
} else {
dispatch(
editProfile({
...values,
handleApiResponseSuccess,
})
);
}
props.closeModalHandler(); props.closeModalHandler();
}; };
const initialValues = useMemo( const initialValues = useMemo(
closeModalHandler: PropTypes.func, closeModalHandler: PropTypes.func,
setImage: PropTypes.func, setImage: PropTypes.func,
reFetchProfile: PropTypes.func, reFetchProfile: PropTypes.func,
isAdmin: PropTypes.bool,
userId: PropTypes.string,
}; };


export default EditProfile; export default EditProfile;

+ 2
- 0
src/components/Cards/ProfileCard/ProfileContact/ProfileContact.js Wyświetl plik

return ( return (
<ProfileContactContainer <ProfileContactContainer
container container
isAdmin={props.isAdmin}
direction={{ xs: "column", sm: "row" }} direction={{ xs: "column", sm: "row" }}
justifyContent={{ xs: "center", sm: "start" }} justifyContent={{ xs: "center", sm: "start" }}
alignItems={{ xs: "start", sm: "center" }} alignItems={{ xs: "start", sm: "center" }}
profile: PropTypes.object, profile: PropTypes.object,
isMyProfile: PropTypes.bool, isMyProfile: PropTypes.bool,
children: PropTypes.node, children: PropTypes.node,
isAdmin: PropTypes.bool,
}; };


export default ProfileContact; export default ProfileContact;

+ 1
- 1
src/components/Cards/ProfileCard/ProfileContact/ProfileContact.styled.js Wyświetl plik

import selectedTheme from "../../../../themes"; import selectedTheme from "../../../../themes";


export const ProfileContactContainer = styled(Grid)` export const ProfileContactContainer = styled(Grid)`
padding-top: 2rem;
padding-top: ${(props) => (props.isAdmin ? `20px` : `2rem`)};
padding-bottom: 2rem; padding-bottom: 2rem;
@media (max-width: 600px) { @media (max-width: 600px) {
padding-bottom: 1rem; padding-bottom: 1rem;

+ 7
- 1
src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.js Wyświetl plik

src={props.profile?.image} src={props.profile?.image}
/> */} /> */}
<AvatarImage <AvatarImage
isAdmin={props.isAdmin}
src={getImageUrl( src={getImageUrl(
props.profile?.image, props.profile?.image,
variants.profileImage, variants.profileImage,
/> />
</AvatarImageContainer> </AvatarImageContainer>
<ProfileMainInfoGrid> <ProfileMainInfoGrid>
<ProfileName isMyProfile={props.isMyProfile} variant="h5">
<ProfileName
isAdmin={props.isAdmin}
isMyProfile={props.isMyProfile}
variant="h5"
>
{props.profile?.company?.name} {props.profile?.company?.name}
</ProfileName> </ProfileName>
<ProfilePIBContainer> <ProfilePIBContainer>
profile: PropTypes.object, profile: PropTypes.object,
isMyProfile: PropTypes.bool, isMyProfile: PropTypes.bool,
children: PropTypes.node, children: PropTypes.node,
isAdmin: PropTypes.any,
}; };


export default ProfileMainInfo; export default ProfileMainInfo;

+ 5
- 4
src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.styled.js Wyświetl plik

align-items: center; align-items: center;
`; `;
export const AvatarImage = styled.img` export const AvatarImage = styled.img`
min-height: 144px;
min-width: 144px;
width: 144px;
height: 144px;
min-height: ${(props) => (props.isAdmin ? `108px` : `144px`)};
min-width: ${(props) => (props.isAdmin ? `108px` : `144px`)};
width: ${(props) => (props.isAdmin ? `108px` : `144px`)};
height: ${(props) => (props.isAdmin ? `108px` : `144px`)};
border-radius: 100%; border-radius: 100%;
@media (max-width: 600px) { @media (max-width: 600px) {
min-height: 90px; min-height: 90px;
font-size: 24px; font-size: 24px;
font-family: ${selectedTheme.fonts.textFont}; font-family: ${selectedTheme.fonts.textFont};
margin-bottom: 5px; margin-bottom: 5px;
cursor: ${(props) => props.isAdmin && `pointer`};
@media (max-width: 600px) { @media (max-width: 600px) {
font-size: 18px; font-size: 18px;
} }

+ 2
- 2
src/components/MarketPlace/Header/Header.js Wyświetl plik

SwapsIcon, SwapsIcon,
SwapsTitle, SwapsTitle,
TooltipInnerContainer, TooltipInnerContainer,
UserIcon,
} from "./Header.styled"; } from "./Header.styled";
import { ReactComponent as GridSquare } from "../../../assets/images/svg/offer-grid-square.svg"; import { ReactComponent as GridSquare } from "../../../assets/images/svg/offer-grid-square.svg";
import { ReactComponent as GridLine } from "../../../assets/images/svg/offer-grid-line.svg"; import { ReactComponent as GridLine } from "../../../assets/images/svg/offer-grid-line.svg";
import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton"; import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton";
// import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton"; // import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton";
import history from "../../../store/utils/history"; import history from "../../../store/utils/history";
import { AccountCircle } from "@mui/icons-material";


const DownArrow = (props) => ( const DownArrow = (props) => (
<IconStyled {...props}> <IconStyled {...props}>
<> <>
{!isMobile ? ( {!isMobile ? (
<HeaderTitleContainer> <HeaderTitleContainer>
{props.users ? <AccountCircle /> : <SwapsHeaderIcon />}
{props.users ? <UserIcon /> : <SwapsHeaderIcon />}
<HeaderTitleText> <HeaderTitleText>
{props.users {props.users
? t("admin.users.headerTitle") ? t("admin.users.headerTitle")

+ 10
- 1
src/components/MarketPlace/Header/Header.styled.js Wyświetl plik

import Select from "../../Select/Select"; import Select from "../../Select/Select";
import { ReactComponent as Swaps } from "../../../assets/images/svg/swaps.svg"; import { ReactComponent as Swaps } from "../../../assets/images/svg/swaps.svg";
import { ReactComponent as CategoryHeader } from "../../../assets/images/svg/category-header.svg"; import { ReactComponent as CategoryHeader } from "../../../assets/images/svg/category-header.svg";
import { ReactComponent as User } from "../../../assets/images/svg/user.svg";


export const HeaderWrapperContainer = styled(Box)` export const HeaderWrapperContainer = styled(Box)`
display: ${(props) => (props.skeleton ? "none" : "block")}; display: ${(props) => (props.skeleton ? "none" : "block")};
position: relative; position: relative;
top: ${props => props.isAdmin && `60px`};
top: ${(props) => props.isAdmin && `60px`};
`; `;


export const HeaderContainer = styled(Box)` export const HeaderContainer = styled(Box)`
position: relative; position: relative;
bottom: 2px; bottom: 2px;
`; `;
export const UserIcon = styled(User)`
position: relative;
top: 3px;
margin-right: 5px;
& path {
stroke: ${selectedTheme.colors.primaryText};
}
`;

+ 3
- 0
src/components/MarketPlace/MarketPlace.js Wyświetl plik

offers={offers} offers={offers}
toggleFilters={props.toggleFilters} toggleFilters={props.toggleFilters}
isAdmin={props.isAdmin} isAdmin={props.isAdmin}
isUsers={props.users}
users={props.allUsers}
/> />
</MarketPlaceContainer> </MarketPlaceContainer>
); );
toggleFilters: PropTypes.func, toggleFilters: PropTypes.func,
isAdmin: PropTypes.bool, isAdmin: PropTypes.bool,
users: PropTypes.bool, users: PropTypes.bool,
allUsers: PropTypes.array,
}; };
MarketPlace.defaultProps = { MarketPlace.defaultProps = {
offers: { offers: {

+ 6
- 1
src/components/MarketPlace/Offers/HeaderMyOffers.js/HeadersMyOffers.js Wyświetl plik

</EndIcon> </EndIcon>
), ),
}} }}
placeholder={t("header.searchOffers")}
placeholder={
props.isUsers
? t("admin.users.searchPlaceholder")
: t("header.searchOffers")
}
onFocus={handleFocusSearch} onFocus={handleFocusSearch}
onBlur={handleBlurSearch} onBlur={handleBlurSearch}
ref={searchRef} ref={searchRef}
handleSearch: PropTypes.func, handleSearch: PropTypes.func,
isAdmin: PropTypes.bool, isAdmin: PropTypes.bool,
offers: PropTypes.any, offers: PropTypes.any,
isUsers: PropTypes.bool,
}; };


export default HeadersMyOffers; export default HeadersMyOffers;

+ 21
- 12
src/components/MarketPlace/Offers/Offers.js Wyświetl plik

import OffersNotFound from "./OffersNotFound"; import OffersNotFound from "./OffersNotFound";
import HeadersMyOffers from "./HeaderMyOffers.js/HeadersMyOffers"; import HeadersMyOffers from "./HeaderMyOffers.js/HeadersMyOffers";
import SkeletonOfferCard from "../../Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard"; import SkeletonOfferCard from "../../Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard";
import BigProfileCard from "../../Cards/ProfileCard/BigProfileCard/BigProfileCard";


const Offers = (props) => { const Offers = (props) => {
const chats = useSelector(selectLatestChats); const chats = useSelector(selectLatestChats);
handleSearch={offers?.apply} handleSearch={offers?.apply}
isAdmin={props?.isAdmin} isAdmin={props?.isAdmin}
offers={offers} offers={offers}
isUsers={props.isUsers}
/> />
)} )}
{offers?.allOffersToShow?.length === 0 ? ( {offers?.allOffersToShow?.length === 0 ? (
<OffersNotFound /> <OffersNotFound />
) : ( ) : (
<OffersContainer ref={offersRef}> <OffersContainer ref={offersRef}>
{offers?.allOffersToShow?.map((item) => {
return (
<OfferCard
key={item._id}
offer={item}
halfwidth={props?.isGrid}
messageUser={messageOneUser}
isMyOffer={item?.userId === userId || props?.isAdmin}
isAdmin={props?.isAdmin}
/>
);
})}
{props.isUsers
? props.users?.map((item) => (
<BigProfileCard key={item._id} profile={item} />
))
: offers?.allOffersToShow?.map((item) => {
return (
<OfferCard
key={item._id}
offer={item}
halfwidth={props?.isGrid}
messageUser={messageOneUser}
isMyOffer={item?.userId === userId || props?.isAdmin}
isAdmin={props?.isAdmin}
/>
);
})}
<Paging <Paging
totalElements={offers?.totalOffers} totalElements={offers?.totalOffers}
elementsPerPage={10} elementsPerPage={10}
offers: PropTypes.any, offers: PropTypes.any,
toggleFilters: PropTypes.func, toggleFilters: PropTypes.func,
isAdmin: PropTypes.bool, isAdmin: PropTypes.bool,
isUsers: PropTypes.bool,
users: PropTypes.array,
}; };


Offers.defaultProps = { Offers.defaultProps = {
myOffers: false, myOffers: false,
users: []
}; };


export default Offers; export default Offers;

+ 4
- 21
src/components/Popovers/MyProfile/MyProfile.js Wyświetl plik

import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import {
DollarIcon,
GrayButtonsContainer,
ProfileImgPIB,
} from "./MyProfile.styled";
import { GrayButtonsContainer, ProfileImgPIB } from "./MyProfile.styled";
import HeaderPopover from "../HeaderPopover/HeaderPopover"; import HeaderPopover from "../HeaderPopover/HeaderPopover";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { EyeIcon } from "../HeaderPopover/HeaderPopover.styled"; import { EyeIcon } from "../HeaderPopover/HeaderPopover.styled";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { ABOUT_PAGE } from "../../../constants/pages";
import LogoutButton from "./LogoutButton/LogoutButton"; import LogoutButton from "./LogoutButton/LogoutButton";
import AboutButton from "./AboutButton/AboutButton"; import AboutButton from "./AboutButton/AboutButton";
import PrivacyPolicyButton from "./PrivacyPolicyButton/PrivacyPolicyButton"; import PrivacyPolicyButton from "./PrivacyPolicyButton/PrivacyPolicyButton";
import scrollConstants from "../../../constants/scrollConstants";
import PricesButton from "./PricesButton/PricesButton";


export const MyProfile = (props) => { export const MyProfile = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
history.push(`/profile/${userId}`); history.push(`/profile/${userId}`);
props.closePopover(); props.closePopover();
}; };
const seePrices = () => {
history.push({
pathname: ABOUT_PAGE,
state: {
clicked: true,
navigation: scrollConstants.about.pricesPage,
},
});
props.closePopover();
};


return ( return (
<HeaderPopover <HeaderPopover
title={t("header.myProfile")} title={t("header.myProfile")}
items={profileAsArray} items={profileAsArray}
isProfile
buttonText={t("header.checkProfile")} buttonText={t("header.checkProfile")}
buttonIcon={<EyeIcon color={selectedTheme.colors.iconYellowColor} />} buttonIcon={<EyeIcon color={selectedTheme.colors.iconYellowColor} />}
isProfile
buttonOnClick={() => seeMyProfile()} buttonOnClick={() => seeMyProfile()}
secondButtonIcon={<DollarIcon />}
secondButtonText={t("header.prices")}
secondButtonOnClick={seePrices}
> >
<GrayButtonsContainer> <GrayButtonsContainer>
<AboutButton closePopover={props.closePopover} /> <AboutButton closePopover={props.closePopover} />
<PricesButton closePopover={props.closePopover} />
<PrivacyPolicyButton closePopover={props.closePopover} /> <PrivacyPolicyButton closePopover={props.closePopover} />
</GrayButtonsContainer> </GrayButtonsContainer>
<LogoutButton /> <LogoutButton />

+ 5
- 1
src/components/Popovers/MyProfile/MyProfile.styled.js Wyświetl plik

`; `;
export const DollarIcon = styled(Dollar)` export const DollarIcon = styled(Dollar)`
position: relative; position: relative;
left: -4px;
left: -7px;
margin-left: 10px; margin-left: 10px;
& path {
stroke: ${selectedTheme.colors.borderNormal};
fill: ${selectedTheme.colors.borderNormal};
}
`; `;

+ 45
- 0
src/components/Popovers/MyProfile/PricesButton/PricesButton.js Wyświetl plik

import React from "react";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
import { ABOUT_PAGE } from "../../../../constants/pages";
import { DollarIcon, GrayButton } from "../MyProfile.styled";
import { PopoverButton } from "../../HeaderPopover/HeaderPopover.styled";
import { useHistory } from "react-router-dom";
import scrollConstants from "../../../../constants/scrollConstants";

const PricesButton = (props) => {
const { t } = useTranslation();
const history = useHistory();
const seePrices = () => {
history.push({
pathname: ABOUT_PAGE,
state: {
navigation: scrollConstants.about.pricesPage,
clicked: true,
},
});
props.closePopover();
};
return (
<GrayButton>
<PopoverButton
sx={{
mr: 2,
mb: 2,
}}
variant="text"
endIcon={<DollarIcon />}
onClick={seePrices}
>
{t("header.prices")}
</PopoverButton>
</GrayButton>
);
};

PricesButton.propTypes = {
children: PropTypes.node,
closePopover: PropTypes.func,
};

export default PricesButton;

+ 8
- 0
src/components/Popovers/MyProfile/PricesButton/PricesButton.styled.js Wyświetl plik

import styled from "styled-components";
import { ReactComponent as Dollar } from "../../../../assets/images/svg/dollar.svg";

export const DollarIcon = styled(Dollar)`
position: relative;
left: -4px;
margin-left: 10px;
`;

+ 6
- 4
src/i18n/resources/rs.js Wyświetl plik

offer: "Proizvod:", offer: "Proizvod:",
}, },
admin: { admin: {
login:{
login: {
welcome: "React template", welcome: "React template",
welcomeText: "Trampa sa kolegama na dohvat ruke", welcomeText: "Trampa sa kolegama na dohvat ruke",
emailFormat: "Nevalidan format email adrese!", emailFormat: "Nevalidan format email adrese!",
headerTitle: "Ulogujte se", headerTitle: "Ulogujte se",
}, },
users: { users: {
headerTitle: "Profili korisnika"
}
}
headerTitle: "Profili korisnika",
searchPlaceholder: "Pretražite korisnike....",
checkProfile: "Pogledaj profil"
},
},
}; };

+ 18
- 2
src/pages/AdminUsersPage/AdminUsersPage.js Wyświetl plik

import React from "react";
import React, { useEffect } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import MarketPlace from "../../components/MarketPlace/MarketPlace"; import MarketPlace from "../../components/MarketPlace/MarketPlace";
import { useDispatch, useSelector } from "react-redux";
import { selectAllProfiles } from "../../store/selectors/profileSelectors";
import { fetchAllProfiles } from "../../store/actions/profile/profileActions";


const AdminUsersPage = () => { const AdminUsersPage = () => {
return <MarketPlace isAdmin myOffers users />;
const dispatch = useDispatch();
const allUsers = useSelector(selectAllProfiles);
useEffect(() => {
dispatch(fetchAllProfiles());
}, []);

return (
<MarketPlace
isAdmin
myOffers
users
allUsers={Array.isArray(allUsers) ? allUsers : []}
/>
);
}; };


AdminUsersPage.propTypes = { AdminUsersPage.propTypes = {

+ 2
- 1
src/request/apiEndpoints.js Wyświetl plik

invite: "/users/invite", invite: "/users/invite",
getProfile: "users/", getProfile: "users/",
editProfile: "users", editProfile: "users",
getAllProfiles: "users"
}, },
applications: { applications: {
application: "/applications/{applicationUid}", application: "/applications/{applicationUid}",
locations: "locations", locations: "locations",
mineOffers: "users", mineOffers: "users",
removeOffer: "offers", removeOffer: "offers",
editOffer: "offers",
pinOffer: "offers/{id}/pin",
}, },
chat: { chat: {
getChat: "chats", getChat: "chats",

+ 19
- 6
src/request/offersRequest.js Wyświetl plik

import { deleteRequest, getRequest, postRequest, putRequest } from ".";
import {
deleteRequest,
getRequest,
patchRequest,
postRequest,
putRequest,
replaceInUrl,
} from ".";
import apiEndpoints from "./apiEndpoints"; import apiEndpoints from "./apiEndpoints";


export const attemptFetchOffers = (payload) => { export const attemptFetchOffers = (payload) => {
return getRequest(apiEndpoints.offers.getOffers); return getRequest(apiEndpoints.offers.getOffers);
}; };
export const attemptFetchFeaturedOffers = (payload) => { export const attemptFetchFeaturedOffers = (payload) => {
if (payload) return getRequest(apiEndpoints.offers.getFeaturedOffers + payload);
if (payload)
return getRequest(apiEndpoints.offers.getFeaturedOffers + payload);
return getRequest(apiEndpoints.offers.getOffers); return getRequest(apiEndpoints.offers.getOffers);
}
};
export const attemptFetchOneOffer = (payload) => { export const attemptFetchOneOffer = (payload) => {
const url = `${apiEndpoints.offers.getOneOffer}/${payload}`;
return getRequest(url);
}
const url = `${apiEndpoints.offers.getOneOffer}/${payload}`;
return getRequest(url);
};
export const attemptFetchMoreOffers = (page, payload) => { export const attemptFetchMoreOffers = (page, payload) => {
if (payload) if (payload)
return getRequest( return getRequest(
export const attemptEditOffer = (payload, editedData) => { export const attemptEditOffer = (payload, editedData) => {
return putRequest(apiEndpoints.offers.editOffer + "/" + payload, editedData); return putRequest(apiEndpoints.offers.editOffer + "/" + payload, editedData);
}; };
export const attemptPinOffer = (payload) => {
return patchRequest(
replaceInUrl(apiEndpoints.offers.pinOffer, { id: payload })
);
};

+ 3
- 0
src/request/profileRequest.js Wyświetl plik

export const attemptFetchProfile = (payload) => export const attemptFetchProfile = (payload) =>
getRequest(apiEndpoints.users.getProfile + payload); getRequest(apiEndpoints.users.getProfile + payload);


export const attemptFetchAllProfiles = () =>
getRequest(apiEndpoints.users.getAllProfiles);

export const attemptEditProfile = (payload, requestData) => export const attemptEditProfile = (payload, requestData) =>
putRequest(apiEndpoints.users.editProfile + "/" + payload, requestData); putRequest(apiEndpoints.users.editProfile + "/" + payload, requestData);

+ 5
- 0
src/store/actions/offers/offersActionConstants.js Wyświetl plik

export const OFFER_ADD_SUCCESS = createSuccessType(OFFER_ADD_SCOPE); export const OFFER_ADD_SUCCESS = createSuccessType(OFFER_ADD_SCOPE);
export const OFFER_ADD_ERROR = createErrorType(OFFER_ADD_SCOPE); export const OFFER_ADD_ERROR = createErrorType(OFFER_ADD_SCOPE);


export const OFFER_PIN_SCOPE = "OFFER_PIN_SCOPE";
export const OFFER_PIN = createFetchType(OFFER_PIN_SCOPE);
export const OFFER_PIN_SUCCESS = createSuccessType(OFFER_PIN_SCOPE);
export const OFFER_PIN_ERROR = createErrorType(OFFER_PIN_SCOPE);

export const OFFER_REMOVE_SCOPE = "OFFER_REMOVE_SCOPE"; export const OFFER_REMOVE_SCOPE = "OFFER_REMOVE_SCOPE";
export const OFFER_REMOVE = createFetchType(OFFER_REMOVE_SCOPE); export const OFFER_REMOVE = createFetchType(OFFER_REMOVE_SCOPE);
export const OFFER_REMOVE_SUCCESS = createSuccessType(OFFER_REMOVE_SCOPE); export const OFFER_REMOVE_SUCCESS = createSuccessType(OFFER_REMOVE_SCOPE);

+ 15
- 0
src/store/actions/offers/offersActions.js Wyświetl plik

OFFER_EDIT_SUCCESS, OFFER_EDIT_SUCCESS,
OFFER_FEATURED_PAGE_SET, OFFER_FEATURED_PAGE_SET,
OFFER_PAGE_SET, OFFER_PAGE_SET,
OFFER_PIN,
OFFER_PIN_ERROR,
OFFER_PIN_SUCCESS,
OFFER_REMOVE, OFFER_REMOVE,
OFFER_REMOVE_ERROR, OFFER_REMOVE_ERROR,
OFFER_REMOVE_SUCCESS, OFFER_REMOVE_SUCCESS,
type: OFFER_EDIT_ERROR, type: OFFER_EDIT_ERROR,
}); });


// Pin/unpin offer
export const pinOffer = (payload) => ({
type: OFFER_PIN,
payload,
});
export const pinOfferSuccess = () => ({
type: OFFER_PIN_SUCCESS,
});
export const pinOfferError = () => ({
type: OFFER_PIN_ERROR,
});

export const setOffers = (payload) => ({ export const setOffers = (payload) => ({
type: OFFERS_SET, type: OFFERS_SET,
payload, payload,

+ 6
- 0
src/store/actions/profile/profileActionConstants.js Wyświetl plik

export const PROFILE_SUCCESS = createSuccessType(PROFILE_SCOPE); export const PROFILE_SUCCESS = createSuccessType(PROFILE_SCOPE);
export const PROFILE_ERROR = createErrorType(PROFILE_SCOPE); export const PROFILE_ERROR = createErrorType(PROFILE_SCOPE);


export const PROFILE_ALL_SCOPE = "PROFILE_ALL_SCOPE";
export const PROFILE_ALL_FETCH = createFetchType(PROFILE_ALL_SCOPE);
export const PROFILE_ALL_SUCCESS = createSuccessType(PROFILE_ALL_SCOPE);
export const PROFILE_ALL_ERROR = createErrorType(PROFILE_ALL_SCOPE);

export const PROFILE_MINE_SCOPE = "PROFILE_MINE_SCOPE"; export const PROFILE_MINE_SCOPE = "PROFILE_MINE_SCOPE";
export const PROFILE_MINE_FETCH = createFetchType(PROFILE_MINE_SCOPE); export const PROFILE_MINE_FETCH = createFetchType(PROFILE_MINE_SCOPE);
export const PROFILE_MINE_FETCH_SUCCESS = createSuccessType(PROFILE_MINE_SCOPE); export const PROFILE_MINE_FETCH_SUCCESS = createSuccessType(PROFILE_MINE_SCOPE);


export const PROFILE_SET = createSetType("PROFILE_SET"); export const PROFILE_SET = createSetType("PROFILE_SET");
export const PROFILE_MINE_SET = createSetType("PROFILE_MINE_SET"); export const PROFILE_MINE_SET = createSetType("PROFILE_MINE_SET");
export const PROFILE_ALL_SET = createSetType("PROFILE_ALL_SET");


const PROFILE_EDIT_SCOPE = "PROFILE_EDIT_SCOPE"; const PROFILE_EDIT_SCOPE = "PROFILE_EDIT_SCOPE";
export const PROFILE_EDIT = createFetchType(PROFILE_EDIT_SCOPE); export const PROFILE_EDIT = createFetchType(PROFILE_EDIT_SCOPE);

+ 24
- 3
src/store/actions/profile/profileActions.js Wyświetl plik

PROFILE_EDIT_SUCCESS, PROFILE_EDIT_SUCCESS,
PROFILE_MINE_FETCH_ERROR, PROFILE_MINE_FETCH_ERROR,
PROFILE_EDIT_ERROR, PROFILE_EDIT_ERROR,
PROFILE_ALL_FETCH,
PROFILE_ALL_SUCCESS,
PROFILE_ALL_ERROR,
PROFILE_ALL_SET,
} from "./profileActionConstants"; } from "./profileActionConstants";


export const fetchProfile = (payload) => ({ export const fetchProfile = (payload) => ({
payload, payload,
}); });


export const fetchAllProfiles = (payload) => ({
type: PROFILE_ALL_FETCH,
payload,
});
export const fetchAllProfilesSuccess = (payload) => ({
type: PROFILE_ALL_SUCCESS,
payload,
});
export const fetchAllProfilesError = (payload) => ({
type: PROFILE_ALL_ERROR,
payload,
});

export const fetchMineProfile = () => ({ export const fetchMineProfile = () => ({
type: PROFILE_MINE_FETCH, type: PROFILE_MINE_FETCH,
}); });
type: PROFILE_MINE_FETCH_ERROR, type: PROFILE_MINE_FETCH_ERROR,
}); });


export const editMineProfile = (payload) => ({
export const editProfile = (payload) => ({
type: PROFILE_EDIT, type: PROFILE_EDIT,
payload, payload,
}); });
export const editMineProfileSuccess = () => ({
export const editProfileSuccess = () => ({
type: PROFILE_EDIT_SUCCESS, type: PROFILE_EDIT_SUCCESS,
}); });
export const editMineProfileError = () => ({
export const editProfileError = () => ({
type: PROFILE_EDIT_ERROR, type: PROFILE_EDIT_ERROR,
}); });


type: PROFILE_SET, type: PROFILE_SET,
payload, payload,
}); });
export const setAllProfiles = (payload) => ({
type: PROFILE_ALL_SET,
payload,
});
export const setMineProfile = (payload) => ({ export const setMineProfile = (payload) => ({
type: PROFILE_MINE_SET, type: PROFILE_MINE_SET,
payload, payload,

+ 16
- 3
src/store/reducers/profile/profileReducer.js Wyświetl plik

import { PROFILE_CLEAR, PROFILE_MINE_SET, PROFILE_SET } from "../../actions/profile/profileActionConstants";
import {
PROFILE_ALL_SET,
PROFILE_CLEAR,
PROFILE_MINE_SET,
PROFILE_SET,
} from "../../actions/profile/profileActionConstants";
import createReducer from "../../utils/createReducer"; import createReducer from "../../utils/createReducer";


const initialState = { const initialState = {
profile: {}, profile: {},
mineProfile: {}, mineProfile: {},
allProfiles: {},
}; };


export default createReducer( export default createReducer(
{ {
[PROFILE_SET]: setProfile, [PROFILE_SET]: setProfile,
[PROFILE_ALL_SET]: setAllProfiles,
[PROFILE_MINE_SET]: setMineProfile, [PROFILE_MINE_SET]: setMineProfile,
[PROFILE_CLEAR]: clearProfile, [PROFILE_CLEAR]: clearProfile,
}, },
function setMineProfile(state, action) { function setMineProfile(state, action) {
return { return {
...state, ...state,
mineProfile: action.payload
}
mineProfile: action.payload,
};
} }
function clearProfile() { function clearProfile() {
return initialState; return initialState;
} }
function setAllProfiles(state, { payload }) {
return {
...state,
allProfiles: payload,
};
}

+ 18
- 0
src/store/saga/offersSaga.js Wyświetl plik

attemptFetchFeaturedOffers, attemptFetchFeaturedOffers,
attemptFetchOffers, attemptFetchOffers,
attemptFetchOneOffer, attemptFetchOneOffer,
attemptPinOffer,
attemptRemoveOffer, attemptRemoveOffer,
} from "../../request/offersRequest"; } from "../../request/offersRequest";
import { import {
OFFERS_PROFILE_FETCH, OFFERS_PROFILE_FETCH,
OFFER_ADD, OFFER_ADD,
OFFER_EDIT, OFFER_EDIT,
OFFER_PIN,
OFFER_REMOVE, OFFER_REMOVE,
ONE_OFFER_FETCH, ONE_OFFER_FETCH,
} from "../actions/offers/offersActionConstants"; } from "../actions/offers/offersActionConstants";
setMineHeaderOffers, setMineHeaderOffers,
fetchMineHeaderOffersSuccess, fetchMineHeaderOffersSuccess,
fetchMineHeaderOffersError, fetchMineHeaderOffersError,
pinOfferSuccess,
pinOfferError,
// fetchAllOffersSuccess, // fetchAllOffersSuccess,
// fetchAllOffersError, // fetchAllOffersError,
// setFeaturedOfferPage, // setFeaturedOfferPage,
console.dir(e); console.dir(e);
} }
} }
function* pinOffer(payload) {
try {
const offerId = payload.payload.offerId;
yield call(attemptPinOffer, offerId);
yield put(pinOfferSuccess());
if (payload.payload.handleApiResponseSuccess) {
yield call(payload.payload.handleApiResponseSuccess);
}
} catch (e) {
yield put(pinOfferError());
console.dir(e);
}
}


function* editOffer(payload) { function* editOffer(payload) {
try { try {
takeLatest(OFFER_EDIT, editOffer), takeLatest(OFFER_EDIT, editOffer),
takeLatest(OFFERS_MINE_HEADER_FETCH, fetchMineHeaderOffers), takeLatest(OFFERS_MINE_HEADER_FETCH, fetchMineHeaderOffers),
takeLatest(OFFERS_FEATURED_FETCH, fetchFeaturedOffers), takeLatest(OFFERS_FEATURED_FETCH, fetchFeaturedOffers),
takeLatest(OFFER_PIN, pinOffer)
// takeLatest(OFFERS_ALL_FETCH, fetchAllOffers), // takeLatest(OFFERS_ALL_FETCH, fetchAllOffers),
]); ]);
} }

+ 27
- 6
src/store/saga/profileSaga.js Wyświetl plik

import { all, call, put, takeLatest, select } from "@redux-saga/core/effects"; import { all, call, put, takeLatest, select } from "@redux-saga/core/effects";
import { import {
attemptEditProfile, attemptEditProfile,
attemptFetchAllProfiles,
attemptFetchProfile, attemptFetchProfile,
} from "../../request/profileRequest"; } from "../../request/profileRequest";
import { import {
PROFILE_FETCH, PROFILE_FETCH,
PROFILE_MINE_FETCH, PROFILE_MINE_FETCH,
PROFILE_EDIT, PROFILE_EDIT,
PROFILE_ALL_FETCH,
} from "../actions/profile/profileActionConstants"; } from "../actions/profile/profileActionConstants";
import { import {
editMineProfileError,
editMineProfileSuccess,
editProfileError,
editProfileSuccess,
fetchAllProfilesError,
fetchAllProfilesSuccess,
fetchErrorProfile, fetchErrorProfile,
fetcHMineProfileError, fetcHMineProfileError,
fetchMineProfileSuccess, fetchMineProfileSuccess,
fetchProfileSuccess, fetchProfileSuccess,
// editMineProfile,
setAllProfiles,
// editProfile,
setMineProfile, setMineProfile,
setProfile, setProfile,
} from "../actions/profile/profileActions"; } from "../actions/profile/profileActions";
console.dir(e); console.dir(e);
} }
} }
function* fetchAllProfiles() {
try {
const data = yield call(attemptFetchAllProfiles);
if (data) yield put(setAllProfiles(data.data));
yield put(fetchAllProfilesSuccess());
} catch (e) {
yield put(fetchAllProfilesError());
console.dir(e);
}
}


function* changeMineProfile(payload) { function* changeMineProfile(payload) {
try { try {
if (payload.payload.firmWebsite.toString().length !== 0) if (payload.payload.firmWebsite.toString().length !== 0)
requestBody.append("company[contacts][web]", payload.payload.firmWebsite); requestBody.append("company[contacts][web]", payload.payload.firmWebsite);


const userId = yield select(selectUserId);
let userId;
if (payload.payload?.userId) {
userId = payload.payload.userId;
} else {
userId = yield select(selectUserId);
}
yield call(attemptEditProfile, userId, requestBody); yield call(attemptEditProfile, userId, requestBody);
yield put(editMineProfileSuccess());
yield put(editProfileSuccess());
if (payload.payload.handleApiResponseSuccess) { if (payload.payload.handleApiResponseSuccess) {
yield call(payload.payload.handleApiResponseSuccess); yield call(payload.payload.handleApiResponseSuccess);
} }
} catch (e) { } catch (e) {
yield put(editMineProfileError());
yield put(editProfileError());
console.dir(e); console.dir(e);
} }
} }
takeLatest(PROFILE_FETCH, fetchProfile), takeLatest(PROFILE_FETCH, fetchProfile),
takeLatest(PROFILE_MINE_FETCH, fetchMineProfile), takeLatest(PROFILE_MINE_FETCH, fetchMineProfile),
takeLatest(PROFILE_EDIT, changeMineProfile), takeLatest(PROFILE_EDIT, changeMineProfile),
takeLatest(PROFILE_ALL_FETCH, fetchAllProfiles),
]); ]);
} }

+ 17
- 13
src/store/selectors/profileSelectors.js Wyświetl plik

import { createSelector } from "reselect"; import { createSelector } from "reselect";


const profileSelector = (state) => state.profile
const profileSelector = (state) => state.profile;


export const selectProfileName = createSelector( export const selectProfileName = createSelector(
profileSelector,
(state) => state?.mineProfile?.company?.name
)
profileSelector,
(state) => state?.mineProfile?.company?.name
);
export const selectProfile = createSelector( export const selectProfile = createSelector(
profileSelector,
(state) => state.profile
)
profileSelector,
(state) => state.profile
);
export const selectMineProfile = createSelector( export const selectMineProfile = createSelector(
profileSelector,
(state) => state?.mineProfile
)
profileSelector,
(state) => state?.mineProfile
);
export const selectMineProfilePicture = createSelector( export const selectMineProfilePicture = createSelector(
profileSelector,
(state) => state?.mineProfile?.image
)
profileSelector,
(state) => state?.mineProfile?.image
);
export const selectAllProfiles = createSelector(
profileSelector,
(state) => state.allProfiles
);

Ładowanie…
Anuluj
Zapisz