| // PRICES_PAGE, | // PRICES_PAGE, | ||||
| ABOUT_PAGE, | ABOUT_PAGE, | ||||
| ADMIN_HOME_PAGE, | ADMIN_HOME_PAGE, | ||||
| ADMIN_USERS_PAGE, | |||||
| // POLICY_PRIVACY_PAGE, | // POLICY_PRIVACY_PAGE, | ||||
| } from "./constants/pages"; | } from "./constants/pages"; | ||||
| import LoginPage from "./pages/LoginPage/LoginPage"; | import LoginPage from "./pages/LoginPage/LoginPage"; | ||||
| // import PricesPage from "./pages/Prices/PricesPage"; | // import PricesPage from "./pages/Prices/PricesPage"; | ||||
| import AboutPage from "./pages/About/AboutPage"; | import AboutPage from "./pages/About/AboutPage"; | ||||
| import AuthRoute from "./components/Router/AuthRoute"; | import AuthRoute from "./components/Router/AuthRoute"; | ||||
| import AdminHomePage from "./pages/AdminHomePage/AdminHomePage"; | |||||
| import AdminRoute from "./components/Router/AdminRoute"; | import AdminRoute from "./components/Router/AdminRoute"; | ||||
| import AdminHomePage from "./pages/AdminHomePage/AdminHomePage"; | |||||
| // import AdminUsersPage from "./pages/AdminUsersPage/AdminUsersPage"; | |||||
| // import PrivacyPolicyPage from "./pages/PrivacyPolicy/PrivacyPolicyPage"; | // import PrivacyPolicyPage from "./pages/PrivacyPolicy/PrivacyPolicyPage"; | ||||
| const AppRoutes = () => { | const AppRoutes = () => { | ||||
| <AuthRoute exact path={LOGIN_PAGE} component={LoginPage} /> | <AuthRoute exact path={LOGIN_PAGE} component={LoginPage} /> | ||||
| <AuthRoute exact path={ADMIN_LOGIN_PAGE} component={AdminLoginPage} /> | <AuthRoute exact path={ADMIN_LOGIN_PAGE} component={AdminLoginPage} /> | ||||
| <AdminRoute path={ADMIN_HOME_PAGE} component={AdminHomePage} /> | <AdminRoute path={ADMIN_HOME_PAGE} component={AdminHomePage} /> | ||||
| {/* <AdminRoute path={ADMIN_USERS_PAGE} component={AdminUsersPage} /> */} | |||||
| <Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> | <Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> | ||||
| <Route path={ERROR_PAGE} component={ErrorPage} /> | <Route path={ERROR_PAGE} component={ErrorPage} /> | ||||
| <AuthRoute | <AuthRoute |
| <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> |
| <svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||||
| <g clip-path="url(#clip0_1833_10358)"> | |||||
| <path d="M17.5239 6.36219L16.7758 5.93024L16.4025 6.70932L14.1445 11.4218L13.9563 11.8146L14.1841 12.1859C14.8482 13.2683 15.1028 14.5843 14.8378 15.889L14.8162 15.9944C14.8162 15.9945 14.8161 15.9947 14.8161 15.9949C14.8045 16.0494 14.745 16.1479 14.6047 16.2108L14.5786 16.2225L14.5533 16.2361C14.5179 16.2551 14.4348 16.27 14.3339 16.2118L4.59109 10.5868C4.49874 10.5334 4.44062 10.442 4.4307 10.3405L4.43071 10.3405L4.43022 10.3357C4.41975 10.2349 4.46016 10.1311 4.53653 10.0637L4.53726 10.063L4.6205 9.9893L4.62095 9.9889C5.6152 9.10697 6.88296 8.67 8.15351 8.70427L8.58904 8.71602L8.83518 8.35652L11.7873 4.04478L12.2754 3.33195L11.5272 2.9L10.6279 2.38074C10.4725 2.29105 10.4192 2.09214 10.5089 1.93679C10.5986 1.78144 10.7975 1.72814 10.9529 1.81783L18.7471 6.31783C18.9029 6.4078 18.956 6.60601 18.8661 6.76179C18.7761 6.91756 18.5779 6.97072 18.4221 6.88074L17.5239 6.36219ZM8.38144 15.9217L7.09394 18.1517C7.00372 18.3079 6.80624 18.3609 6.64998 18.2706C6.49372 18.1804 6.4408 17.9829 6.53102 17.8267L7.81852 15.5967L8.38144 15.9217Z" stroke="#5A3984" stroke-width="1.6"/> | |||||
| </g> | |||||
| <defs> | |||||
| <clipPath id="clip0_1833_10358"> | |||||
| <rect width="13.5" height="18" fill="white" transform="translate(9.4043) rotate(30)"/> | |||||
| </clipPath> | |||||
| </defs> | |||||
| </svg> |
| import useIsMobile from "../../../hooks/useIsMobile"; | import useIsMobile from "../../../hooks/useIsMobile"; | ||||
| import { ADMIN_NAVIGATION } from "../../../constants/adminNavigation"; | import { ADMIN_NAVIGATION } from "../../../constants/adminNavigation"; | ||||
| import { ReactComponent as Logout } from "../../../assets/images/svg/log-out.svg"; | import { ReactComponent as Logout } from "../../../assets/images/svg/log-out.svg"; | ||||
| import { useTranslation } from "react-i18next"; | |||||
| import { useDispatch } from "react-redux"; | |||||
| import { logoutAdmin } from "../../../store/actions/login/loginActions"; | |||||
| const Sidebar = () => { | const Sidebar = () => { | ||||
| const history = useHistory(); | const history = useHistory(); | ||||
| const profile = useSelector(selectMineProfile); | const profile = useSelector(selectMineProfile); | ||||
| const dispatch = useDispatch(); | |||||
| const { isMobile } = useIsMobile(); | const { isMobile } = useIsMobile(); | ||||
| console.log(history); | |||||
| const { t } = useTranslation(); | |||||
| console.log(profile); | |||||
| const routeToItem = (route) => { | const routeToItem = (route) => { | ||||
| console.log(route); | |||||
| history.push(route); | history.push(route); | ||||
| }; | }; | ||||
| const logoutHandler = () => { | |||||
| dispatch(logoutAdmin()); | |||||
| }; | |||||
| return ( | return ( | ||||
| <SidebarContainer> | <SidebarContainer> | ||||
| src={getImageUrl(profile.image, variants.profileImage, isMobile)} | src={getImageUrl(profile.image, variants.profileImage, isMobile)} | ||||
| /> | /> | ||||
| <SidebarProfileName>{profile.company.name}</SidebarProfileName> | <SidebarProfileName>{profile.company.name}</SidebarProfileName> | ||||
| <SidebarProfileRole>Administrator</SidebarProfileRole> | |||||
| <SidebarProfileRole>{t("admin.navigation.role")}</SidebarProfileRole> | |||||
| </SidebarProfileImageContainer> | </SidebarProfileImageContainer> | ||||
| <SidebarNavigation> | <SidebarNavigation> | ||||
| <SidebarNavigationMeni>Meni</SidebarNavigationMeni> | |||||
| <SidebarNavigationMeni> | |||||
| {t("admin.navigation.menu")} | |||||
| </SidebarNavigationMeni> | |||||
| <SidebarNavigationMeniItemUl> | <SidebarNavigationMeniItemUl> | ||||
| {ADMIN_NAVIGATION.map((value) => ( | {ADMIN_NAVIGATION.map((value) => ( | ||||
| <SidebarNavigationMeniItem | <SidebarNavigationMeniItem | ||||
| </SidebarNavigationMeniItem> | </SidebarNavigationMeniItem> | ||||
| ))} | ))} | ||||
| </SidebarNavigationMeniItemUl> | </SidebarNavigationMeniItemUl> | ||||
| <SidebarNavigationMeniLogout> | |||||
| <Logout /> Odjavi se | |||||
| <SidebarNavigationMeniLogout onClick={logoutHandler}> | |||||
| <Logout /> {t("admin.navigation.logout")} | |||||
| </SidebarNavigationMeniLogout> | </SidebarNavigationMeniLogout> | ||||
| </SidebarNavigation> | </SidebarNavigation> | ||||
| </SidebarContent> | </SidebarContent> |
| export const SidebarContainer = styled(Box)` | export const SidebarContainer = styled(Box)` | ||||
| margin-top: -30px; | margin-top: -30px; | ||||
| position: fixed; | |||||
| bottom: 0; | |||||
| left: 0; | |||||
| min-width: 20%; | |||||
| overflow-y: auto; | |||||
| height: 100vh; | |||||
| `; | `; | ||||
| export const SidebarHeader = styled(Box)` | export const SidebarHeader = styled(Box)` |
| LikeIcon, | LikeIcon, | ||||
| LikeIconContainer, | LikeIconContainer, | ||||
| CategoryIcon, | CategoryIcon, | ||||
| PinIconContainer, | |||||
| PinOutlinedIcon, | |||||
| } from "./OfferCard.styled"; | } from "./OfferCard.styled"; | ||||
| import DeleteOffer from "./DeleteOffer/DeleteOffer"; | 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"; | ||||
| const userId = useSelector(selectUserId); | const userId = useSelector(selectUserId); | ||||
| const { isMobile } = useIsMobile(); | const { isMobile } = useIsMobile(); | ||||
| const pinOffer = (event) => { | |||||
| event.stopPropagation(); | |||||
| }; | |||||
| const routeToItem = (itemId) => { | const routeToItem = (itemId) => { | ||||
| if (!props.disabledCheckButton) { | if (!props.disabledCheckButton) { | ||||
| history.push(`/proizvodi/${itemId}`); | history.push(`/proizvodi/${itemId}`); | ||||
| <Message /> | <Message /> | ||||
| </MessageIcon> | </MessageIcon> | ||||
| )} | )} | ||||
| {props.isAdmin && !props.pinned && ( | |||||
| <PinIconContainer showMessageIcon onClick={pinOffer}> | |||||
| <PinOutlinedIcon /> | |||||
| </PinIconContainer> | |||||
| )} | |||||
| {props?.offer?.pinned && <PinIcon isMyOffer={props.isMyOffer} />} | {props?.offer?.pinned && <PinIcon isMyOffer={props.isMyOffer} />} | ||||
| </OfferFlexContainer> | </OfferFlexContainer> | ||||
| </OfferCardContainer> | </OfferCardContainer> | ||||
| dontShowViews: PropTypes.bool, | dontShowViews: PropTypes.bool, | ||||
| skeleton: PropTypes.bool, | skeleton: PropTypes.bool, | ||||
| disabledCheckButton: PropTypes.bool, | disabledCheckButton: PropTypes.bool, | ||||
| isAdmin: PropTypes.bool, | |||||
| }; | }; | ||||
| OfferCard.defaultProps = { | OfferCard.defaultProps = { | ||||
| halfwidth: false, | halfwidth: false, |
| import { ReactComponent as Edit } from "../../../assets/images/svg/edit.svg"; | import { ReactComponent as Edit } from "../../../assets/images/svg/edit.svg"; | ||||
| import { ReactComponent as Like } from "../../../assets/images/svg/like.svg"; | import { ReactComponent as Like } from "../../../assets/images/svg/like.svg"; | ||||
| import { ReactComponent as Pin } from "../../../assets/images/svg/pin.svg"; | import { ReactComponent as Pin } from "../../../assets/images/svg/pin.svg"; | ||||
| import { ReactComponent as PinOutlined } from "../../../assets/images/svg/pin-outlined.svg"; | |||||
| import { ReactComponent as Category } from "../../../assets/images/svg/category.svg"; | import { ReactComponent as Category } from "../../../assets/images/svg/category.svg"; | ||||
| export const OfferCardContainer = styled(Container)` | export const OfferCardContainer = styled(Container)` | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| display: block; | display: block; | ||||
| position: ${props => props.vertical && "absolute"}; | |||||
| top: ${props => props.vertical && "325px"}; | |||||
| left: ${props => props.vertical && "59px"}; | |||||
| position: ${(props) => props.vertical && "absolute"}; | |||||
| top: ${(props) => props.vertical && "325px"}; | |||||
| left: ${(props) => props.vertical && "59px"}; | |||||
| } | } | ||||
| `; | `; | ||||
| export const RemoveIcon = styled(Remove)``; | export const RemoveIcon = styled(Remove)``; | ||||
| @media screen and (max-width: 600px) { | @media screen and (max-width: 600px) { | ||||
| position: absolute; | position: absolute; | ||||
| display: block; | display: block; | ||||
| right: ${props => !props.vertical && "64px"}; | |||||
| top: ${props => props.vertical && "325px"}; | |||||
| left: ${props => props.vertical && "18px"}; | |||||
| right: ${(props) => !props.vertical && "64px"}; | |||||
| top: ${(props) => props.vertical && "325px"}; | |||||
| left: ${(props) => props.vertical && "18px"}; | |||||
| } | } | ||||
| `; | `; | ||||
| export const EditIcon = styled(Edit)``; | export const EditIcon = styled(Edit)``; | ||||
| } | } | ||||
| `} | `} | ||||
| `; | `; | ||||
| export const PinIconContainer = styled(MessageIcon)` | |||||
| right: 134px; | |||||
| top: 18px; | |||||
| `; | |||||
| export const LikeIcon = styled(Like)` | export const LikeIcon = styled(Like)` | ||||
| & path { | & path { | ||||
| stroke: ${(props) => | stroke: ${(props) => | ||||
| top: -1px; | top: -1px; | ||||
| } | } | ||||
| `; | `; | ||||
| export const PinOutlinedIcon = styled(PinOutlined)` | |||||
| & g path { | |||||
| /* fill: transparent !important; */ | |||||
| /* stroke-width: 2; */ | |||||
| /* stroke: ${selectedTheme.colors.primaryPurple} !important; */ | |||||
| } | |||||
| `; | |||||
| export const PinIcon = styled(Pin)` | export const PinIcon = styled(Pin)` | ||||
| position: absolute; | position: absolute; | ||||
| top: 20px; | top: 20px; |
| 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; |
| 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; | |||||
| `; |
| 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; |
| 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; |
| 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; |
| 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; |
| 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; | ||||
| } | } |
| 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"; | ||||
| const Header = (props) => { | const Header = (props) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const sorting = props.sorting; | |||||
| const sorting = props?.sorting; | |||||
| const headerString = useSelector(selectHeaderString); | const headerString = useSelector(selectHeaderString); | ||||
| const { isMobile } = useIsMobile(); | const { isMobile } = useIsMobile(); | ||||
| // Changing header string on refresh or on load | // Changing header string on refresh or on load | ||||
| const altString = useMemo(() => { | const altString = useMemo(() => { | ||||
| if (sorting.selectedSortOption === sortEnum.OLD) { | |||||
| return `: ${t("header.oldOffers")}`; | |||||
| } | |||||
| if (sorting.selectedSortOption === sortEnum.POPULAR) { | |||||
| return `: ${t("header.popularOffers")}`; | |||||
| if (!props?.users) { | |||||
| if (sorting?.selectedSortOption === sortEnum.OLD) { | |||||
| return `: ${t("header.oldOffers")}`; | |||||
| } | |||||
| if (sorting?.selectedSortOption === sortEnum.POPULAR) { | |||||
| return `: ${t("header.popularOffers")}`; | |||||
| } | |||||
| } | } | ||||
| return `: ${t("header.newOffers")}`; | return `: ${t("header.newOffers")}`; | ||||
| }, [sorting.selectedSortOption]); | |||||
| }, [sorting?.selectedSortOption]); | |||||
| const handleChangeSelect = (event) => { | const handleChangeSelect = (event) => { | ||||
| sorting.changeSorting(event.target.value); | |||||
| if (!props.users) sorting?.changeSorting(event.target.value); | |||||
| }; | }; | ||||
| const handleClickCategory = () => { | const handleClickCategory = () => { | ||||
| props.offers.filters.locations.clear(); | |||||
| props.offers.filters.subcategory.clear(); | |||||
| props.offers.applyFilters(); | |||||
| props?.offers?.filters?.locations.clear(); | |||||
| props?.offers?.filters?.subcategory.clear(); | |||||
| props?.offers?.applyFilters(); | |||||
| }; | }; | ||||
| const handleClickSubcategory = () => { | const handleClickSubcategory = () => { | ||||
| props.offers.filters.locations.clear(); | |||||
| props.offers.applyFilters(); | |||||
| props?.offers?.filters?.locations.clear(); | |||||
| props?.offers?.applyFilters(); | |||||
| }; | }; | ||||
| const goBack = () => { | const goBack = () => { | ||||
| history.goBack(); | history.goBack(); | ||||
| return ( | return ( | ||||
| <> | <> | ||||
| <SkeletonHeader skeleton={props.skeleton} myOffers={props.myOffers} /> | |||||
| <HeaderWrapperContainer skeleton={props.skeleton} isAdmin={props.isAdmin}> | |||||
| <SkeletonHeader skeleton={props?.skeleton} myOffers={props?.myOffers} /> | |||||
| <HeaderWrapperContainer | |||||
| skeleton={props?.skeleton} | |||||
| isAdmin={props?.isAdmin} | |||||
| > | |||||
| <HeaderContainer> | <HeaderContainer> | ||||
| {/* Setting appropriate header title if page is market place or my offers */} | {/* Setting appropriate header title if page is market place or my offers */} | ||||
| <Tooltip title={headerString.text}> | <Tooltip title={headerString.text}> | ||||
| <TooltipInnerContainer> | <TooltipInnerContainer> | ||||
| {!props.myOffers ? ( | |||||
| {!props?.myOffers ? ( | |||||
| <> | <> | ||||
| <CategoryHeaderIcon /> | <CategoryHeaderIcon /> | ||||
| <HeaderLocation> | <HeaderLocation> | ||||
| <> | <> | ||||
| {!isMobile ? ( | {!isMobile ? ( | ||||
| <HeaderTitleContainer> | <HeaderTitleContainer> | ||||
| <SwapsHeaderIcon /> | |||||
| <HeaderTitleText>{t("header.myOffers")}</HeaderTitleText> | |||||
| {props.users ? <UserIcon /> : <SwapsHeaderIcon />} | |||||
| <HeaderTitleText> | |||||
| {props.users | |||||
| ? t("admin.users.headerTitle") | |||||
| : t("header.myOffers")} | |||||
| </HeaderTitleText> | |||||
| </HeaderTitleContainer> | </HeaderTitleContainer> | ||||
| ) : ( | ) : ( | ||||
| <ButtonContainer onClick={goBack}> | <ButtonContainer onClick={goBack}> | ||||
| {/* Setting display of offer cards to full width */} | {/* Setting display of offer cards to full width */} | ||||
| <HeaderButton | <HeaderButton | ||||
| iconColor={ | iconColor={ | ||||
| props.isGrid | |||||
| props?.isGrid | |||||
| ? selectedTheme.colors.iconStrokeColor | ? selectedTheme.colors.iconStrokeColor | ||||
| : selectedTheme.colors.primaryPurple | : selectedTheme.colors.primaryPurple | ||||
| } | } | ||||
| onClick={() => props.setIsGrid(false)} | |||||
| onClick={() => props?.setIsGrid(false)} | |||||
| > | > | ||||
| <GridLine /> | <GridLine /> | ||||
| </HeaderButton> | </HeaderButton> | ||||
| {/* Setting display of offer cards to half width (Grid) */} | {/* Setting display of offer cards to half width (Grid) */} | ||||
| <HeaderButton | <HeaderButton | ||||
| iconColor={ | iconColor={ | ||||
| props.isGrid | |||||
| props?.isGrid | |||||
| ? selectedTheme.colors.primaryPurple | ? selectedTheme.colors.primaryPurple | ||||
| : selectedTheme.colors.iconStrokeColor | : selectedTheme.colors.iconStrokeColor | ||||
| } | } | ||||
| onClick={() => props.setIsGrid(true)} | |||||
| onClick={() => props?.setIsGrid(true)} | |||||
| > | > | ||||
| <GridSquare /> | <GridSquare /> | ||||
| </HeaderButton> | </HeaderButton> | ||||
| {/* Select option to choose sorting */} | {/* Select option to choose sorting */} | ||||
| <HeaderSelect | <HeaderSelect | ||||
| value={ | value={ | ||||
| sorting.selectedSortOption?.value | |||||
| ? sorting.selectedSortOption | |||||
| sorting?.selectedSortOption?.value | |||||
| ? sorting?.selectedSortOption | |||||
| : "default" | : "default" | ||||
| } | } | ||||
| IconComponent={DownArrow} | IconComponent={DownArrow} | ||||
| onChange={handleChangeSelect} | onChange={handleChangeSelect} | ||||
| myOffers={props.myOffers} | |||||
| myOffers={props?.myOffers} | |||||
| > | > | ||||
| <SelectOption style={{ display: "none" }} value="default"> | <SelectOption style={{ display: "none" }} value="default"> | ||||
| {t("reviews.sortBy")} | {t("reviews.sortBy")} | ||||
| <PageTitleContainer> | <PageTitleContainer> | ||||
| <SwapsIcon /> | <SwapsIcon /> | ||||
| <SwapsTitle> | <SwapsTitle> | ||||
| {props.myOffers ? t("header.myOffers") : t("offer.offers")} | |||||
| {props?.myOffers ? t("header.myOffers") : t("offer.offers")} | |||||
| </SwapsTitle> | </SwapsTitle> | ||||
| </PageTitleContainer> | </PageTitleContainer> | ||||
| )} | )} | ||||
| skeleton: PropTypes.bool, | skeleton: PropTypes.bool, | ||||
| sorting: PropTypes.any, | sorting: PropTypes.any, | ||||
| isAdmin: PropTypes.bool, | isAdmin: PropTypes.bool, | ||||
| users: PropTypes.bool, | |||||
| }; | }; | ||||
| Header.defaultProps = { | Header.defaultProps = { | ||||
| isGrid: false, | isGrid: false, |
| 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}; | |||||
| } | |||||
| `; |
| offers={props.offers} | offers={props.offers} | ||||
| skeleton={props.skeleton} | skeleton={props.skeleton} | ||||
| isAdmin={props.isAdmin} | isAdmin={props.isAdmin} | ||||
| users={props.users} | |||||
| /> | /> | ||||
| <Offers | <Offers | ||||
| isGrid={isGrid} | isGrid={isGrid} | ||||
| offers={offers} | offers={offers} | ||||
| toggleFilters={props.toggleFilters} | toggleFilters={props.toggleFilters} | ||||
| isAdmin={props.isAdmin} | isAdmin={props.isAdmin} | ||||
| isUsers={props.users} | |||||
| users={props.allUsers} | |||||
| /> | /> | ||||
| </MarketPlaceContainer> | </MarketPlaceContainer> | ||||
| ); | ); | ||||
| offers: PropTypes.any, | offers: PropTypes.any, | ||||
| toggleFilters: PropTypes.func, | toggleFilters: PropTypes.func, | ||||
| isAdmin: PropTypes.bool, | isAdmin: PropTypes.bool, | ||||
| users: PropTypes.bool, | |||||
| allUsers: PropTypes.array, | |||||
| }; | |||||
| MarketPlace.defaultProps = { | |||||
| offers: { | |||||
| sorting: {}, | |||||
| filters: { | |||||
| numOfFiltersChosen: 0, | |||||
| }, | |||||
| }, | |||||
| }; | }; | ||||
| export default MarketPlace; | export default MarketPlace; |
| import React, { useCallback, useRef } from "react"; | |||||
| import React, { useCallback, useEffect, useRef } from "react"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import { EndIcon, SearchIcon, SearchInput } from "./HeadersMyOffers.styled"; | import { EndIcon, SearchIcon, SearchInput } from "./HeadersMyOffers.styled"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| }, | }, | ||||
| [searchRef.current] | [searchRef.current] | ||||
| ); | ); | ||||
| useEffect(() => { | |||||
| searchRef.current.value = search.searchString || ""; | |||||
| }, []); | |||||
| const handleFocusSearch = () => { | const handleFocusSearch = () => { | ||||
| searchRef.current.addEventListener("keyup", listener); | searchRef.current.addEventListener("keyup", listener); | ||||
| }; | }; | ||||
| </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; |
| 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); | ||||
| const offersRef = useRef(null); | const offersRef = useRef(null); | ||||
| const userId = useSelector(selectUserId); | const userId = useSelector(selectUserId); | ||||
| const offers = props.offers; | |||||
| const offers = props?.offers; | |||||
| // For skeleton screen | // For skeleton screen | ||||
| const arrayForMapping = Array.apply(null, Array(4)).map(() => {}); | const arrayForMapping = Array.apply(null, Array(4)).map(() => {}); | ||||
| startChat(chats, offer, userId); | startChat(chats, offer, userId); | ||||
| }; | }; | ||||
| const toggleFilters = () => { | const toggleFilters = () => { | ||||
| props.toggleFilters(); | |||||
| props?.toggleFilters(); | |||||
| }; | }; | ||||
| return ( | return ( | ||||
| <> | <> | ||||
| {!props.skeleton ? ( | |||||
| {!props?.skeleton ? ( | |||||
| <> | <> | ||||
| <FilterContainer | <FilterContainer | ||||
| isAdmin={props.isAdmin} | |||||
| isAdmin={props?.isAdmin} | |||||
| onClick={toggleFilters} | onClick={toggleFilters} | ||||
| number={offers.filters.numOfFiltersChosen} | |||||
| myOffers={props.myOffers} | |||||
| number={offers?.filters?.numOfFiltersChosen} | |||||
| myOffers={props?.myOffers} | |||||
| > | > | ||||
| <FilterIcon /> | <FilterIcon /> | ||||
| </FilterContainer> | </FilterContainer> | ||||
| {(props.myOffers || props.isAdmin) && ( | |||||
| {(props?.myOffers || props?.isAdmin) && ( | |||||
| <HeadersMyOffers | <HeadersMyOffers | ||||
| searchMyOffers={offers.search.searchOffers} | |||||
| handleSearch={offers.apply} | |||||
| isAdmin={props.isAdmin} | |||||
| searchMyOffers={offers?.search?.searchOffers} | |||||
| handleSearch={offers?.apply} | |||||
| 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} | |||||
| /> | |||||
| ); | |||||
| })} | |||||
| {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} | ||||
| current={parseInt(offers.paging.currentPage)} | |||||
| changePage={offers.paging.changePage} | |||||
| current={parseInt(offers?.paging?.currentPage)} | |||||
| changePage={offers?.paging?.changePage} | |||||
| /> | /> | ||||
| </OffersContainer> | </OffersContainer> | ||||
| )} | )} | ||||
| 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; |
| 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 /> |
| `; | `; | ||||
| 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}; | |||||
| } | |||||
| `; | `; |
| 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; |
| 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; | |||||
| `; |
| import { ReactComponent as CategoryIcon } from "../assets/images/svg/category.svg"; | import { ReactComponent as CategoryIcon } from "../assets/images/svg/category.svg"; | ||||
| import { ReactComponent as LocationIcon } from "../assets/images/svg/location.svg"; | import { ReactComponent as LocationIcon } from "../assets/images/svg/location.svg"; | ||||
| import { ReactComponent as DollarIcon } from "../assets/images/svg/dollar-sign.svg"; | import { ReactComponent as DollarIcon } from "../assets/images/svg/dollar-sign.svg"; | ||||
| import { ADMIN_USERS_PAGE } from "./pages"; | |||||
| export const ADMIN_NAVIGATION = [ | export const ADMIN_NAVIGATION = [ | ||||
| { text: "Korisnici", icon: <UserIcon />, route: "/admin/users" }, | |||||
| { text: "Korisnici", icon: <UserIcon />, route: `${ADMIN_USERS_PAGE}` }, | |||||
| { text: "Kategorije", icon: <CategoryIcon />, route: "/admin/categoires" }, | { text: "Kategorije", icon: <CategoryIcon />, route: "/admin/categoires" }, | ||||
| { text: "Lokacije", icon: <LocationIcon />, route: "/admin/locations" }, | { text: "Lokacije", icon: <LocationIcon />, route: "/admin/locations" }, | ||||
| { text: "Uplate", icon: <DollarIcon />, route: "/admin/payment" }, | { text: "Uplate", icon: <DollarIcon />, route: "/admin/payment" }, |
| export const ABOUT_PAGE = "/about"; | export const ABOUT_PAGE = "/about"; | ||||
| export const PRICES_PAGE = "/prices"; | export const PRICES_PAGE = "/prices"; | ||||
| export const POLICY_PRIVACY_PAGE = "/policy"; | export const POLICY_PRIVACY_PAGE = "/policy"; | ||||
| export const ADMIN_HOME_PAGE = "/admin/home"; | |||||
| export const ADMIN_HOME_PAGE = "/admin"; | |||||
| export const ADMIN_USERS_PAGE = "/admin/users"; |
| 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!", | ||||
| passwordRequired: "Lozinka je obavezna!", | passwordRequired: "Lozinka je obavezna!", | ||||
| wrongCredentials: "Pogrešan mail ili lozinka!", | wrongCredentials: "Pogrešan mail ili lozinka!", | ||||
| headerTitle: "Ulogujte se", | headerTitle: "Ulogujte se", | ||||
| } | |||||
| } | |||||
| }, | |||||
| users: { | |||||
| headerTitle: "Profili korisnika", | |||||
| searchPlaceholder: "Pretražite korisnike....", | |||||
| checkProfile: "Pogledaj profil", | |||||
| }, | |||||
| navigation: { | |||||
| role: "Administrator", | |||||
| menu: "Meni", | |||||
| logout: "Odjavi se", | |||||
| }, | |||||
| }, | |||||
| }; | }; |
| import React from "react"; | |||||
| import React, { useMemo } from "react"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import MarketPlace from "../../components/MarketPlace/MarketPlace"; | |||||
| import useOffers from "../../hooks/useOffers/useOffers"; | |||||
| // import MarketPlace from "../../components/MarketPlace/MarketPlace"; | |||||
| // import useOffers from "../../hooks/useOffers/useOffers"; | |||||
| import Sidebar from "../../components/Admin/Sidebar/Sidebar"; | import Sidebar from "../../components/Admin/Sidebar/Sidebar"; | ||||
| import { MainLayoutAdminHomePage } from "./AdminHomePage.styled"; | import { MainLayoutAdminHomePage } from "./AdminHomePage.styled"; | ||||
| import { useSelector } from "react-redux"; | |||||
| // import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; | |||||
| // import { OFFERS_SCOPE } from "../../store/actions/offers/offersActionConstants"; | |||||
| import AdminUsersPage from "../AdminUsersPage/AdminUsersPage"; | |||||
| import { selectMineProfile } from "../../store/selectors/profileSelectors"; | |||||
| import { Route, useHistory } from "react-router-dom"; | |||||
| import { ADMIN_USERS_PAGE, HOME_PAGE } from "../../constants/pages"; | |||||
| import { selectUserId } from "../../store/selectors/loginSelectors"; | |||||
| // import AdminRoute from "../../components/Router/AdminRoute"; | |||||
| const AdminHomePage = () => { | const AdminHomePage = () => { | ||||
| const offers = useOffers(); | |||||
| const profile = useSelector(selectMineProfile); | |||||
| const userId = useSelector(selectUserId); | |||||
| const history = useHistory(); | |||||
| const isUserLogin = useMemo(() => { | |||||
| if (userId?.length === 0) return false; | |||||
| return true; | |||||
| }, [userId]); | |||||
| if (!profile.roles.includes("Admin") || !isUserLogin) { | |||||
| history.push(HOME_PAGE); | |||||
| } | |||||
| // const offers = useOffers(); | |||||
| // const isLoadingOffers = useSelector( | |||||
| // selectIsLoadingByActionType(OFFERS_SCOPE) | |||||
| // ); | |||||
| return ( | return ( | ||||
| <MainLayoutAdminHomePage | <MainLayoutAdminHomePage | ||||
| leftCard={<Sidebar />} | leftCard={<Sidebar />} | ||||
| content={<MarketPlace offers={offers} isAdmin />} | |||||
| content={ | |||||
| // <MarketPlace offers={offers} isAdmin skeleton={isLoadingOffers} /> | |||||
| <> | |||||
| <Route path={ADMIN_USERS_PAGE} component={AdminUsersPage} /> | |||||
| <Route component={AdminUsersPage} /> | |||||
| </> | |||||
| } | |||||
| /> | /> | ||||
| ); | ); | ||||
| }; | }; |
| 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 = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const allUsers = useSelector(selectAllProfiles); | |||||
| useEffect(() => { | |||||
| dispatch(fetchAllProfiles()); | |||||
| }, []); | |||||
| return ( | |||||
| <MarketPlace | |||||
| isAdmin | |||||
| myOffers | |||||
| users | |||||
| allUsers={Array.isArray(allUsers) ? allUsers : []} | |||||
| /> | |||||
| ); | |||||
| }; | |||||
| AdminUsersPage.propTypes = { | |||||
| children: PropTypes.node, | |||||
| }; | |||||
| export default AdminUsersPage; |
| 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", |
| export const attemptLogin = (payload) => | export const attemptLogin = (payload) => | ||||
| postRequest(apiEndpoints.authentications.login, payload); | postRequest(apiEndpoints.authentications.login, payload); | ||||
| export const logoutUserRequest = (payload) => | export const logoutUserRequest = (payload) => | ||||
| postRequest(apiEndpoints.authentications.logout, payload); | postRequest(apiEndpoints.authentications.logout, payload); | ||||
| export const logoutAdminRequest = (payload) => | |||||
| postRequest(apiEndpoints.authentications.logout, payload); |
| 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 }) | |||||
| ); | |||||
| }; |
| 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); |
| createSuccessType, | createSuccessType, | ||||
| createSubmitType, | createSubmitType, | ||||
| createUpdateType, | createUpdateType, | ||||
| } from '../actionHelpers'; | |||||
| } from "../actionHelpers"; | |||||
| const LOGIN_USER_SCOPE = 'LOGIN_USER'; | |||||
| const LOGIN_USER_SCOPE = "LOGIN_USER"; | |||||
| export const LOGIN_USER_FETCH = createFetchType(LOGIN_USER_SCOPE); | export const LOGIN_USER_FETCH = createFetchType(LOGIN_USER_SCOPE); | ||||
| export const LOGIN_USER_SUCCESS = createSuccessType(LOGIN_USER_SCOPE); | export const LOGIN_USER_SUCCESS = createSuccessType(LOGIN_USER_SCOPE); | ||||
| export const LOGIN_USER_ERROR = createErrorType(LOGIN_USER_SCOPE); | export const LOGIN_USER_ERROR = createErrorType(LOGIN_USER_SCOPE); | ||||
| export const CLEAR_LOGIN_USER_ERROR = createClearType( | export const CLEAR_LOGIN_USER_ERROR = createClearType( | ||||
| `${LOGIN_USER_SCOPE}_ERROR`, | |||||
| `${LOGIN_USER_SCOPE}_ERROR` | |||||
| ); | ); | ||||
| export const LOGIN_USER_LOADING = createLoadingType(LOGIN_USER_SCOPE); | export const LOGIN_USER_LOADING = createLoadingType(LOGIN_USER_SCOPE); | ||||
| export const UPDATE_USER_JWT_TOKEN = createUpdateType("UPDATE_USER_JWT_TOKEN"); | |||||
| export const RESET_LOGIN_STATE = createClearType("UPDATE_USER_JWT_TOKEN"); | |||||
| export const AUTHENTICATE_USER = createUpdateType("AUTHENTICATE_USER"); | |||||
| export const LOGOUT_USER = createUpdateType("LOGOUT_USER"); | |||||
| export const LOGOUT_ADMIN = createUpdateType("LOGOUT_ADMIN"); | |||||
| export const REFRESH_TOKEN = createUpdateType("REFRESH_TOKEN"); | |||||
| export const UPDATE_USER_JWT_TOKEN = createUpdateType('UPDATE_USER_JWT_TOKEN'); | |||||
| export const RESET_LOGIN_STATE = createClearType('UPDATE_USER_JWT_TOKEN'); | |||||
| export const AUTHENTICATE_USER = createUpdateType('AUTHENTICATE_USER'); | |||||
| export const LOGOUT_USER = createUpdateType('LOGOUT_USER'); | |||||
| export const REFRESH_TOKEN = createUpdateType('REFRESH_TOKEN'); | |||||
| const GENERATE_TOKEN_SCOPE = 'GENERATE_TOKEN'; | |||||
| const GENERATE_TOKEN_SCOPE = "GENERATE_TOKEN"; | |||||
| export const GENERATE_TOKEN = createSubmitType(GENERATE_TOKEN_SCOPE); | export const GENERATE_TOKEN = createSubmitType(GENERATE_TOKEN_SCOPE); | ||||
| export const GENERATE_TOKEN_SUCCESS = createSuccessType(GENERATE_TOKEN_SCOPE); | export const GENERATE_TOKEN_SUCCESS = createSuccessType(GENERATE_TOKEN_SCOPE); | ||||
| export const GENERATE_TOKEN_ERROR = createErrorType(GENERATE_TOKEN_SCOPE); | export const GENERATE_TOKEN_ERROR = createErrorType(GENERATE_TOKEN_SCOPE); |
| GENERATE_TOKEN, | GENERATE_TOKEN, | ||||
| GENERATE_TOKEN_SUCCESS, | GENERATE_TOKEN_SUCCESS, | ||||
| GENERATE_TOKEN_ERROR, | GENERATE_TOKEN_ERROR, | ||||
| } from './loginActionConstants'; | |||||
| LOGOUT_ADMIN, | |||||
| } from "./loginActionConstants"; | |||||
| export const fetchLogin = (payload) => ({ | export const fetchLogin = (payload) => ({ | ||||
| type: LOGIN_USER_FETCH, | type: LOGIN_USER_FETCH, | ||||
| payload, | payload, | ||||
| }); | }); | ||||
| export const logoutAdmin = (payload) => ({ | |||||
| type: LOGOUT_ADMIN, | |||||
| payload, | |||||
| }); | |||||
| export const refreshUserToken = (payload) => ({ | export const refreshUserToken = (payload) => ({ | ||||
| type: REFRESH_TOKEN, | type: REFRESH_TOKEN, | ||||
| payload | |||||
| payload, | |||||
| }); | }); | ||||
| export const generateToken = (payload) => ({ | export const generateToken = (payload) => ({ |
| 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); |
| 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, |
| 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); |
| 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, |
| 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, | |||||
| }; | |||||
| } |
| import { | import { | ||||
| AUTHENTICATE_USER, | AUTHENTICATE_USER, | ||||
| LOGIN_USER_FETCH, | LOGIN_USER_FETCH, | ||||
| LOGOUT_ADMIN, | |||||
| LOGOUT_USER, | LOGOUT_USER, | ||||
| REFRESH_TOKEN, | REFRESH_TOKEN, | ||||
| } from "../actions/login/loginActionConstants"; | } from "../actions/login/loginActionConstants"; | ||||
| import { attemptLogin, logoutUserRequest } from "../../request/loginRequest"; | |||||
| import { | |||||
| attemptLogin, | |||||
| logoutAdminRequest, | |||||
| logoutUserRequest, | |||||
| } from "../../request/loginRequest"; | |||||
| import { | import { | ||||
| fetchUserError, | fetchUserError, | ||||
| fetchUserSuccess, | fetchUserSuccess, | ||||
| resetLoginState, | resetLoginState, | ||||
| setUserJwtToken, | setUserJwtToken, | ||||
| } from "../actions/login/loginActions"; | } from "../actions/login/loginActions"; | ||||
| import { LOGIN_PAGE } from "../../constants/pages"; | |||||
| import { ADMIN_LOGIN_PAGE, LOGIN_PAGE } from "../../constants/pages"; | |||||
| import { addHeaderToken, removeHeaderToken } from "../../request"; | import { addHeaderToken, removeHeaderToken } from "../../request"; | ||||
| import { | import { | ||||
| JWT_REFRESH_TOKEN, | JWT_REFRESH_TOKEN, | ||||
| yield put(clearChat()); | yield put(clearChat()); | ||||
| } | } | ||||
| } | } | ||||
| function* logoutAdmin(payload) { | |||||
| try { | |||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | |||||
| const user = yield call(jwt.decode, JwtToken); | |||||
| if (user) { | |||||
| const requestBody = { token: JwtToken }; | |||||
| yield call(logoutAdminRequest, requestBody); | |||||
| yield call(payload.payload); | |||||
| } | |||||
| } catch (error) { | |||||
| console.dir(error); // eslint-disable-line | |||||
| } finally { | |||||
| yield call(authScopeClearHelper); | |||||
| yield call(removeHeaderToken); | |||||
| yield put(resetLoginState()); | |||||
| yield call(history.replace, ADMIN_LOGIN_PAGE); | |||||
| yield put(clearProfile()); | |||||
| yield put(clearOffers()); | |||||
| yield put(clearChat()); | |||||
| } | |||||
| } | |||||
| function* refreshUserToken({ payload }) { | function* refreshUserToken({ payload }) { | ||||
| try { | try { | ||||
| const newTokenDecoded = jwt.decode(payload); | const newTokenDecoded = jwt.decode(payload); | ||||
| takeLatest(AUTHENTICATE_USER, authenticateUser), | takeLatest(AUTHENTICATE_USER, authenticateUser), | ||||
| takeLatest(LOGOUT_USER, logout), | takeLatest(LOGOUT_USER, logout), | ||||
| takeLatest(REFRESH_TOKEN, refreshUserToken), | takeLatest(REFRESH_TOKEN, refreshUserToken), | ||||
| takeLatest(LOGOUT_ADMIN, logoutAdmin), | |||||
| ]); | ]); | ||||
| } | } |
| 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), | ||||
| ]); | ]); | ||||
| } | } |
| 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), | |||||
| ]); | ]); | ||||
| } | } |
| profileSelector, | profileSelector, | ||||
| (state) => state?.mineProfile?.image | (state) => state?.mineProfile?.image | ||||
| ); | ); | ||||
| export const selectAllProfiles = createSelector( | |||||
| profileSelector, | |||||
| (state) => state.allProfiles | |||||
| ); |
| import { | import { | ||||
| ADMIN_HOME_PAGE, | ADMIN_HOME_PAGE, | ||||
| ADMIN_LOGIN_PAGE, | ADMIN_LOGIN_PAGE, | ||||
| ADMIN_USERS_PAGE, | |||||
| FORGOT_PASSWORD_MAIL_SENT, | FORGOT_PASSWORD_MAIL_SENT, | ||||
| FORGOT_PASSWORD_PAGE, | FORGOT_PASSWORD_PAGE, | ||||
| LOGIN_PAGE, | LOGIN_PAGE, | ||||
| return false; | return false; | ||||
| }; | }; | ||||
| export const isAdminRoute = () => { | export const isAdminRoute = () => { | ||||
| if (routeMatches(ADMIN_LOGIN_PAGE) || routeMatches(ADMIN_HOME_PAGE)) | |||||
| if ( | |||||
| routeMatches(ADMIN_LOGIN_PAGE) || | |||||
| routeMatches(ADMIN_HOME_PAGE) || | |||||
| routeMatches(ADMIN_USERS_PAGE) | |||||
| ) | |||||
| return true; | return true; | ||||
| return false; | return false; | ||||
| }; | }; |