Переглянути джерело

Partly finished feature 701

feature/701
djordjemitrovic00 3 роки тому
джерело
коміт
e0d5498056
27 змінених файлів з 366 додано та 177 видалено
  1. 3
    3
      src/assets/images/svg/block.svg
  2. 14
    0
      src/assets/images/svg/unblock-gold.svg
  3. 14
    0
      src/assets/images/svg/unblock.svg
  4. 17
    4
      src/components/Cards/OfferCard/OfferCard.styled.js
  5. 6
    5
      src/components/Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard.js
  6. 33
    14
      src/components/Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard.styled.js
  7. 24
    5
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js
  8. 13
    0
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js
  9. 57
    6
      src/components/Cards/ProfileCard/ProfileCard.js
  10. 90
    74
      src/components/Cards/ProfileCard/ProfileCard.styled.js
  11. 13
    1
      src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.js
  12. 13
    1
      src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.styled.js
  13. 2
    1
      src/components/Header/Header.styled.js
  14. 2
    0
      src/components/Header/SearchInput/SearchInput.js
  15. 2
    17
      src/components/Header/SearchInput/SearchInput.styled.js
  16. 5
    7
      src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.styled.js
  17. 4
    4
      src/components/Modals/DeleteCategory/DeleteCategory.styled.js
  18. 12
    15
      src/hooks/useOffers/useOffers.js
  19. 8
    0
      src/i18n/resources/rs.js
  20. 0
    12
      src/layouts/ItemDetailsLayout/ItemDetailsLayout.styled.js
  21. 2
    2
      src/layouts/MainLayout/MainLayout.js
  22. 2
    0
      src/store/actions/admin/adminActionConstants.js
  23. 4
    0
      src/store/actions/admin/adminActions.js
  24. 13
    4
      src/store/saga/profileSaga.js
  25. 2
    0
      src/themes/primaryTheme/primaryThemeColors.js
  26. 9
    0
      src/util/helpers/hexToRgb.js
  27. 2
    2
      src/util/helpers/queryHelpers.js

+ 3
- 3
src/assets/images/svg/block.svg Переглянути файл

@@ -1,10 +1,10 @@
<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)">
<g clip-path="url(#clip0_2930_12933)">
<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"/>
<path d="M6 9H12" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_1412_9649">
<clipPath id="clip0_2930_12933">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>

+ 14
- 0
src/assets/images/svg/unblock-gold.svg Переглянути файл

@@ -0,0 +1,14 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2944_12839)">
<path d="M10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5Z" stroke="#FEB005" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 10H13" stroke="#FEB005" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<path d="M1 17.5L17.5 0.999999" stroke="#5A3984" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 18.5L19.5 2" stroke="#5A3984" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.74927 18.2505L18.2493 1.75049" stroke="#FEB005" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<clipPath id="clip0_2944_12839">
<rect width="18" height="18" fill="white" transform="translate(1 1)"/>
</clipPath>
</defs>
</svg>

+ 14
- 0
src/assets/images/svg/unblock.svg Переглянути файл

@@ -0,0 +1,14 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2930_12825)">
<path d="M10 17.5C14.1421 17.5 17.5 14.1421 17.5 10C17.5 5.85786 14.1421 2.5 10 2.5C5.85786 2.5 2.5 5.85786 2.5 10C2.5 14.1421 5.85786 17.5 10 17.5Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7 10H13" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<path d="M1 17.5L17.5 0.999999" stroke="#E4E4E4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 18.5L19.5 2" stroke="#E4E4E4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.74902 18.2505L18.249 1.75049" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<clipPath id="clip0_2930_12825">
<rect width="18" height="18" fill="white" transform="translate(1 1)"/>
</clipPath>
</defs>
</svg>

+ 17
- 4
src/components/Cards/OfferCard/OfferCard.styled.js Переглянути файл

