Преглед на файлове

Finished feature 618

feature/618
jovan.cirkovic преди 3 години
родител
ревизия
7e2852aa9a
променени са 19 файла, в които са добавени 1054 реда и са изтрити 134 реда
  1. 18
    9
      src/components/DirectChat/DirectChat.js
  2. 4
    1
      src/components/DirectChat/DirectChatContent/DirectChatContent.js
  3. 53
    1
      src/components/DirectChat/DirectChatContent/SkeletonDirectChatContent/SkeletonDirectChatContent.styled.js
  4. 36
    2
      src/components/DirectChat/MiniChatColumn/SkeletonMiniChatColumn/SkeletonMiniChatColumn.styled.js
  5. 41
    1
      src/components/DirectChat/SkeletonDirectChat/SkeletonDirectChat.styled.js
  6. 21
    9
      src/components/ItemDetails/ItemDetails.js
  7. 88
    0
      src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.js
  8. 252
    0
      src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.styled.js
  9. 23
    11
      src/components/ProfileMini/ProfileMini.js
  10. 39
    0
      src/components/ProfileMini/SkeletonProfileMini/SkeletonProfileMini.js
  11. 107
    0
      src/components/ProfileMini/SkeletonProfileMini/SkeletonProfileMini.styled.js
  12. 40
    19
      src/components/UserReviews/NoReviews/UserReviewsSkeleton/UserReviewsSkeleton.js
  13. 175
    44
      src/components/UserReviews/NoReviews/UserReviewsSkeleton/UserReviewsSkeleton.styled.js
  14. 30
    0
      src/components/UserReviews/SkeletonUserReviews/SkeletonUserReviews.js
  15. 69
    0
      src/components/UserReviews/SkeletonUserReviews/SkeletonUserReviews.styled.js
  16. 42
    29
      src/components/UserReviews/UserReviews.js
  17. 4
    1
      src/pages/ItemDetailsPage/ItemDetailsPageMUI.js
  18. 3
    3
      src/store/actions/profile/profileActionConstants.js
  19. 9
    4
      src/store/actions/review/reviewActionConstants.js

+ 18
- 9
src/components/DirectChat/DirectChat.js Целия файл

@@ -5,7 +5,11 @@ import DirectChatHeaderTitle from "./DirectChatHeaderTitle/DirectChatHeaderTitle
import DirectChatHeader from "./DirectChatHeader/DirectChatHeader";
import { useDispatch, useSelector } from "react-redux";
import { useLocation, useRouteMatch } from "react-router-dom";
import { addNewMessage, fetchOneChat, setOneChat } from "../../store/actions/chat/chatActions";
import {
addNewMessage,
fetchOneChat,
setOneChat,
} from "../../store/actions/chat/chatActions";
import { selectSelectedChat } from "../../store/selectors/chatSelectors";
import DirectChatContent from "./DirectChatContent/DirectChatContent";
import { selectOffer } from "../../store/selectors/offersSelectors";
@@ -22,7 +26,7 @@ const DirectChat = () => {
const routeMatch = useRouteMatch();
const location = useLocation();
const dispatch = useDispatch();
const userId = useSelector(selectUserId);
const isLoadingDirectChat = useSelector(
selectIsLoadingByActionType(CHAT_SCOPE)
@@ -48,12 +52,15 @@ const DirectChat = () => {
image: offer?.companyData?.image,
name: offer?.companyData?.company?.name,
location: offer?.companyData?.company?.contacts?.location,
userId: offer?.offer?.userId
userId: offer?.offer?.userId,
};
}
return {
...chat?.interlocutor,
userId: chat?.chat?.participants[0] === userId ? chat?.chat?.participants[1] : chat?.chat?.participants[0]
userId:
chat?.chat?.participants[0] === userId
? chat?.chat?.participants[1]
: chat?.chat?.participants[0],
};
}, [chat, location.state, offer]);

@@ -65,13 +72,15 @@ const DirectChat = () => {

useEffect(() => {
addMesageListener((data) => {
dispatch(addNewMessage({
_id: data.chatId,
message: data.message
}))
dispatch(
addNewMessage({
_id: data.chatId,
message: data.message,
})
);
});
return () => removeMessageListener();
}, [])
}, []);

