| @@ -0,0 +1,11 @@ | |||
| <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> | |||
| @@ -0,0 +1,75 @@ | |||
| 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; | |||
| @@ -0,0 +1,313 @@ | |||
| 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,7 +19,7 @@ import { ReactComponent as ArrowBack } from "../../../../assets/images/svg/arrow | |||
| import { ReactComponent as CloseIcon } from "../../../../assets/images/svg/close-modal.svg"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { | |||
| editMineProfile, | |||
| editProfile, | |||
| fetchMineProfile, | |||
| } from "../../../../store/actions/profile/profileActions"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| @@ -56,7 +56,22 @@ const EditProfile = (props) => { | |||
| }; | |||
| const handleSubmit = (values) => { | |||
| dispatch(editMineProfile({ ...values, handleApiResponseSuccess })); | |||
| if (props.isAdmin) { | |||
| dispatch( | |||
| editProfile({ | |||
| userId: props.userId, | |||
| ...values, | |||
| handleApiResponseSuccess, | |||
| }) | |||
| ); | |||
| } else { | |||
| dispatch( | |||
| editProfile({ | |||
| ...values, | |||
| handleApiResponseSuccess, | |||
| }) | |||
| ); | |||
| } | |||
| props.closeModalHandler(); | |||
| }; | |||
| const initialValues = useMemo( | |||
| @@ -166,6 +181,8 @@ EditProfile.propTypes = { | |||
| closeModalHandler: PropTypes.func, | |||
| setImage: PropTypes.func, | |||
| reFetchProfile: PropTypes.func, | |||
| isAdmin: PropTypes.bool, | |||
| userId: PropTypes.string, | |||
| }; | |||
| export default EditProfile; | |||
| @@ -13,6 +13,7 @@ const ProfileContact = (props) => { | |||
| return ( | |||
| <ProfileContactContainer | |||
| container | |||
| isAdmin={props.isAdmin} | |||
| direction={{ xs: "column", sm: "row" }} | |||
| justifyContent={{ xs: "center", sm: "start" }} | |||
| alignItems={{ xs: "start", sm: "center" }} | |||
| @@ -47,6 +48,7 @@ ProfileContact.propTypes = { | |||
| profile: PropTypes.object, | |||
| isMyProfile: PropTypes.bool, | |||
| children: PropTypes.node, | |||
| isAdmin: PropTypes.bool, | |||
| }; | |||
| export default ProfileContact; | |||
| @@ -6,7 +6,7 @@ import { ReactComponent as Globe } from "../../../../assets/images/svg/globe.svg | |||
| import selectedTheme from "../../../../themes"; | |||
| export const ProfileContactContainer = styled(Grid)` | |||
| padding-top: 2rem; | |||
| padding-top: ${(props) => (props.isAdmin ? `20px` : `2rem`)}; | |||
| padding-bottom: 2rem; | |||
| @media (max-width: 600px) { | |||
| padding-bottom: 1rem; | |||
| @@ -25,6 +25,7 @@ const ProfileMainInfo = (props) => { | |||
| src={props.profile?.image} | |||
| /> */} | |||
| <AvatarImage | |||
| isAdmin={props.isAdmin} | |||
| src={getImageUrl( | |||
| props.profile?.image, | |||
| variants.profileImage, | |||
| @@ -33,7 +34,11 @@ const ProfileMainInfo = (props) => { | |||
| /> | |||
| </AvatarImageContainer> | |||
| <ProfileMainInfoGrid> | |||
| <ProfileName isMyProfile={props.isMyProfile} variant="h5"> | |||
| <ProfileName | |||
| isAdmin={props.isAdmin} | |||
| isMyProfile={props.isMyProfile} | |||
| variant="h5" | |||
| > | |||
| {props.profile?.company?.name} | |||
| </ProfileName> | |||
| <ProfilePIBContainer> | |||
| @@ -51,6 +56,7 @@ ProfileMainInfo.propTypes = { | |||
| profile: PropTypes.object, | |||
| isMyProfile: PropTypes.bool, | |||
| children: PropTypes.node, | |||
| isAdmin: PropTypes.any, | |||
| }; | |||
| export default ProfileMainInfo; | |||
| @@ -14,10 +14,10 @@ export const AvatarImageContainer = styled(Grid)` | |||
| align-items: center; | |||
| `; | |||
| 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%; | |||
| @media (max-width: 600px) { | |||
| min-height: 90px; | |||
| @@ -41,6 +41,7 @@ export const ProfileName = styled(Typography)` | |||
| font-size: 24px; | |||
| font-family: ${selectedTheme.fonts.textFont}; | |||
| margin-bottom: 5px; | |||
| cursor: ${(props) => props.isAdmin && `pointer`}; | |||
| @media (max-width: 600px) { | |||
| font-size: 18px; | |||
| } | |||
| @@ -27,6 +27,7 @@ import { | |||
| SwapsIcon, | |||
| SwapsTitle, | |||
| TooltipInnerContainer, | |||
| UserIcon, | |||
| } from "./Header.styled"; | |||
| import { ReactComponent as GridSquare } from "../../../assets/images/svg/offer-grid-square.svg"; | |||
| import { ReactComponent as GridLine } from "../../../assets/images/svg/offer-grid-line.svg"; | |||
| @@ -42,7 +43,6 @@ import useIsMobile from "../../../hooks/useIsMobile"; | |||
| import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton"; | |||
| // import { ArrowButton } from "../../Buttons/ArrowButton/ArrowButton"; | |||
| import history from "../../../store/utils/history"; | |||
| import { AccountCircle } from "@mui/icons-material"; | |||
| const DownArrow = (props) => ( | |||
| <IconStyled {...props}> | |||
| @@ -129,7 +129,7 @@ const Header = (props) => { | |||
| <> | |||
| {!isMobile ? ( | |||
| <HeaderTitleContainer> | |||
| {props.users ? <AccountCircle /> : <SwapsHeaderIcon />} | |||
| {props.users ? <UserIcon /> : <SwapsHeaderIcon />} | |||
| <HeaderTitleText> | |||
| {props.users | |||
| ? t("admin.users.headerTitle") | |||
| @@ -6,11 +6,12 @@ import Option from "../../Select/Option/Option"; | |||
| import Select from "../../Select/Select"; | |||
| import { ReactComponent as Swaps } from "../../../assets/images/svg/swaps.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)` | |||
| display: ${(props) => (props.skeleton ? "none" : "block")}; | |||
| position: relative; | |||
| top: ${props => props.isAdmin && `60px`}; | |||
| top: ${(props) => props.isAdmin && `60px`}; | |||
| `; | |||
| export const HeaderContainer = styled(Box)` | |||
| @@ -245,3 +246,11 @@ export const HeaderTitleText = styled(Typography)` | |||
| position: relative; | |||
| bottom: 2px; | |||
| `; | |||
| export const UserIcon = styled(User)` | |||
| position: relative; | |||
| top: 3px; | |||
| margin-right: 5px; | |||
| & path { | |||
| stroke: ${selectedTheme.colors.primaryText}; | |||
| } | |||
| `; | |||
| @@ -27,6 +27,8 @@ const MarketPlace = (props) => { | |||
| offers={offers} | |||
| toggleFilters={props.toggleFilters} | |||
| isAdmin={props.isAdmin} | |||
| isUsers={props.users} | |||
| users={props.allUsers} | |||
| /> | |||
| </MarketPlaceContainer> | |||
| ); | |||
| @@ -40,6 +42,7 @@ MarketPlace.propTypes = { | |||
| toggleFilters: PropTypes.func, | |||
| isAdmin: PropTypes.bool, | |||
| users: PropTypes.bool, | |||
| allUsers: PropTypes.array, | |||
| }; | |||
| MarketPlace.defaultProps = { | |||
| offers: { | |||
| @@ -47,7 +47,11 @@ const HeadersMyOffers = (props) => { | |||
| </EndIcon> | |||
| ), | |||
| }} | |||
| placeholder={t("header.searchOffers")} | |||
| placeholder={ | |||
| props.isUsers | |||
| ? t("admin.users.searchPlaceholder") | |||
| : t("header.searchOffers") | |||
| } | |||
| onFocus={handleFocusSearch} | |||
| onBlur={handleBlurSearch} | |||
| ref={searchRef} | |||
| @@ -61,6 +65,7 @@ HeadersMyOffers.propTypes = { | |||
| handleSearch: PropTypes.func, | |||
| isAdmin: PropTypes.bool, | |||
| offers: PropTypes.any, | |||
| isUsers: PropTypes.bool, | |||
| }; | |||
| export default HeadersMyOffers; | |||
| @@ -10,6 +10,7 @@ import { startChat } from "../../../util/helpers/chatHelper"; | |||
| import OffersNotFound from "./OffersNotFound"; | |||
| import HeadersMyOffers from "./HeaderMyOffers.js/HeadersMyOffers"; | |||
| import SkeletonOfferCard from "../../Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard"; | |||
| import BigProfileCard from "../../Cards/ProfileCard/BigProfileCard/BigProfileCard"; | |||
| const Offers = (props) => { | |||
| const chats = useSelector(selectLatestChats); | |||
| @@ -44,24 +45,29 @@ const Offers = (props) => { | |||
| handleSearch={offers?.apply} | |||
| isAdmin={props?.isAdmin} | |||
| offers={offers} | |||
| isUsers={props.isUsers} | |||
| /> | |||
| )} | |||
| {offers?.allOffersToShow?.length === 0 ? ( | |||
| <OffersNotFound /> | |||
| ) : ( | |||
| <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 | |||
| totalElements={offers?.totalOffers} | |||
| elementsPerPage={10} | |||
| @@ -90,10 +96,13 @@ Offers.propTypes = { | |||
| offers: PropTypes.any, | |||
| toggleFilters: PropTypes.func, | |||
| isAdmin: PropTypes.bool, | |||
| isUsers: PropTypes.bool, | |||
| users: PropTypes.array, | |||
| }; | |||
| Offers.defaultProps = { | |||
| myOffers: false, | |||
| users: [] | |||
| }; | |||
| export default Offers; | |||
| @@ -1,9 +1,5 @@ | |||
| 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 { useTranslation } from "react-i18next"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| @@ -14,11 +10,10 @@ import selectedTheme from "../../../themes"; | |||
| import { EyeIcon } from "../HeaderPopover/HeaderPopover.styled"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import PropTypes from "prop-types"; | |||
| import { ABOUT_PAGE } from "../../../constants/pages"; | |||
| import LogoutButton from "./LogoutButton/LogoutButton"; | |||
| import AboutButton from "./AboutButton/AboutButton"; | |||
| import PrivacyPolicyButton from "./PrivacyPolicyButton/PrivacyPolicyButton"; | |||
| import scrollConstants from "../../../constants/scrollConstants"; | |||
| import PricesButton from "./PricesButton/PricesButton"; | |||
| export const MyProfile = (props) => { | |||
| const { t } = useTranslation(); | |||
| @@ -53,31 +48,19 @@ export const MyProfile = (props) => { | |||
| history.push(`/profile/${userId}`); | |||
| props.closePopover(); | |||
| }; | |||
| const seePrices = () => { | |||
| history.push({ | |||
| pathname: ABOUT_PAGE, | |||
| state: { | |||
| clicked: true, | |||
| navigation: scrollConstants.about.pricesPage, | |||
| }, | |||
| }); | |||
| props.closePopover(); | |||
| }; | |||
| return ( | |||
| <HeaderPopover | |||
| title={t("header.myProfile")} | |||
| items={profileAsArray} | |||
| isProfile | |||
| buttonText={t("header.checkProfile")} | |||
| buttonIcon={<EyeIcon color={selectedTheme.colors.iconYellowColor} />} | |||
| isProfile | |||
| buttonOnClick={() => seeMyProfile()} | |||
| secondButtonIcon={<DollarIcon />} | |||
| secondButtonText={t("header.prices")} | |||
| secondButtonOnClick={seePrices} | |||
| > | |||
| <GrayButtonsContainer> | |||
| <AboutButton closePopover={props.closePopover} /> | |||
| <PricesButton closePopover={props.closePopover} /> | |||
| <PrivacyPolicyButton closePopover={props.closePopover} /> | |||
| </GrayButtonsContainer> | |||
| <LogoutButton /> | |||
| @@ -49,6 +49,10 @@ export const GrayButtonsContainer = styled(Box)` | |||
| `; | |||
| export const DollarIcon = styled(Dollar)` | |||
| position: relative; | |||
| left: -4px; | |||
| left: -7px; | |||
| margin-left: 10px; | |||
| & path { | |||
| stroke: ${selectedTheme.colors.borderNormal}; | |||
| fill: ${selectedTheme.colors.borderNormal}; | |||
| } | |||
| `; | |||
| @@ -0,0 +1,45 @@ | |||
| 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; | |||
| @@ -0,0 +1,8 @@ | |||
| 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; | |||
| `; | |||
| @@ -408,7 +408,7 @@ export default { | |||
| offer: "Proizvod:", | |||
| }, | |||
| admin: { | |||
| login:{ | |||
| login: { | |||
| welcome: "React template", | |||
| welcomeText: "Trampa sa kolegama na dohvat ruke", | |||
| emailFormat: "Nevalidan format email adrese!", | |||
| @@ -425,7 +425,9 @@ export default { | |||
| headerTitle: "Ulogujte se", | |||
| }, | |||
| users: { | |||
| headerTitle: "Profili korisnika" | |||
| } | |||
| } | |||
| headerTitle: "Profili korisnika", | |||
| searchPlaceholder: "Pretražite korisnike....", | |||
| checkProfile: "Pogledaj profil" | |||
| }, | |||
| }, | |||
| }; | |||
| @@ -1,9 +1,25 @@ | |||
| import React from "react"; | |||
| import React, { useEffect } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| 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 = () => { | |||
| 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 = { | |||
| @@ -120,6 +120,7 @@ export default { | |||
| invite: "/users/invite", | |||
| getProfile: "users/", | |||
| editProfile: "users", | |||
| getAllProfiles: "users" | |||
| }, | |||
| applications: { | |||
| application: "/applications/{applicationUid}", | |||
| @@ -168,7 +169,7 @@ export default { | |||
| locations: "locations", | |||
| mineOffers: "users", | |||
| removeOffer: "offers", | |||
| editOffer: "offers", | |||
| pinOffer: "offers/{id}/pin", | |||
| }, | |||
| chat: { | |||
| getChat: "chats", | |||
| @@ -1,4 +1,11 @@ | |||
| import { deleteRequest, getRequest, postRequest, putRequest } from "."; | |||
| import { | |||
| deleteRequest, | |||
| getRequest, | |||
| patchRequest, | |||
| postRequest, | |||
| putRequest, | |||
| replaceInUrl, | |||
| } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const attemptFetchOffers = (payload) => { | |||
| @@ -6,13 +13,14 @@ export const attemptFetchOffers = (payload) => { | |||
| return getRequest(apiEndpoints.offers.getOffers); | |||
| }; | |||
| 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); | |||
| } | |||
| }; | |||
| 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) => { | |||
| if (payload) | |||
| return getRequest( | |||
| @@ -32,3 +40,8 @@ export const attemptRemoveOffer = (payload) => { | |||
| export const attemptEditOffer = (payload, editedData) => { | |||
| return putRequest(apiEndpoints.offers.editOffer + "/" + payload, editedData); | |||
| }; | |||
| export const attemptPinOffer = (payload) => { | |||
| return patchRequest( | |||
| replaceInUrl(apiEndpoints.offers.pinOffer, { id: payload }) | |||
| ); | |||
| }; | |||
| @@ -4,5 +4,8 @@ import apiEndpoints from "./apiEndpoints"; | |||
| export const attemptFetchProfile = (payload) => | |||
| getRequest(apiEndpoints.users.getProfile + payload); | |||
| export const attemptFetchAllProfiles = () => | |||
| getRequest(apiEndpoints.users.getAllProfiles); | |||
| export const attemptEditProfile = (payload, requestData) => | |||
| putRequest(apiEndpoints.users.editProfile + "/" + payload, requestData); | |||
| @@ -72,6 +72,11 @@ export const OFFER_ADD = createFetchType(OFFER_ADD_SCOPE); | |||
| export const OFFER_ADD_SUCCESS = createSuccessType(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 = createFetchType(OFFER_REMOVE_SCOPE); | |||
| export const OFFER_REMOVE_SUCCESS = createSuccessType(OFFER_REMOVE_SCOPE); | |||
| @@ -37,6 +37,9 @@ import { | |||
| OFFER_EDIT_SUCCESS, | |||
| OFFER_FEATURED_PAGE_SET, | |||
| OFFER_PAGE_SET, | |||
| OFFER_PIN, | |||
| OFFER_PIN_ERROR, | |||
| OFFER_PIN_SUCCESS, | |||
| OFFER_REMOVE, | |||
| OFFER_REMOVE_ERROR, | |||
| OFFER_REMOVE_SUCCESS, | |||
| @@ -191,6 +194,18 @@ export const editOfferError = () => ({ | |||
| 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) => ({ | |||
| type: OFFERS_SET, | |||
| payload, | |||
| @@ -11,6 +11,11 @@ export const PROFILE_FETCH = createFetchType(PROFILE_SCOPE); | |||
| export const PROFILE_SUCCESS = createSuccessType(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_FETCH = createFetchType(PROFILE_MINE_SCOPE); | |||
| export const PROFILE_MINE_FETCH_SUCCESS = createSuccessType(PROFILE_MINE_SCOPE); | |||
| @@ -18,6 +23,7 @@ export const PROFILE_MINE_FETCH_ERROR = createErrorType(PROFILE_MINE_SCOPE); | |||
| export const PROFILE_SET = createSetType("PROFILE_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"; | |||
| export const PROFILE_EDIT = createFetchType(PROFILE_EDIT_SCOPE); | |||
| @@ -11,6 +11,10 @@ import { | |||
| PROFILE_EDIT_SUCCESS, | |||
| PROFILE_MINE_FETCH_ERROR, | |||
| PROFILE_EDIT_ERROR, | |||
| PROFILE_ALL_FETCH, | |||
| PROFILE_ALL_SUCCESS, | |||
| PROFILE_ALL_ERROR, | |||
| PROFILE_ALL_SET, | |||
| } from "./profileActionConstants"; | |||
| export const fetchProfile = (payload) => ({ | |||
| @@ -26,6 +30,19 @@ export const fetchErrorProfile = (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 = () => ({ | |||
| type: PROFILE_MINE_FETCH, | |||
| }); | |||
| @@ -36,14 +53,14 @@ export const fetcHMineProfileError = () => ({ | |||
| type: PROFILE_MINE_FETCH_ERROR, | |||
| }); | |||
| export const editMineProfile = (payload) => ({ | |||
| export const editProfile = (payload) => ({ | |||
| type: PROFILE_EDIT, | |||
| payload, | |||
| }); | |||
| export const editMineProfileSuccess = () => ({ | |||
| export const editProfileSuccess = () => ({ | |||
| type: PROFILE_EDIT_SUCCESS, | |||
| }); | |||
| export const editMineProfileError = () => ({ | |||
| export const editProfileError = () => ({ | |||
| type: PROFILE_EDIT_ERROR, | |||
| }); | |||
| @@ -54,6 +71,10 @@ export const setProfile = (payload) => ({ | |||
| type: PROFILE_SET, | |||
| payload, | |||
| }); | |||
| export const setAllProfiles = (payload) => ({ | |||
| type: PROFILE_ALL_SET, | |||
| payload, | |||
| }); | |||
| export const setMineProfile = (payload) => ({ | |||
| type: PROFILE_MINE_SET, | |||
| payload, | |||
| @@ -1,14 +1,21 @@ | |||
| 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"; | |||
| const initialState = { | |||
| profile: {}, | |||
| mineProfile: {}, | |||
| allProfiles: {}, | |||
| }; | |||
| export default createReducer( | |||
| { | |||
| [PROFILE_SET]: setProfile, | |||
| [PROFILE_ALL_SET]: setAllProfiles, | |||
| [PROFILE_MINE_SET]: setMineProfile, | |||
| [PROFILE_CLEAR]: clearProfile, | |||
| }, | |||
| @@ -24,9 +31,15 @@ function setProfile(state, action) { | |||
| function setMineProfile(state, action) { | |||
| return { | |||
| ...state, | |||
| mineProfile: action.payload | |||
| } | |||
| mineProfile: action.payload, | |||
| }; | |||
| } | |||
| function clearProfile() { | |||
| return initialState; | |||
| } | |||
| function setAllProfiles(state, { payload }) { | |||
| return { | |||
| ...state, | |||
| allProfiles: payload, | |||
| }; | |||
| } | |||
| @@ -4,6 +4,7 @@ import { | |||
| attemptFetchFeaturedOffers, | |||
| attemptFetchOffers, | |||
| attemptFetchOneOffer, | |||
| attemptPinOffer, | |||
| attemptRemoveOffer, | |||
| } from "../../request/offersRequest"; | |||
| import { | |||
| @@ -14,6 +15,7 @@ import { | |||
| OFFERS_PROFILE_FETCH, | |||
| OFFER_ADD, | |||
| OFFER_EDIT, | |||
| OFFER_PIN, | |||
| OFFER_REMOVE, | |||
| ONE_OFFER_FETCH, | |||
| } from "../actions/offers/offersActionConstants"; | |||
| @@ -40,6 +42,8 @@ import { | |||
| setMineHeaderOffers, | |||
| fetchMineHeaderOffersSuccess, | |||
| fetchMineHeaderOffersError, | |||
| pinOfferSuccess, | |||
| pinOfferError, | |||
| // fetchAllOffersSuccess, | |||
| // fetchAllOffersError, | |||
| // setFeaturedOfferPage, | |||
| @@ -244,6 +248,19 @@ function* removeOffer(payload) { | |||
| 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) { | |||
| try { | |||
| @@ -296,6 +313,7 @@ export default function* offersSaga() { | |||
| takeLatest(OFFER_EDIT, editOffer), | |||
| takeLatest(OFFERS_MINE_HEADER_FETCH, fetchMineHeaderOffers), | |||
| takeLatest(OFFERS_FEATURED_FETCH, fetchFeaturedOffers), | |||
| takeLatest(OFFER_PIN, pinOffer) | |||
| // takeLatest(OFFERS_ALL_FETCH, fetchAllOffers), | |||
| ]); | |||
| } | |||
| @@ -1,21 +1,26 @@ | |||
| import { all, call, put, takeLatest, select } from "@redux-saga/core/effects"; | |||
| import { | |||
| attemptEditProfile, | |||
| attemptFetchAllProfiles, | |||
| attemptFetchProfile, | |||
| } from "../../request/profileRequest"; | |||
| import { | |||
| PROFILE_FETCH, | |||
| PROFILE_MINE_FETCH, | |||
| PROFILE_EDIT, | |||
| PROFILE_ALL_FETCH, | |||
| } from "../actions/profile/profileActionConstants"; | |||
| import { | |||
| editMineProfileError, | |||
| editMineProfileSuccess, | |||
| editProfileError, | |||
| editProfileSuccess, | |||
| fetchAllProfilesError, | |||
| fetchAllProfilesSuccess, | |||
| fetchErrorProfile, | |||
| fetcHMineProfileError, | |||
| fetchMineProfileSuccess, | |||
| fetchProfileSuccess, | |||
| // editMineProfile, | |||
| setAllProfiles, | |||
| // editProfile, | |||
| setMineProfile, | |||
| setProfile, | |||
| } from "../actions/profile/profileActions"; | |||
| @@ -43,6 +48,16 @@ function* fetchMineProfile() { | |||
| 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) { | |||
| try { | |||
| @@ -93,14 +108,19 @@ function* changeMineProfile(payload) { | |||
| if (payload.payload.firmWebsite.toString().length !== 0) | |||
| 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 put(editMineProfileSuccess()); | |||
| yield put(editProfileSuccess()); | |||
| if (payload.payload.handleApiResponseSuccess) { | |||
| yield call(payload.payload.handleApiResponseSuccess); | |||
| } | |||
| } catch (e) { | |||
| yield put(editMineProfileError()); | |||
| yield put(editProfileError()); | |||
| console.dir(e); | |||
| } | |||
| } | |||
| @@ -110,5 +130,6 @@ export default function* profileSaga() { | |||
| takeLatest(PROFILE_FETCH, fetchProfile), | |||
| takeLatest(PROFILE_MINE_FETCH, fetchMineProfile), | |||
| takeLatest(PROFILE_EDIT, changeMineProfile), | |||
| takeLatest(PROFILE_ALL_FETCH, fetchAllProfiles), | |||
| ]); | |||
| } | |||
| @@ -1,20 +1,24 @@ | |||
| import { createSelector } from "reselect"; | |||
| const profileSelector = (state) => state.profile | |||
| const profileSelector = (state) => state.profile; | |||
| export const selectProfileName = createSelector( | |||
| profileSelector, | |||
| (state) => state?.mineProfile?.company?.name | |||
| ) | |||
| profileSelector, | |||
| (state) => state?.mineProfile?.company?.name | |||
| ); | |||
| export const selectProfile = createSelector( | |||
| profileSelector, | |||
| (state) => state.profile | |||
| ) | |||
| profileSelector, | |||
| (state) => state.profile | |||
| ); | |||
| export const selectMineProfile = createSelector( | |||
| profileSelector, | |||
| (state) => state?.mineProfile | |||
| ) | |||
| profileSelector, | |||
| (state) => state?.mineProfile | |||
| ); | |||
| export const selectMineProfilePicture = createSelector( | |||
| profileSelector, | |||
| (state) => state?.mineProfile?.image | |||
| ) | |||
| profileSelector, | |||
| (state) => state?.mineProfile?.image | |||
| ); | |||
| export const selectAllProfiles = createSelector( | |||
| profileSelector, | |||
| (state) => state.allProfiles | |||
| ); | |||