@@ -164,7 +164,17 @@ export const OfferDetails = styled(Box)`
flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")};
justify-content: start;
gap: 1rem;
@media (max-width: 760px) {
@media (max-width: 1150px) {
flex-direction: column;
justify-content: center;
gap: 0;
}
@media (max-width: 900px) {
gap: 1rem;
justify-content: start;
flex-direction: row;
}
@media (max-width: 800px) {
flex-direction: column;
justify-content: center;
gap: 0;
@@ -372,7 +382,9 @@ export const PinIconContainer = styled(MessageIcon)`
right: 134px;
top: 18px;
@media (max-width: 600px) {
${props => props.vertical && `
${(props) =>
props.vertical &&
`
display: block;
top: initial;
right: initial;
@@ -421,13 +433,14 @@ export const PinIcon = styled(Pin)`
@media (max-width: 600px) {
top: 20px;
right: 55px;
${props => props.vertical && `
${(props) =>
props.vertical &&
`
top: initial;
bottom: 18px;
right: 18px;
`}
}
`;
export const CategoryIcon = styled(Category)`
width: 14px;

+ 6
- 5
src/components/Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard.js Переглянути файл

@@ -19,7 +19,7 @@ import {
SkeletonOfferCardContainer,
SkeletonRowGroup,
SkeletonTitle,
// SkeletonTitleAboveImage,
SkeletonTitleAboveImage,
SpreadLine,
} from "./SkeletonOfferCard.styled";
import useIsMobile from "../../../../hooks/useIsMobile";
@@ -29,6 +29,7 @@ const SkeletonOfferCard = (props) => {
return (
<SkeletonOfferCardsContainer>
<SkeletonOfferCardContainer skeleton={props.skeleton}>
<SkeletonTitleAboveImage />
<LeftPart>
<SkeletonImage />
<SkeletonColumnContainer>
@@ -41,6 +42,7 @@ const SkeletonOfferCard = (props) => {
<SkeletonDetail />
<SkeletonDetail />
<SkeletonDetail />
<SkeletonDetail />
</SkeletonRowGroup>
</SkeletonColumnContainer>
</LeftPart>
@@ -57,9 +59,8 @@ const SkeletonOfferCard = (props) => {
</SkeletonExchangeButton>
<SkeletonMessageButton />
{isMobile && <SkeletonMessageButtonSecond />}
{/* <SkeletonTitleAboveImage /> */}
</SkeletonOfferCardContainer>
{isMobile && (
{/* {isMobile && (
<SkeletonOfferCardContainer skeleton={props.skeleton}>
<LeftPart>
<SkeletonImage />
@@ -89,9 +90,9 @@ const SkeletonOfferCard = (props) => {
</SkeletonExchangeButton>
<SkeletonMessageButton />
{isMobile && <SkeletonMessageButtonSecond />}
{/* <SkeletonTitleAboveImage /> */}
<SkeletonTitleAboveImage />
</SkeletonOfferCardContainer>
)}
)} */}
</SkeletonOfferCardsContainer>
);
};

+ 33
- 14
src/components/Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard.styled.js Переглянути файл

@@ -29,7 +29,7 @@ export const SkeletonOfferCardContainer = styled(BackgroundTransition)`
}

@media (max-width: 550px) {
height: 184px;
height: 194px;
padding: 18px;
padding-top: 12px;
${(props) =>
@@ -40,11 +40,11 @@ export const SkeletonOfferCardContainer = styled(BackgroundTransition)`
margin: 0 18px;
`}
}
@media (max-width: 600px) {
/* @media (max-width: 600px) {
width: 180px;
height: 373px;
margin-right: 18px;
}
} */
`;
export const LeftPart = styled(Box)`
display: flex;
@@ -52,8 +52,11 @@ export const LeftPart = styled(Box)`
flex-direction: row;
margin-right: 40px;
@media (max-width: 600px) {
flex-direction: column;
gap: 18px;
}
/* @media (max-width: 600px) {
flex-direction: column;
} */
`;
export const SpreadLine = styled(Box)`
height: 108px;
@@ -61,7 +64,7 @@ export const SpreadLine = styled(Box)`
margin-bottom: auto;
opacity: 0.12;
border: 1px solid black;
@media (max-width: 600px) {
@media (max-width: 1050px) {
display: none;
}
`;
@@ -72,13 +75,18 @@ export const RightPart = styled(Box)`
gap: 4px;
margin-left: 36px;
padding-top: 20px;
@media (max-width: 600px) {
@media (max-width: 1050px) {
display: none;
}
`;
export const SkeletonImage = styled(ItemsTransition)`
width: 144px;
height: 144px;
@media (max-width: 600px) {
margin-top: 54px;
width: 108px;
height: 108px;
}
`;
export const SkeletonColumnContainer = styled(Box)`
display: flex;
@@ -108,20 +116,24 @@ export const SkeletonGroup = styled(Box)`
export const SkeletonAuthor = styled(ItemsTransition)`
width: 117px;
height: 18px;
@media (max-width: 600px) {
visibility: hidden;
}
`;
export const SkeletonLocation = styled(ItemsTransition)`
width: 90px;
height: 18px;

@media (max-width: 600px) {
width: 100px;
margin-top: 36px;
width: 117px;
margin-top: 26px;
}
`;
export const SkeletonRowGroup = styled(Box)`
display: flex;
flex-direction: row;
justify-content: space-between;
& div:nth-child(4) {display: none;}
@media (max-width: 600px) {
flex-direction: column;
gap: 4px;
@@ -130,12 +142,18 @@ export const SkeletonRowGroup = styled(Box)`
}
& div:nth-child(1) {
display: block;
width: 85px;
width: 90px;
margin-top: 4px;
${(props) => props.aboveChat && `margin-bottom: 18px;`}
}
& div:nth-child(2) {
display: ${(props) => (props.aboveChat ? "none" : "block")};
width: 85px;
}
& div:nth-child(4) {
display: block;
margin-top: 0;
}
}
`;
@@ -157,6 +175,9 @@ export const SkeletonDescriptionLine = styled(ItemsTransition)`
width: 221px;
height: 18px;
background-color: ${selectedTheme.colors.filterSkeletonItems};
@media (max-width: 1400px) {
${props => props.removeOnSmallerScreens && `display: none;`}
}
`;
export const SkeletonMessageButton = styled(ItemsTransition)`
width: 40px;
@@ -169,8 +190,6 @@ export const SkeletonMessageButton = styled(ItemsTransition)`
@media (max-width: 600px) {
width: 32px;
height: 32px;
top: 323px;
left: 18px;
}
`;
export const SkeletonMessageButtonSecond = styled(ItemsTransition)`
@@ -184,8 +203,8 @@ export const SkeletonMessageButtonSecond = styled(ItemsTransition)`
@media (max-width: 600px) {
width: 32px;
height: 32px;
top: 323px;
left: 59px;
/* top: 323px; */
/* left: 59px; */
}
`;
export const SkeletonExchangeButton = styled(ItemsTransition)`
@@ -196,7 +215,7 @@ export const SkeletonExchangeButton = styled(ItemsTransition)`
right: 18px;
position: absolute;
padding-top: 17px;
@media (max-width: 600px) {
@media (max-width: 1400px) {
display: none;
}
`;