const refreshChat = () => {
if (routeMatch.params.idChat === "newMessage") {

+ 4
- 1
src/components/DirectChat/DirectChatContent/DirectChatContent.js Целия файл

@@ -30,7 +30,10 @@ const DirectChatContent = (props) => {
useEffect(() => {
// const offsetBottom =
// messagesRef.current?.offsetTop + messagesRef.current?.offsetHeight;
messagesRef.current?.scrollTo({ top: messagesRef.current.scrollHeight, behaviour: "smooth" });
messagesRef.current?.scrollTo({
top: messagesRef.current.scrollHeight,
behaviour: "smooth",
});
}, [messages]);
return (
<>

+ 53
- 1
src/components/DirectChat/DirectChatContent/SkeletonDirectChatContent/SkeletonDirectChatContent.styled.js Целия файл

@@ -1,7 +1,35 @@
import styled from "styled-components";
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonChatContentContainer = styled(Box)`
display: flex;
flex-direction: column;
@@ -14,6 +42,7 @@ export const SkeletonChatContentHeader = styled(Box)`
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
justify-content: space-between;
align-items: center;
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonChatContentHeaderFirstColumn = styled(Box)`
@@ -25,6 +54,7 @@ export const SkeletonChatContentHeaderFirstColumnImage = styled(Box)`
height: 54px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentHeaderFirstColumnInfo = styled(Box)`
@@ -38,12 +68,14 @@ export const SkeletonChatContentHeaderFirstColumnFirstLine = styled(Box)`
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
margin-bottom: 15px;
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentHeaderFirstColumnSecondLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentHeaderSecondColumnImageSmall = styled(Box)`
@@ -51,11 +83,13 @@ export const SkeletonChatContentHeaderSecondColumnImageSmall = styled(Box)`
height: 40px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentMain = styled(Box)`
padding: 27px 36px 18px 36px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentMainRow = styled(Box)`
@@ -72,6 +106,7 @@ export const SkeletonChatContentMainImage = styled(Box)`
height: 54px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonChatContentMainLeftRowInfo = styled(Box)`
@@ -83,6 +118,7 @@ export const SkeletonChatContentMainLeftRowInfo = styled(Box)`
margin-left: 18px;
margin-bottom: 18px;
border-radius: 0px 9px 9px 9px;
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonChatContentMainFirstRowInfoFirstLine = styled(Box)`
@@ -90,6 +126,7 @@ export const SkeletonChatContentMainFirstRowInfoFirstLine = styled(Box)`
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
margin-bottom: 15px;
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 480px;
@@ -104,12 +141,14 @@ export const SkeletonChatContentMainFirstRowInfoSecondLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentMainRightRowInfo = styled(Box)`
display: flex;
flex-direction: column;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
padding: 9px;
align-items: flex-start;
margin-right: 18px;
@@ -122,6 +161,7 @@ export const SkeletonChatContentSecondRowFirstLine = styled(Box)`
height: 18px;
margin-bottom: 15px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 600px) {
width: 180px;
@@ -132,12 +172,14 @@ export const SkeletonChatContentSecondRowSecondLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentThirdRowFirstLine = styled(Box)`
width: 394px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
margin-bottom: 15px;

@media (max-width: 600px) {
@@ -149,12 +191,14 @@ export const SkeletonChatContentThirdRowSecondLine = styled(Box)`
width: 93px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentFourthRowFirstLine = styled(Box)`
width: 101px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
margin-bottom: 15px;
`;

@@ -162,12 +206,14 @@ export const SkeletonChatContentFourthRowSecondLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentFifthRowFirstLine = styled(Box)`
width: 131px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
margin-bottom: 15px;
`;

@@ -175,12 +221,14 @@ export const SkeletonChatContentFifthRowSecondLine = styled(Box)`
width: 87px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonChatContentHorizontalLine = styled(Box)`
width: 100%;
height: 1px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin: 9px 0 18px 0;
`;

@@ -188,6 +236,7 @@ export const SkeletonChatContentVerticalLine = styled(Box)`
width: 5px;
height: 180px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
position: absolute;
top: 490px;
right: 35px;
@@ -201,6 +250,7 @@ export const SkeletonChatContentFooterFirstColumn = styled(Box)`
flex: 1;
padding: 17px 16px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-right: 36px;
`;

@@ -208,6 +258,7 @@ export const SkeletonChatContentFooterColumnInside = styled(Box)`
width: 108px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 600px) {
width: 80px;
@@ -217,4 +268,5 @@ export const SkeletonChatContentFooterColumnInside = styled(Box)`
export const SkeletonChatContentFooterSecondColumn = styled(Box)`
padding: 17px 36px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

+ 36
- 2
src/components/DirectChat/MiniChatColumn/SkeletonMiniChatColumn/SkeletonMiniChatColumn.styled.js Целия файл

@@ -1,7 +1,35 @@
import styled from "styled-components";
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonMiniChatColumnContainer = styled(Box)`
display: flex;
flex-direction: column;
@@ -14,8 +42,9 @@ export const SkeletonMiniChatColumnContainer = styled(Box)`
export const SkeletonMiniChatColumnHeading = styled(Box)`
width: 90px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
margin-bottom: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonMiniChatColumnItem = styled(Box)`
@@ -23,6 +52,7 @@ export const SkeletonMiniChatColumnItem = styled(Box)`
background-color: ${selectedTheme.filterSkeletonBackground};
padding: 18px;
margin-bottom: 18px;
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonMiniChatItemImage = styled(Box)`
@@ -30,6 +60,7 @@ export const SkeletonMiniChatItemImage = styled(Box)`
height: 72px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonMiniChatItemInfo = styled(Box)`
@@ -43,6 +74,7 @@ export const SkeletonMiniChatItemInfoFirstLine = styled(Box)`
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
margin-bottom: 9px;
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonMiniChatItemInfoSecondLine = styled(Box)`
@@ -50,10 +82,12 @@ export const SkeletonMiniChatItemInfoSecondLine = styled(Box)`
height: 9px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
margin-bottom: 4px;
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonMiniChatItemInfoThirdLine = styled(Box)`
width: 90px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

+ 41
- 1
src/components/DirectChat/SkeletonDirectChat/SkeletonDirectChat.styled.js Целия файл

@@ -1,11 +1,40 @@
import styled from "styled-components";
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonDirectChatHeading = styled(Box)`
width: 90px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
margin-bottom: 18px;
`;

@@ -15,12 +44,14 @@ export const SkeletonDirectChatContainer = styled(Box)`
border: 1px solid ${selectedTheme.filterSkeletonBackgroundSecond};
padding: 18px;
justify-content: space-between;
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonDirectChatImage = styled(Box)`
width: 144px;
height: 144px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;

@media (max-width: 600px) {
width: 108px;
@@ -44,6 +75,7 @@ export const SkeletonDirectChatFirstLine = styled(Box)`
width: 90px;
height: 27px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-bottom: 28px;
`;

@@ -51,6 +83,7 @@ export const SkeletonDirectChatSecondLine = styled(Box)`
width: 117px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-bottom: 4px;
`;

@@ -58,6 +91,7 @@ export const SkeletonDirectChatThirdLine = styled(Box)`
width: 90px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-bottom: 35px;
`;

@@ -69,6 +103,7 @@ export const SkeletonDirectChatFourthLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-right: 27px;

@media (max-width: 600px) {
@@ -103,6 +138,7 @@ export const SkeletonDirectChatSecondColumnFirstLine = styled(Box)`
width: 72px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-top: 18px;
margin-bottom: 4px;
`;
@@ -111,6 +147,7 @@ export const SkeletonDirectChatSecondColumnSecondLine = styled(Box)`
width: 221px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
margin-bottom: 4px;
`;

@@ -127,12 +164,14 @@ export const SkeletonDirectChatRoundImage = styled(Box)`
height: 40px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonDirectChatThirdColumnSecondLine = styled(Box)`
width: 180px;
height: 48px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonBackgroundAnimation} 2s infinite;
padding: 17px 36px;
`;

@@ -140,4 +179,5 @@ export const SkeletonDirectChatThirdColumnSecondLineInside = styled(Box)`
width: 108px;
height: 14px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

+ 21
- 9
src/components/ItemDetails/ItemDetails.js Целия файл

@@ -13,11 +13,17 @@ import { selectOffer } from "../../store/selectors/offersSelectors";
import { selectUserId } from "../../store/selectors/loginSelectors";
import { ReactComponent as OfferIcon } from "../../assets/images/svg/package-gray.svg";
import { useTranslation } from "react-i18next";
import { ONE_OFFER_SCOPE } from "../../store/actions/offers/offersActionConstants";
import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
import SkeletonItemDetails from "./SkeletonItemDetails/SkeletonItemDetails";

const ItemDetails = (props) => {
const offer = useSelector(selectOffer);
const userId = useSelector(selectUserId);
const { t } = useTranslation();
const isLoadingOffer = useSelector(
selectIsLoadingByActionType(ONE_OFFER_SCOPE)
);
let isMyProfile = useMemo(() => {
if (offer?.offer?.userId?.toString() === userId?.toString()) {
return true;
@@ -27,16 +33,22 @@ const ItemDetails = (props) => {
return (
<ItemDetailsContainer>
<Header />
{!props.singleOffer && (
<ItemDetailsHeaderCard offer={offer} isMyProfile={isMyProfile} />
)}
{props.singleOffer && (
<OfferIconContainer>
<OfferIcon />
<OfferIconText>{t("offer.product")}</OfferIconText>
</OfferIconContainer>
{isLoadingOffer || isLoadingOffer === undefined ? (
<SkeletonItemDetails />
) : (
<>
{!props.singleOffer && (
<ItemDetailsHeaderCard offer={offer} isMyProfile={isMyProfile} />
)}
{props.singleOffer && (
<OfferIconContainer>
<OfferIcon />
<OfferIconText>{t("offer.product")}</OfferIconText>
</OfferIconContainer>
)}
<ItemDetailsCard offer={offer} isMyOffer={isMyProfile} singleOffer />
</>
)}
<ItemDetailsCard offer={offer} isMyOffer={isMyProfile} singleOffer />
</ItemDetailsContainer>
);
};

+ 88
- 0
src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.js Целия файл

@@ -0,0 +1,88 @@
import React from "react";
import {
SkeletonItemDetailsContainer,
SkeletonItemDetailsHeader,
SkeletonItemDetailsContent,
SkeletonItemDetailsLineContainer,
SkeletonItemDetailsLineSmallContainer,
SkeletonItemDetailsLineSmall,
SkeletonItemDetailsLineBig,
SkeletonItemDetailsGalleryMainContainer,
SkeletonItemDetailsGallery,
SkeletonItemDetailsImagesContainer,
SkeletonItemDetailsArrow,
SkeletonItemDetailsImage,
SkeletonItemDetailsImageHalf,
SkeletonItemDetailsMainContainer,
SkeletonItemDetailsMainFirstLine,
SkeletonItemDetailsMainMarginS,
SkeletonItemDetailsMainMarginL,
SkeletonItemDetailsMainSecondLine,
SkeletonItemDetailsMainThirdLine,
SkeletonItemDetailsMainFourthLine,
SkeletonItemDetailsMainFifthLine,
SkeletonItemDetailsMainSixthLine,
SkeletonItemDetailsMainButtons,
SkeletonItemDetailsMainButtonRound,
SkeletonItemDetailsMainButtonContainer,
SkeletonItemDetailsMainButton,
} from "./SkeletonItemDetails.styled";

const SkeletonItemDetails = () => {
return (
<SkeletonItemDetailsContainer>
<SkeletonItemDetailsHeader />
<SkeletonItemDetailsContent>
<SkeletonItemDetailsLineContainer>
<SkeletonItemDetailsLineSmallContainer>
<SkeletonItemDetailsLineSmall />
<SkeletonItemDetailsLineSmall />
<SkeletonItemDetailsLineSmall />
<SkeletonItemDetailsLineSmall />
</SkeletonItemDetailsLineSmallContainer>
<SkeletonItemDetailsLineBig />
</SkeletonItemDetailsLineContainer>
<SkeletonItemDetailsGalleryMainContainer>
<SkeletonItemDetailsGallery>
<SkeletonItemDetailsArrow />
<SkeletonItemDetailsImagesContainer>
<SkeletonItemDetailsImage />
<SkeletonItemDetailsImage />
<SkeletonItemDetailsImage />
<SkeletonItemDetailsImageHalf />
</SkeletonItemDetailsImagesContainer>
<SkeletonItemDetailsArrow />
</SkeletonItemDetailsGallery>
<SkeletonItemDetailsMainContainer>
<SkeletonItemDetailsMainFirstLine />
<SkeletonItemDetailsLineSmall />
<SkeletonItemDetailsMainMarginS />
<SkeletonItemDetailsMainSecondLine />
<SkeletonItemDetailsMainThirdLine />
<SkeletonItemDetailsMainFourthLine />
<SkeletonItemDetailsMainMarginL />
<SkeletonItemDetailsMainSecondLine />
<SkeletonItemDetailsMainFourthLine />
<SkeletonItemDetailsMainThirdLine />
<SkeletonItemDetailsMainFourthLine />
<SkeletonItemDetailsMainFifthLine />
<SkeletonItemDetailsMainSecondLine />
<SkeletonItemDetailsMainThirdLine />
<SkeletonItemDetailsMainFifthLine />
<SkeletonItemDetailsMainFourthLine />
<SkeletonItemDetailsMainSixthLine />
<SkeletonItemDetailsMainButtons>
<SkeletonItemDetailsMainButtonRound />
<SkeletonItemDetailsMainButtonRound />
<SkeletonItemDetailsMainButtonContainer>
<SkeletonItemDetailsMainButton />
</SkeletonItemDetailsMainButtonContainer>
</SkeletonItemDetailsMainButtons>
</SkeletonItemDetailsMainContainer>
</SkeletonItemDetailsGalleryMainContainer>
</SkeletonItemDetailsContent>
</SkeletonItemDetailsContainer>
);
};

export default SkeletonItemDetails;

+ 252
- 0
src/components/ItemDetails/SkeletonItemDetails/SkeletonItemDetails.styled.js Целия файл

@@ -0,0 +1,252 @@
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonItemDetailsContainer = styled(Box)`
display: flex;
flex-direction: column;
margin-left: 36px;
margin-right: -36px;

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

@media (max-width: 600px) {
display: none;
}
`;

export const SkeletonItemDetailsHeader = styled(Box)`
width: 145px;
height: 18px;
margin-top: 34px;
margin-bottom: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonItemDetailsContent = styled(Box)`
padding: 18px;
display: flex;
flex-direction: column;
border: 1px solid ${selectedTheme.filterSkeletonBackgroundSecond};
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonItemDetailsLineContainer = styled(Box)`
display: flex;
justify-content: space-between;
margin-bottom: 20px;
`;

export const SkeletonItemDetailsLineSmallContainer = styled(Box)`
display: flex;
gap: 27px;
`;

export const SkeletonItemDetailsLineSmall = styled(Box)`
width: 72px;
height: 14px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsLineBig = styled(Box)`
width: 108px;
height: 14px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsGalleryMainContainer = styled(Box)`
display: flex;
`;

export const SkeletonItemDetailsGallery = styled(Box)`
display: flex;
flex-direction: column;
align-items: center;
gap: 18px;
`;

export const SkeletonItemDetailsArrow = styled(Box)`
width: 36px;
height: 36px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsImagesContainer = styled(Box)`
display: flex;
flex-direction: column;
`;

export const SkeletonItemDetailsImage = styled(Box)`
width: 144px;
min-height: 144px;
border-radius: 4px;
margin-bottom: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsImageHalf = styled(Box)`
width: 144px;
height: 83px;
border-radius: 4px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsMainContainer = styled(Box)`
display: flex;
flex-direction: column;
margin-left: 20px;
width: 100%;
`;

export const SkeletonItemDetailsMainMarginS = styled(Box)`
margin-bottom: 4px;
`;

export const SkeletonItemDetailsMainMarginL = styled(Box)`
margin-bottom: 30px;
`;

export const SkeletonItemDetailsMainFirstLine = styled(Box)`
width: 90px;
height: 27px;
border-radius: 2px;
margin-bottom: 15px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsMainSecondLine = styled(Box)`
width: 449px;
height: 18px;
border-radius: 2px;
margin-bottom: 4px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 370px;
}
`;

export const SkeletonItemDetailsMainThirdLine = styled(Box)`
width: 427px;
height: 18px;
border-radius: 2px;
margin-bottom: 4px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 350px;
}
`;

export const SkeletonItemDetailsMainFourthLine = styled(Box)`
width: 445px;
height: 18px;
border-radius: 2px;
margin-bottom: 4px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 365px;
}
`;

export const SkeletonItemDetailsMainFifthLine = styled(Box)`
width: 441px;
height: 18px;
border-radius: 2px;
margin-bottom: 4px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 361px;
}
`;

export const SkeletonItemDetailsMainSixthLine = styled(Box)`
width: 307px;
height: 18px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;

@media (max-width: 1200px) {
width: 227px;
}
`;

export const SkeletonItemDetailsMainButtons = styled(Box)`
display: flex;
align-items: center;
margin-top: 268px;
margin-left: auto;
`;

export const SkeletonItemDetailsMainButtonRound = styled(Box)`
width: 40px;
height: 40px;
border-radius: 100%;
margin-right: 18px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsMainButton = styled(Box)`
width: 108px;
height: 14px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonItemDetailsMainButtonContainer = styled(Box)`
border-radius: 4px;
padding: 17px 36px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

+ 23
- 11
src/components/ProfileMini/ProfileMini.js Целия файл

@@ -10,11 +10,17 @@ import { selectUserId } from "../../store/selectors/loginSelectors";
import { ReactComponent as ProfileIcon } from "../../assets/images/svg/user-gray.svg";
import ItemDetailsHeaderCard from "../ItemDetails/ItemDetailsHeaderCard/ItemDetailsHeaderCard";
import { useTranslation } from "react-i18next";
import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
import SkeletonProfileMini from "./SkeletonProfileMini/SkeletonProfileMini";
import { ONE_OFFER_SCOPE } from "../../store/actions/offers/offersActionConstants";

const ProfileMini = () => {
const offer = useSelector(selectOffer);
const userId = useSelector(selectUserId);
const { t } = useTranslation();
const isLoadingOfferContent = useSelector(
selectIsLoadingByActionType(ONE_OFFER_SCOPE)
);
let isMyProfile = useMemo(() => {
if (offer?.offer?.userId?.toString() === userId?.toString()) {
return true;
@@ -22,17 +28,23 @@ const ProfileMini = () => {
return false;
}, [offer, userId]);
return (
<ProfileHeader>
<ProfileHeaderIconContainer>
<ProfileIcon />
<ProfileHeaderText>{t("profile.companyProfile")}</ProfileHeaderText>
</ProfileHeaderIconContainer>
<ItemDetailsHeaderCard
offer={offer}
isMyProfile={isMyProfile}
singleOffer
/>
</ProfileHeader>
<>
{isLoadingOfferContent || isLoadingOfferContent === undefined ? (
<SkeletonProfileMini />
) : (
<ProfileHeader>
<ProfileHeaderIconContainer>
<ProfileIcon />
<ProfileHeaderText>{t("profile.companyProfile")}</ProfileHeaderText>
</ProfileHeaderIconContainer>
<ItemDetailsHeaderCard
offer={offer}
isMyProfile={isMyProfile}
singleOffer
/>
</ProfileHeader>
)}
</>
);
};


+ 39
- 0
src/components/ProfileMini/SkeletonProfileMini/SkeletonProfileMini.js Целия файл

@@ -0,0 +1,39 @@
import React from "react";
import PropTypes from "prop-types";
import {
SkeletonProfileMiniContainer,
SkeletonProfileMiniContent,
SkeletonProfileMiniHeader,
SkeletonProfileMiniImageColumn,
SkeletonProfileMiniImage,
SkeletonProfileMiniColumn,
SkeletonProfileMiniFirstRow,
SkeletonProfileMiniSecondRow,
SkeletonProfileMiniThirdRow,
SkeletonProfileMiniImageSmall,
} from "./SkeletonProfileMini.styled";

const SkeletonProfileMini = () => {
return (
<SkeletonProfileMiniContainer>
<SkeletonProfileMiniHeader />
<SkeletonProfileMiniContent>
<SkeletonProfileMiniImageColumn>
<SkeletonProfileMiniImage />
<SkeletonProfileMiniColumn>
<SkeletonProfileMiniFirstRow />
<SkeletonProfileMiniSecondRow />
<SkeletonProfileMiniThirdRow />
</SkeletonProfileMiniColumn>
</SkeletonProfileMiniImageColumn>
<SkeletonProfileMiniImageSmall />
</SkeletonProfileMiniContent>
</SkeletonProfileMiniContainer>
);
};

SkeletonProfileMini.propTypes = {
animationStage: PropTypes.number,
};

export default SkeletonProfileMini;

+ 107
- 0
src/components/ProfileMini/SkeletonProfileMini/SkeletonProfileMini.styled.js Целия файл

@@ -0,0 +1,107 @@
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonProfileMiniContainer = styled(Box)`
display: flex;
flex-direction: column;
margin: 60px 0 40px 0;
`;

export const SkeletonProfileMiniHeader = styled(Box)`
width: 145px;
height: 18px;
margin-bottom: 18px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonProfileMiniContent = styled(Box)`
display: flex;
justify-content: space-between;
padding: 18px;
border-radius: 4px;
border: 1px solid ${selectedTheme.filterSkeletonBackgroundSecond};
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

export const SkeletonProfileMiniImageColumn = styled(Box)`
display: flex;
`;

export const SkeletonProfileMiniImage = styled(Box)`
width: 108px;
height: 108px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonProfileMiniColumn = styled(Box)`
display: flex;
flex-direction: column;
margin-left: 18px;
`;

export const SkeletonProfileMiniFirstRow = styled(Box)`
width: 90px;
height: 27px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonProfileMiniSecondRow = styled(Box)`
width: 163px;
height: 18px;
margin: 27px 0 9px 0;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonProfileMiniThirdRow = styled(Box)`
width: 117px;
height: 18px;
border-radius: 2px;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonProfileMiniImageSmall = styled(Box)`
width: 40px;
height: 40px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
animation: ${skeletonAnimation} 2s infinite;
`;

+ 40
- 19
src/components/UserReviews/NoReviews/UserReviewsSkeleton/UserReviewsSkeleton.js Целия файл

@@ -3,6 +3,7 @@ import PropTypes from "prop-types";
import {
UserReviewsSkeletonCircle,
UserReviewsSkeletonContainer,
UserReviewsSkeletonHrLine,
UserReviewsSkeletonItemsContainer,
UserReviewsSkeletonLine,
UserReviewsSkeletonLineFifth,
@@ -11,6 +12,11 @@ import {
UserReviewsSkeletonLineSecond,
UserReviewsSkeletonLineThird,
UserReviewsSkeletonSquare,
UserReviewsSkeletonSquareImage,
UserReviewsSkeletonSquareImageContainer,
UserReviewsSkeletonSquareInfo,
UserReviewsSkeletonSquareInfoFirstLine,
UserReviewsSkeletonSquareInfoSecondLine,
} from "./UserReviewsSkeleton.styled";

const UserReviewsSkeleton = (props) => {
@@ -18,25 +24,39 @@ const UserReviewsSkeleton = (props) => {
return (
<UserReviewsSkeletonContainer>
{array.map((item, index) => (
<UserReviewsSkeletonItemsContainer key={index}>
<UserReviewsSkeletonLine>
<UserReviewsSkeletonCircle />
<UserReviewsSkeletonLineOne />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine>
<UserReviewsSkeletonSquare />
<UserReviewsSkeletonLineSecond />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine>
<UserReviewsSkeletonLineThird />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine>
<UserReviewsSkeletonLineForth />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine>
<UserReviewsSkeletonLineFifth />
</UserReviewsSkeletonLine>
</UserReviewsSkeletonItemsContainer>
<>
<UserReviewsSkeletonItemsContainer key={index}>
<UserReviewsSkeletonLine skeleton={props.skeleton}>
<UserReviewsSkeletonCircle skeleton={props.skeleton} />
<UserReviewsSkeletonLineOne skeleton={props.skeleton} />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine skeleton={props.skeleton}>
<UserReviewsSkeletonSquare />
<UserReviewsSkeletonLineSecond />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine skeleton={props.skeleton}>
<UserReviewsSkeletonLineThird />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine skeleton={props.skeleton}>
<UserReviewsSkeletonLineForth />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonLine skeleton={props.skeleton}>
<UserReviewsSkeletonLineFifth />
</UserReviewsSkeletonLine>
<UserReviewsSkeletonSquareImageContainer>
<UserReviewsSkeletonSquareImage skeleton={props.skeleton} />
<UserReviewsSkeletonSquareInfo>
<UserReviewsSkeletonSquareInfoFirstLine
skeleton={props.skeleton}
/>
<UserReviewsSkeletonSquareInfoSecondLine
skeleton={props.skeleton}
/>
</UserReviewsSkeletonSquareInfo>
</UserReviewsSkeletonSquareImageContainer>
</UserReviewsSkeletonItemsContainer>
<UserReviewsSkeletonHrLine skeleton={props.skeleton} />
</>
))}
</UserReviewsSkeletonContainer>
);
@@ -45,6 +65,7 @@ const UserReviewsSkeleton = (props) => {
UserReviewsSkeleton.propTypes = {
children: PropTypes.node,
numOfElements: PropTypes.number,
skeleton: PropTypes.bool,
};

export default UserReviewsSkeleton;

+ 175
- 44
src/components/UserReviews/NoReviews/UserReviewsSkeleton/UserReviewsSkeleton.styled.js Целия файл

@@ -1,57 +1,188 @@
import styled, { css, keyframes } from "styled-components";
import { Box } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

// const skeletonBackgroundAnimation = keyframes`
// 0% {
// background-color: ${selectedTheme.filterSkeletonBackground};
// }

// 50% {
// background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
// }

// 100% {
// background-color: ${selectedTheme.filterSkeletonBackground}
// }
// `;

export const UserReviewsSkeletonContainer = styled(Box)`
width: 100%;
`
width: 100%;
`;
export const UserReviewsSkeletonItemsContainer = styled(Box)`
width: 100%;
padding: 36px;
`
width: 100%;
padding: 36px;
`;
export const UserReviewsSkeletonLine = styled(Box)`
display: flex;
flex-direction: row;
& * {
background-color: ${selectedTheme.skeletonItemColor};
}
`
display: flex;
flex-direction: row;
& * {
background-color: ${(props) =>
props.skeleton
? `${selectedTheme.skeletonItemColor}`
: `${selectedTheme.filterSkeletonBackgroundSecond}`};
}
& * {
${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
}
`;

export const UserReviewsSkeletonCircle = styled(Box)`
width: 54px;
height: 54px;
border-radius: 100%;
`
width: 54px;
height: 54px;
border-radius: 100%;
${(props) =>
props.skeleton &&
css`
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
`}
${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;
export const UserReviewsSkeletonLineOne = styled(Box)`
width: 78px;
height: 18px;
margin-top: 18px;
margin-left: 18px;
`
width: 78px;
height: 18px;
margin-top: 18px;
margin-left: 18px;
${(props) =>
props.skeleton &&
css`
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
`}
${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;
export const UserReviewsSkeletonLineSecond = styled(Box)`
width: 200px;
height: 14px;
margin-top: 18px;
margin-left: 9px;
margin-bottom: 4px;
flex: 1;
`
width: 200px;
height: 14px;
margin-top: 18px;
margin-left: 9px;
margin-bottom: 4px;
flex: 1;
`;
export const UserReviewsSkeletonSquare = styled(Box)`
width: 14px;
height: 14px;
margin-top: 18px;
`
width: 14px;
height: 14px;
margin-top: 18px;
`;
export const UserReviewsSkeletonLineThird = styled(Box)`
width: 91px;
height: 14px;
margin-left: 23px;
`
width: 91px;
height: 14px;
margin-left: 23px;
`;
export const UserReviewsSkeletonLineForth = styled(Box)`
width: 154px;
height: 14px;
margin-top: 20px;
margin-bottom: 4px;
`
width: 154px;
height: 14px;
margin-top: 20px;
margin-bottom: 4px;
`;
export const UserReviewsSkeletonLineFifth = styled(Box)`
width: 121px;
height: 14px;
`
width: 121px;
height: 14px;
`;

export const UserReviewsSkeletonSquareImageContainer = styled(Box)`
display: flex;
margin-top: 18px;
`;

export const UserReviewsSkeletonSquareImage = styled(Box)`
width: 54px;
height: 54px;
background-color: ${(props) =>
props.skeleton
? `${selectedTheme.filterSkeletonBackgroundSecond}`
: `${selectedTheme.skeletonItemColor}`};

${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;

export const UserReviewsSkeletonSquareInfo = styled(Box)`
display: flex;
flex-direction: column;
margin-left: 18px;
justify-content: center;
`;

export const UserReviewsSkeletonSquareInfoFirstLine = styled(Box)`
width: 121px;
height: 14px;
background-color: ${(props) =>
props.skeleton
? `${selectedTheme.filterSkeletonBackgroundSecond}`
: `${selectedTheme.skeletonItemColor}`};

${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;

export const UserReviewsSkeletonSquareInfoSecondLine = styled(Box)`
width: 78px;
height: 18px;
margin-top: 6px;
background-color: ${(props) =>
props.skeleton
? `${selectedTheme.filterSkeletonBackgroundSecond}`
: `${selectedTheme.skeletonItemColor}`};
${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;

export const UserReviewsSkeletonHrLine = styled(Box)`
width: 100%;
height: 1px;
background-color: ${(props) =>
props.skeleton
? `${selectedTheme.filterSkeletonBackgroundSecond}`
: `${selectedTheme.skeletonItemColor}`};

${(props) =>
props.skeleton &&
css`
animation: ${skeletonAnimation} 2s infinite;
`}
`;

+ 30
- 0
src/components/UserReviews/SkeletonUserReviews/SkeletonUserReviews.js Целия файл

@@ -0,0 +1,30 @@
import React from "react";
import UserReviewsSkeleton from "../NoReviews/UserReviewsSkeleton/UserReviewsSkeleton";
import {
SkeletonUserReviewsHeader,
SkeletonUserReviewsHeaderFirstline,
SkeletonUserReviewsHeaderFilter,
SkeletonUserReviewsHeaderSecondline,
SkeletonUserReviewsHeaderFilterRound,
SkeletonUserReviewsMainContainer,
} from "./SkeletonUserReviews.styled";

const SkeletonUserReviews = () => {
return (
<>
<SkeletonUserReviewsHeader>
<SkeletonUserReviewsHeaderFirstline />
<SkeletonUserReviewsHeaderFilter>
<SkeletonUserReviewsHeaderSecondline />
<SkeletonUserReviewsHeaderFilterRound />
</SkeletonUserReviewsHeaderFilter>
</SkeletonUserReviewsHeader>
<SkeletonUserReviewsMainContainer>
<UserReviewsSkeleton skeleton />
<UserReviewsSkeleton skeleton />
</SkeletonUserReviewsMainContainer>
</>
);
};

export default SkeletonUserReviews;

+ 69
- 0
src/components/UserReviews/SkeletonUserReviews/SkeletonUserReviews.styled.js Целия файл

@@ -0,0 +1,69 @@
import styled, { keyframes } from "styled-components";
import { Box } from "@mui/system";
import selectedTheme from "../../../themes";

const skeletonAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonItems};
}

50% {
background-color: ${selectedTheme.filterSkeletonItemsSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonItems}
}
`;

const skeletonBackgroundAnimation = keyframes`
0% {
background-color: ${selectedTheme.filterSkeletonBackground};
}

50% {
background-color: ${selectedTheme.filterSkeletonBackgroundSecond};
}

100% {
background-color: ${selectedTheme.filterSkeletonBackground}
}
`;

export const SkeletonUserReviewsHeader = styled(Box)`
display: flex;
justify-content: space-between;
margin-bottom: 18px;
`;

export const SkeletonUserReviewsHeaderFirstline = styled(Box)`
width: 145px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonUserReviewsHeaderFilter = styled(Box)`
display: flex;
`;

export const SkeletonUserReviewsHeaderSecondline = styled(Box)`
width: 118px;
height: 18px;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonUserReviewsHeaderFilterRound = styled(Box)`
width: 18px;
height: 18px;
margin-left: 9px;
border-radius: 100%;
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonAnimation} 2s infinite;
`;

export const SkeletonUserReviewsMainContainer = styled(Box)`
background-color: ${selectedTheme.filterSkeletonBackground};
animation: ${skeletonBackgroundAnimation} 2s infinite;
`;

+ 42
- 29
src/components/UserReviews/UserReviews.js Целия файл

@@ -16,6 +16,9 @@ import { selectOffer } from "../../store/selectors/offersSelectors";
import { selectSelectedReviews } from "../../store/selectors/reviewSelector";
import { useRouteMatch } from "react-router-dom";
import { fetchReviews } from "../../store/actions/review/reviewActions";
import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
import SkeletonUserReviews from "./SkeletonUserReviews/SkeletonUserReviews";
import { ONE_OFFER_SCOPE } from "../../store/actions/offers/offersActionConstants";

const UserReviews = (props) => {
const { t } = useTranslation();
@@ -24,6 +27,10 @@ const UserReviews = (props) => {
const routeMatch = useRouteMatch();
const dispatch = useDispatch();

const isLoadingReview = useSelector(
selectIsLoadingByActionType(ONE_OFFER_SCOPE)
);

useEffect(() => {
if (props.profileReviews && routeMatch.params?.idProfile) {
let idProfile = routeMatch.params.idProfile;
@@ -44,37 +51,43 @@ const UserReviews = (props) => {
}, [props.profileReviews, offer, props.isProfileReviews, reviews]);

return (
<ReviewsBox
profile={props.isProfileReviews}
className={props.className}
numOfReviews={lastThreeReviews?.length}
>
{!props.givingReview && (
<ReviewsHeader
container
direction="row"
justifyContent="start"
alignItems="center"
sx={{ mb: 1.4 }}
<>
{isLoadingReview || isLoadingReview === undefined ? (
<SkeletonUserReviews />
) : (
<ReviewsBox
profile={props.isProfileReviews}
className={props.className}
numOfReviews={lastThreeReviews?.length}
>
<StarBorderIcon color="action" sx={{ mr: 0.9 }} />
<ReviewsTitle>{t("reviews.rates")}</ReviewsTitle>
</ReviewsHeader>
{!props.givingReview && (
<ReviewsHeader
container
direction="row"
justifyContent="start"
alignItems="center"
sx={{ mb: 1.4 }}
>
<StarBorderIcon color="action" sx={{ mr: 0.9 }} />
<ReviewsTitle>{t("reviews.rates")}</ReviewsTitle>
</ReviewsHeader>
)}
<ReviewList>
{lastThreeReviews?.length > 0 ? (
lastThreeReviews?.map((review, index) => (
<UserReviewsCard
review={review}
key={index}
givingReview={props.givingReview}
/>
))
) : (
<NoReviews></NoReviews>
)}
</ReviewList>
</ReviewsBox>
)}
<ReviewList>
{lastThreeReviews?.length > 0 ? (
lastThreeReviews?.map((review, index) => (
<UserReviewsCard
review={review}
key={index}
givingReview={props.givingReview}
/>
))
) : (
<NoReviews></NoReviews>
)}
</ReviewList>
</ReviewsBox>
</>
);
};


+ 4
- 1
src/pages/ItemDetailsPage/ItemDetailsPageMUI.js Целия файл

@@ -4,7 +4,10 @@ import { ItemDetailsPageContainer } from "./ItemDetailsPage.styled";
import { useDispatch, useSelector } from "react-redux";
import ItemDetails from "../../components/ItemDetails/ItemDetails";
import ItemDetailsLayout from "../../layouts/ItemDetailsLayout/ItemDetailsLayout";
import { clearSelectedOffer, fetchOneOffer } from "../../store/actions/offers/offersActions";
import {
clearSelectedOffer,
fetchOneOffer,
} from "../../store/actions/offers/offersActions";
import UserReviews from "../../components/UserReviews/UserReviews";
import { selectOffer } from "../../store/selectors/offersSelectors";
import ProfileMini from "../../components/ProfileMini/ProfileMini";

+ 3
- 3
src/store/actions/profile/profileActionConstants.js Целия файл

@@ -11,7 +11,7 @@ export const PROFILE_FETCH = createFetchType(PROFILE_SCOPE);
export const PROFILE_SUCCESS = createSuccessType(PROFILE_SCOPE);
export const PROFILE_ERROR = createErrorType(PROFILE_SCOPE);

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_SUCCESS = createSuccessType(PROFILE_MINE_SCOPE);
export const PROFILE_MINE_FETCH_ERROR = createErrorType(PROFILE_MINE_SCOPE);
@@ -21,7 +21,7 @@ export const PROFILE_MINE_SET = createSetType("PROFILE_MINE_SET");

const PROFILE_EDIT_SCOPE = "PROFILE_EDIT_SCOPE";
export const PROFILE_EDIT = createFetchType(PROFILE_EDIT_SCOPE);
export const PROFILE_EDIT_SUCCESS = createSuccessType(PROFILE_EDIT_SCOPE)
export const PROFILE_EDIT_SUCCESS = createSuccessType(PROFILE_EDIT_SCOPE);
export const PROFILE_EDIT_ERROR = createErrorType(PROFILE_EDIT_SCOPE);

export const PROFILE_CLEAR = createClearType("PROFILE_CLEAR");
export const PROFILE_CLEAR = createClearType("PROFILE_CLEAR");

+ 9
- 4
src/store/actions/review/reviewActionConstants.js Целия файл

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

const REVIEW_GIVE_SCOPE = "REVIEW_GIVE_SCOPE";
export const REVIEW_GIVE_SCOPE = "REVIEW_GIVE_SCOPE";
export const REVIEW_GIVE = createFetchType(REVIEW_GIVE_SCOPE);
export const REVIEW_GIVE_SUCCESS = createSuccessType(REVIEW_GIVE_SCOPE);
export const REVIEW_GIVE_ERROR = createErrorType(REVIEW_GIVE_SCOPE);

const REVIEW_GET_SCOPE = "REVIEW_GET_SCOPE";
export const REVIEW_GET_SCOPE = "REVIEW_GET_SCOPE";
export const REVIEW_GET = createFetchType(REVIEW_GET_SCOPE);
export const REVIEW_GET_SUCCESS = createSuccessType(REVIEW_GET_SCOPE);
export const REVIEW_GET_ERROR = createErrorType(REVIEW_GET_SCOPE);

export const REVIEW_SET = createSetType("REVIEW_SET");
export const REVIEW_SET = createSetType("REVIEW_SET");

Loading…
Отказ
Запис