+ 24
- 5
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js Переглянути файл

@@ -13,6 +13,9 @@ import {
ProfileInfoContainer,
RemoveIcon,
RemoveIconContainer,
UnblockIcon,
UnblockIconContainer,
UnblockLabelIcon,
} from "./BigProfileCard.styled";
import ProfileMainInfo from "../ProfileMainInfo/ProfileMainInfo";
import ProfileContact from "../ProfileContact/ProfileContact";
@@ -49,6 +52,12 @@ const BigProfileCard = (props) => {
type: "blockUser",
});
};
const unblockUser = () => {
setDeleteOrEditModal({
show: true,
type: "unblockUser",
});
};
const goToUser = () => {
history.push(
replaceInRoute(ADMIN_SINGLE_USER_PAGE, {
@@ -67,13 +76,19 @@ const BigProfileCard = (props) => {
<RemoveIconContainer onClick={removeUser}>
<RemoveIcon />
</RemoveIconContainer>
<BlockIconContainer onClick={blockUser}>
<BlockIcon />
</BlockIconContainer>
{props.profile?._blocked ? (
<UnblockIconContainer onClick={unblockUser}>
<UnblockIcon />
</UnblockIconContainer>
) : (
<BlockIconContainer onClick={blockUser}>
<BlockIcon />
</BlockIconContainer>
)}
</ButtonsContainer>
<ProfileInfoContainer>
{/* Profile Main Info */}
<ProfileMainInfo profile={props.profile} isAdmin />
<ProfileMainInfo profile={props.profile} isAdmin bigProfileCard />
{/* Profile Contact */}
<ProfileContact profile={props.profile} isAdmin />
</ProfileInfoContainer>
@@ -106,7 +121,11 @@ const BigProfileCard = (props) => {
customLabeledCard={<UserLabeledCard user={props.profile} />}
customLabeledCardHeight="90px"
customLabeledCardIcon={
deleteOrEditModal.type === "blockUser" && <BlockLabelIcon />
deleteOrEditModal.type === "blockUser" ? (
<BlockLabelIcon />
) : (
<UnblockLabelIcon />
)
}
/>
)}

+ 13
- 0
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js Переглянути файл

@@ -7,6 +7,8 @@ import { ReactComponent as Edit } from "../../../../assets/images/svg/edit.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 { ReactComponent as Unblock } from "../../../../assets/images/svg/unblock.svg";
import { ReactComponent as UnblockGold } from "../../../../assets/images/svg/unblock-gold.svg";
import { IconButton } from "../../../Buttons/IconButton/IconButton";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
// import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";
@@ -110,6 +112,10 @@ export const BlockIconContainer = styled(MessageButton)`
display: block;
`;
export const BlockIcon = styled(Block)``;
export const UnblockIconContainer = styled(MessageButton)`
display: block;
`;
export const UnblockIcon = styled(Unblock)``;
export const BlockLabelIcon = styled(Block)`
width: 18px;
height: 18px;
@@ -120,6 +126,13 @@ export const BlockLabelIcon = styled(Block)`
stroke: ${selectedTheme.colors.iconYellowColor};
}
`;
export const UnblockLabelIcon = styled(UnblockGold)`
width: 18px;
height: 18px;
position: relative;
top: 10px;
left: 11px;
`;
export const CheckButton = styled(PrimaryButton)`
width: 180px;
height: 48px;

+ 57
- 6
src/components/Cards/ProfileCard/ProfileCard.js Переглянути файл

@@ -17,6 +17,13 @@ import {
MessageButton,
MessageIcon,
ProfileInfoAndContactContainer,
UnblockButton,
UnblockIcon,
BlockedProfileText,
BlockedIcon,
BlockedProfileTextContainer,
BlockedIconContainer,
BlockedContainer,
} from "./ProfileCard.styled";
import PersonOutlineIcon from "@mui/icons-material/PersonOutline";
import { useRouteMatch } from "react-router-dom";
@@ -39,6 +46,8 @@ import { useMemo } from "react";
import companyData from "../../../notFoundData/companyData";
import DeleteCategory from "../../Modals/DeleteCategory/DeleteCategory";
import UserLabeledCard from "../LabeledCard/User/UserLabeledCard";
import history from "../../../store/utils/history";
import { HOME_PAGE } from "../../../constants/pages";

const ProfileCard = (props) => {
const [editProfileModal, setEditProfileModal] = useState(false);
@@ -75,6 +84,12 @@ const ProfileCard = (props) => {
reFetchProfile();
}
}, [idProfile]);
useEffect(() => {
if (profile && isMyProfile !== undefined) {
if (!isMyProfile && profile._blocked && !props.isAdmin)
history.push(HOME_PAGE);
}
}, [profile, isMyProfile, props.isAdmin]);

const reFetchProfile = () => {
dispatch(fetchProfile(idProfile));
@@ -108,6 +123,15 @@ const ProfileCard = (props) => {
type: "blockUser",
});
};
const unblockUser = () => {
setDeleteOrEditModal({
show: true,
type: "unblockUser",
});
};
const handleEditProfile = () => {
if (!profile?._blocked) setEditProfileModal(true);
};

if (editProfileModal) {
document.body.style.overflow = "hidden";
@@ -130,13 +154,35 @@ const ProfileCard = (props) => {
: t("profile.companyProfile")}
</HeaderTitle>
</ProfileCardHeader>
<ProfileCardWrapper variant="outlined" isMyProfile={isMyProfile}>
<ProfileCardWrapper
variant="outlined"
isMyProfile={isMyProfile}
blocked={profile?._blocked}
>
<ButtonsContainer>
{profile?._blocked && (
<BlockedContainer>
<BlockedProfileTextContainer>
<BlockedProfileText>
{t("profile.blockedProfile")}
</BlockedProfileText>
</BlockedProfileTextContainer>
<BlockedIconContainer>
<BlockedIcon />
</BlockedIconContainer>
</BlockedContainer>
)}
{props.isAdmin && (
<>
<BlockButton onClick={blockUser}>
<BlockIcon />
</BlockButton>
{profile?._blocked ? (
<UnblockButton onClick={unblockUser}>
<UnblockIcon />
</UnblockButton>
) : (
<BlockButton onClick={blockUser}>
<BlockIcon />
</BlockButton>
)}
<RemoveButton onClick={removeUser}>
<RemoveIcon />
</RemoveButton>
@@ -144,8 +190,9 @@ const ProfileCard = (props) => {
)}
{isMyProfile || props.isAdmin ? (
<EditButton
onClick={() => setEditProfileModal(true)}
onClick={handleEditProfile}
isAdmin={props.isAdmin}
disabled={!props.isAdmin && profile?._blocked}
>
<EditIcon />
</EditButton>
@@ -161,9 +208,13 @@ const ProfileCard = (props) => {
<ProfileMainInfo
profile={profile}
isMyProfile={isMyProfile}
isBlocked={profile?._blocked}
/>
{/* Profile Contact */}
<ProfileContact profile={profile} isMyProfile={isMyProfile} />
<ProfileContact
profile={profile}
isMyProfile={profile?._blocked || isMyProfile}
/>
</ProfileInfoAndContactContainer>
{/* Profile Stats */}
<ProfileStats

+ 90
- 74
src/components/Cards/ProfileCard/ProfileCard.styled.js Переглянути файл

@@ -1,14 +1,11 @@
import styled from "styled-components";
import styled, { css } 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 Block } from "../../../assets/images/svg/block.svg";
import { ReactComponent as Unblock } from "../../../assets/images/svg/unblock.svg";
import { ReactComponent as Remove } from "../../../assets/images/svg/trash.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 Location } from "../../assets/images/svg/location.svg";
// import { PRIMARY_PURPLE_COLOR, PRIMARY_YELLOW_COLOR } from '../../constants/stylesConstants';

export const ProfileCardContainer = styled(Box)`
width: 100%;
@@ -21,7 +18,7 @@ export const ProfileCardContainer = styled(Box)`
padding: 0 36px 0 0;
}
@media (max-width: 600px) {
padding: 0 ${props => props.isAdmin ? "18px" : "0"};
padding: 0 ${(props) => (props.isAdmin ? "18px" : "0")};
}
`;
export const EditIcon = styled(Edit)`
@@ -45,7 +42,14 @@ export const EditButton = styled(Box)`
background: ${selectedTheme.colors.primaryIconBackgroundColor};
border-radius: 360px;
padding: 0.45rem 0.45rem 0.27rem 0.57rem;
cursor: pointer;
cursor: ${(props) => !props.disabled && `pointer`};
${(props) =>
props.disabled &&
css`
& path {
stroke: ${selectedTheme.colors.iconStrokePurpleDisabledColor};
}
`}
@media (max-width: 600px) {
width: 32px;
height: 32px;
@@ -78,10 +82,46 @@ export const RemoveButton = styled(Box)`
height: 32px;
}
`;
export const BlockIcon = styled(Block)`

export const BlockLabelIcon = styled(Block)`
width: 18px;
height: 18px;
position: relative;
top: 10px;
left: 11px;
& path {
stroke: ${selectedTheme.colors.iconYellowColor};
}
`;
export const BlockedProfileTextContainer = styled(Box)`
display: flex;
flex-direction: column;
height: 40px;
justify-content: center;
`;
export const BlockedProfileText = styled(Typography)`
font-style: italic;
font-weight: 400;
font-size: 12px;
line-height: 16px;
font-family: ${selectedTheme.fonts.textFont};
color: white;
`;
export const BlockedContainer = styled(Box)`
display: flex;
flex-direction: row;
gap: 9px;
`;
export const BlockedIconContainer = styled(Box)`
display: flex;
flex-direction: column;
height: 40px;
justify-content: center;
`;
export const BlockedIcon = styled(Block)`
/* position: relative;
top: 3px;
left: 2px;
left: 2px; */
width: 18px;
height: 18px;
@media (max-width: 600px) {
@@ -89,20 +129,38 @@ export const BlockIcon = styled(Block)`
left: -2px;
}
& path {
stroke: ${selectedTheme.colors.primaryPurple};
stroke: white;
}
`;
export const BlockLabelIcon = styled(Block)`

export const BlockButton = styled(Box)`
width: 40px;
height: 40px;
font-weight: 900;
background: ${selectedTheme.colors.primaryIconBackgroundColor};
border-radius: 360px;
padding: 0.45rem 0.45rem 0.27rem 0.57rem;
cursor: pointer;
@media (max-width: 600px) {
width: 32px;
height: 32px;
}
`;
export const BlockIcon = styled(Block)`
position: relative;
top: 3px;
left: 2px;
width: 18px;
height: 18px;
position: relative;
top: 10px;
left: 11px;
@media (max-width: 600px) {
top: 0;
left: -2px;
}
& path {
stroke: ${selectedTheme.colors.iconYellowColor};
stroke: ${selectedTheme.colors.primaryPurple};
}
`;
export const BlockButton = styled(Box)`
export const UnblockButton = styled(Box)`
width: 40px;
height: 40px;
font-weight: 900;
@@ -115,7 +173,17 @@ export const BlockButton = styled(Box)`
height: 32px;
}
`;

export const UnblockIcon = styled(Unblock)`
position: relative;
top: 3px;
left: 2px;
width: 18px;
height: 18px;
@media (max-width: 600px) {
top: 0;
left: -2px;
}
`;
export const MessageButton = styled(EditButton)`
background: ${selectedTheme.colors.primaryPurple};
width: 40px;
@@ -141,7 +209,11 @@ export const ButtonsContainer = styled(Box)`
export const ProfileCardWrapper = styled(Card)`
border: 1px solid ${selectedTheme.colors.borderNormal};
background: ${(props) =>
props.isMyProfile ? selectedTheme.colors.primaryPurple : "white"};
props.blocked
? selectedTheme.colors.blockedColor
: props.isMyProfile
? selectedTheme.colors.primaryPurple
: "white"};
width: 100%;
min-width: fit-content;
padding: 1rem;
@@ -280,62 +352,6 @@ export const HeaderTitle = styled(Typography)`
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;

+ 13
- 1
src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.js Переглянути файл

@@ -9,6 +9,7 @@ import {
ProfilePIBContainer,
PocketIcon,
ProfilePIB,
BlockedProfileText,
} from "./ProfileMainInfo.styled";
import { useTranslation } from "react-i18next";
import { getImageUrl, variants } from "../../../../util/helpers/imageUrlGetter";
@@ -32,6 +33,7 @@ const ProfileMainInfo = (props) => {
);
}
};
if (props.profile?.blocked) console.log(props.profile);
return (
<ProfileMainInfoContainer>
<AvatarImageContainer>
@@ -45,9 +47,17 @@ const ProfileMainInfo = (props) => {
/>
</AvatarImageContainer>
<ProfileMainInfoGrid>
{props.bigProfileCard && (props.profile?._deleted ? (
<BlockedProfileText>{t("profile.deletedProfile")}</BlockedProfileText>
) : props.profile?._blocked ? (
<BlockedProfileText>{t("profile.blockedProfile")}</BlockedProfileText>
) : (
<></>
))}
<ProfileName
isAdmin={props.isAdmin}
isMyProfile={props.isMyProfile}
isBlocked={props.isBlocked}
variant="h5"
onClick={goToUser}
>
@@ -55,7 +65,7 @@ const ProfileMainInfo = (props) => {
</ProfileName>
<ProfilePIBContainer>
<PocketIcon />
<ProfilePIB isMyProfile={props.isMyProfile} variant="subtitle2">
<ProfilePIB isMyProfile={props?.isBlocked || props.isMyProfile} variant="subtitle2">
{t("profile.PIB")} {props.profile?.company?.PIB}
</ProfilePIB>
</ProfilePIBContainer>
@@ -69,6 +79,8 @@ ProfileMainInfo.propTypes = {
isMyProfile: PropTypes.bool,
children: PropTypes.node,
isAdmin: PropTypes.any,
bigProfileCard: PropTypes.bool,
isBlocked: PropTypes.bool,
};

export default ProfileMainInfo;

+ 13
- 1
src/components/Cards/ProfileCard/ProfileMainInfo/ProfileMainInfo.styled.js Переглянути файл

@@ -32,6 +32,16 @@ export const AvatarImage = styled.img`
height: ${(props) => (props.isAdmin ? "108px" : "90px")};
}
`;

export const BlockedProfileText = styled(Typography)`
font-style: italic;
font-weight: 400;
font-size: 12px;
line-height: 16px;
font-family: ${selectedTheme.fonts.textFont};
color: ${selectedTheme.colors.blockedColor};
`;

export const ProfileMainInfoGrid = styled(Grid)`
display: flex;
flex-direction: column;
@@ -43,7 +53,9 @@ export const ProfileMainInfoGrid = styled(Grid)`
`;
export const ProfileName = styled(Typography)`
color: ${(props) =>
props.isMyProfile
props.isBlocked
? "white"
: props.isMyProfile
? selectedTheme.colors.primaryYellow
: selectedTheme.colors.primaryPurple};
font-weight: 700;

+ 2
- 1
src/components/Header/Header.styled.js Переглянути файл

@@ -17,6 +17,7 @@ export const LogoContainer = styled(Box)`
justify-content: center;
align-items: center;
cursor: pointer;
max-width: 130px;
svg {
width: 90%;
}
@@ -42,7 +43,7 @@ export const ToolsButtonsContainer = styled(Box)`
min-width: ${(props) => (props.shrink ? "0" : "400px")};
}
@media (max-width: 900px) {
flex: 0.35;
flex: 0.2;
min-width: 0px;
width: 60px;
justify-content: right;

+ 2
- 0
src/components/Header/SearchInput/SearchInput.js Переглянути файл

@@ -25,6 +25,8 @@ const SearchInput = forwardRef((props, ref) => {
};
const listener = useCallback(
(event) => {
console.log(event);
console.log(ref);
if (event.keyCode === 13) {
event.preventDefault();
handleManualSearch();

+ 2
- 17
src/components/Header/SearchInput/SearchInput.styled.js Переглянути файл

@@ -6,10 +6,8 @@ import { Icon } from "../../Icon/Icon";

export const SearchInputContainer = styled(TextField)`
background-color: ${selectedTheme.colors.primaryBackgroundColor};
width: 45%;
flex: 3;
flex: 1;
max-width: 520px;
margin-right: 30px;
font-family: ${selectedTheme.fonts.textFont};
@media (max-width: 1700px) {
margin-left: 15%;
@@ -20,28 +18,15 @@ export const SearchInputContainer = styled(TextField)`
@media (max-width: 1320px) {
margin-left: 7%;
}
@media (max-width: 1100px) {
width: 36%;
}
@media (max-width: 1000px) {
width: 36%;
@media (max-width: 1250px) {
margin-left: 5%;
margin-right: 10px;
}
@media (max-width: 550px) {
/* display: none; */
/* width: 0; */
display: block;
/* position: relative; */
width: 80%;
/* top: 70px; */
height: 46px;
margin-right: 27px;
/* left: -5px; */
font-family: ${selectedTheme.fonts.textFont};
/* ${(props) => !props.shouldShow && `display: none;`} */
& div {
/* background-color: white; */
height: 46px;
overflow: visible;
& input {

+ 5
- 7
src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.styled.js Переглянути файл

@@ -33,16 +33,14 @@ const skeletonBackgroundAnimation = keyframes`
export const SkeletonItemDetailsContainer = styled(Box)`
display: flex;
flex-direction: column;
margin-left: 36px;
margin-right: -36px;
/* margin-left: 36px; */
/* margin-right: -36px; */
max-width: 45vw;

@media (max-width: 1200px) {
@media (max-width: 600px) {
margin-left: 0;
margin-right: 0;
}

@media (max-width: 600px) {
margin-top: 180px;
max-width: none;
}
`;


+ 4
- 4
src/components/Modals/DeleteCategory/DeleteCategory.styled.js Переглянути файл

@@ -7,12 +7,12 @@ import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
export const DeleteCategoryContainer = styled(Box)`
width: 537px;
height: ${(props) =>
["blockUser", "deleteUser"].includes(props.type) ? "309px" : "274px"};
["blockUser", "unblockUser", "deleteUser"].includes(props.type) ? "309px" : "274px"};
position: fixed;
z-index: 150;
left: calc(50vw - 268px);
top: ${(props) =>
["blockUser", "deleteUser"].includes(props.type)
["blockUser", "unblockUser", "deleteUser"].includes(props.type)
? `calc(50vh - 153px)`
: `calc(50vh - 137px)`};
padding-top: 36px;
@@ -26,9 +26,9 @@ export const DeleteCategoryContainer = styled(Box)`
width: 350px;
left: calc(50vw - 175px);
height: ${(props) =>
["blockUser", "deleteUser"].includes(props.type) ? "281px" : "246px"};
["blockUser", "unblockUser", "deleteUser"].includes(props.type) ? "281px" : "246px"};
top: ${(props) =>
["blockUser", "deleteUser"].includes(props.type)
["blockUser", "unblockUser", "deleteUser"].includes(props.type)
? `calc(50vh - 140px)`
: `calc(50vh - 123px)`};
}

+ 12
- 15
src/hooks/useOffers/useOffers.js Переглянути файл

@@ -138,19 +138,6 @@ const useOffers = () => {
console.log("applyfilters");
setFiltersCleared(true);
};
// const applySorting = () => {
// filters.apply();
// console.log("ovde");
// const newQueryString = makeQueryStringHelper(
// filters,
// paging,
// search,
// sorting
// );
// paging.changePage(1);
// newQueryString.set(KEY_PAGE, 1);
// dispatch(setQueryString(convertQueryStringForBackend(newQueryString)));
// };

const clearFiltersAndApply = () => {
clear();
@@ -158,10 +145,20 @@ const useOffers = () => {
setFiltersCleared(true);
};

const applySorting = () => {
paging.changePage(1);
setFiltersCleared(true);
}

const applySearch = () => {
paging.changePage(1);
setFiltersCleared(true);
}

// Those hooks are below becouse function apply cannot be put on props before initialization
const sorting = useSorting(apply);
const sorting = useSorting(applySorting);
const paging = usePaging(apply);
const search = useSearch(applyFilters);
const search = useSearch(applySearch);

// On every change of search string, offers should be immediately searched
useEffect(() => {

+ 8
- 0
src/i18n/resources/rs.js Переглянути файл

@@ -299,6 +299,8 @@ export default {
backToHome: "Nazad na sve objave",
myOffers: "Moje objave",
profileOffers: "Objave kompanije",
blockedProfile: "Trenutno blokiran profil",
deletedProfile: "Obrisan profil"
},
about: {
header: {
@@ -535,6 +537,12 @@ export default {
cancel: "Otkaži",
delete: "Blokiraj",
},
unblockUser: {
reassuranceDelete:
"Da li ste sigurni da želite da odblokirate profil kompanje?",
cancel: "Otkaži",
delete: "Odblokiraj",
},
pin: {
reassurancePin:
"Da li ste sigurni da želite da zakačite proizvod na vrhu?",

+ 0
- 12
src/layouts/ItemDetailsLayout/ItemDetailsLayout.styled.js Переглянути файл

@@ -2,22 +2,10 @@ import { Container, Grid, Box } from "@mui/material";
import styled from "styled-components";

export const ItemDetailsLayoutContainer = styled(Container)`
/* padding-left: 36px; */
/* padding-right: ${(props) => (props.singleOffer ? "76px" : 0)}; */
margin: 0;
width: calc(100vw - 17px);
max-width: 100vw;
/* display: flex; */
position: relative;
/* flex: 1; */
height: 100%;
@media (max-width: 1200px) {
/* padding-right: ${(props) => (props.profile ? 0 : "36px")}; */
}
@media (max-width: 600px) {
/* padding-left: 18px; */
/* padding-right: 18px; */
}
`;

export const ContentRightCardContainer = styled(Box)`

+ 2
- 2
src/layouts/MainLayout/MainLayout.js Переглянути файл

@@ -8,10 +8,10 @@ const MainLayout = (props) => {
<MainLayoutContainer className={props.className}>
{props.children}
<Grid container maxHeight="xl">
<LeftCard item xs={0} sm={0} md={3} lg={3} xl={2.4}>
<LeftCard item xs={0} sm={0} md={3.5} lg={3.5} xl={3}>
{props.leftCard}
</LeftCard>
<Content item xs={12} sm={12} md={9} lg={9} xl={9.6}>
<Content item xs={12} sm={12} md={8.5} lg={8.5} xl={9}>
{props.content}
</Content>
</Grid>

+ 2
- 0
src/store/actions/admin/adminActionConstants.js Переглянути файл

@@ -1,6 +1,7 @@
import {
createErrorType,
createFetchType,
createSetType,
createSuccessType,
} from "../actionHelpers";

@@ -8,3 +9,4 @@ const ADMIN_SCOPE = "ADMIN";
export const ADMIN_FETCH = createFetchType(ADMIN_SCOPE);
export const ADMIN_FETCH_SUCCESS = createSuccessType(ADMIN_SCOPE);
export const ADMIN_FETCH_ERROR = createErrorType(ADMIN_SCOPE);
export const ADMIN_QUERY_STRING = createSetType("ADMIN_QUERY_STRING");

+ 4
- 0
src/store/actions/admin/adminActions.js Переглянути файл

@@ -2,6 +2,7 @@ import {
ADMIN_FETCH,
ADMIN_FETCH_ERROR,
ADMIN_FETCH_SUCCESS,
ADMIN_QUERY_STRING,
} from "./adminActionConstants";

export const fetchAdminMethod = (payload) => ({
@@ -14,3 +15,6 @@ export const fetchAdminMethodSuccess = () => ({
export const fetchAdminMethodError = () => ({
type: ADMIN_FETCH_ERROR,
});
export const setAdminQueryString = () => ({
type: ADMIN_QUERY_STRING
})

+ 13
- 4
src/store/saga/profileSaga.js Переглянути файл

@@ -39,7 +39,9 @@ import {
setMineProfile,
setProfile,
} from "../actions/profile/profileActions";
import { setQueryStringRedux } from "../actions/queryString/queryStringActions";
import { selectUserId } from "../selectors/loginSelectors";
import { selectQueryString } from "../selectors/queryStringSelectors";

function* fetchProfile(payload) {
try {
@@ -77,19 +79,26 @@ function* fetchAllProfiles() {
function* fetchAllProfilesAsAdmin({ payload }) {
try {
yield call(console.log, payload);
const queryObject = new URLSearchParams();
queryObject.set(KEY_SIZE, "10");
let queryString;
if (payload?.currentPage) {
const queryObject = new URLSearchParams();
queryObject.set(KEY_SIZE, "10");
if (payload?.searchValue && payload?.searchValue?.length !== 0)
queryObject.set(KEY_NAME, payload.searchValue);
if (payload?.sortOption?.value === sortUsersEnum.OLD.value)
queryObject.set(KEY_SORT_DATE, "false");
if (payload?.sortOption?.value === sortUsersEnum.NEW.value)
queryObject.set(KEY_SORT_DATE, "true");
queryObject.set(KEY_PAGE, payload.currentPage);
queryString = queryObject.toString();
yield put(setQueryStringRedux(queryString))
} else {
queryString = yield select(selectQueryString);
}

queryObject.set(KEY_PAGE, payload.currentPage);
const data = yield call(
attemptFetchAllProfilesAsAdmin,
queryObject.toString()
queryString
);
if (data) yield put(setAllProfiles(data.data));
yield put(fetchAllProfilesAsAdminSuccess());

+ 2
- 0
src/themes/primaryTheme/primaryThemeColors.js Переглянути файл

@@ -20,6 +20,7 @@ export const primaryThemeColors = {
primaryDarkTextThird: "#4D4D4D",
iconStrokeColor: "#8C8C8C",
iconStrokeDisabledColor: "#C4C4C4",
iconStrokePurpleDisabledColor: "#B4B4B4",
imagePickerBackground: "#E4E4E4",
iconYellowColor: "#FEB005",
iconMineProfileColor: "#9E9E9E",
@@ -36,4 +37,5 @@ export const primaryThemeColors = {
filterSkeletonItemsSecond: "#DDDDDD",
staticBackgroundColor: "#F3EFF8",
stepProgressAltColor: "#F4F4F4",
blockedColor: "#EE3A3A",
};

+ 9
- 0
src/util/helpers/hexToRgb.js Переглянути файл

@@ -0,0 +1,9 @@
export default function (hex) {
var hexToDo = hex[0] === "#" ? hex.slice(1) : hex;
var bigint = parseInt(hexToDo, 16);
var r = (bigint >> 16) & 255;
var g = (bigint >> 8) & 255;
var b = bigint & 255;
return r + "," + g + "," + b;
}

+ 2
- 2
src/util/helpers/queryHelpers.js Переглянути файл

@@ -51,9 +51,9 @@ export const convertQueryStringForFrontend = (queryURL) => {
queryObjectToReturn.delete(KEY_SIZE);
return queryObjectToReturn.toString();
} else {
queryObjectToReturn.delete(KEY_PAGE);
queryObjectToReturn.set(KEY_PAGE, queryObject.get(KEY_PAGE));
return (
queryObjectToReturn.toString() + "&page=" + queryObject.get(KEY_PAGE)
queryObjectToReturn.toString()
);
}
}

Завантаження…
Відмінити
Зберегти