| @@ -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") { | |||
| @@ -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 ( | |||
| <> | |||
| @@ -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; | |||
| `; | |||
| @@ -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; | |||
| `; | |||
| @@ -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; | |||
| `; | |||
| @@ -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> | |||
| ); | |||
| }; | |||
| @@ -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; | |||
| @@ -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; | |||
| `; | |||
| @@ -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> | |||
| )} | |||
| </> | |||
| ); | |||
| }; | |||
| @@ -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; | |||
| @@ -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; | |||
| `; | |||
| @@ -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; | |||
| @@ -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; | |||
| `} | |||
| `; | |||
| @@ -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; | |||
| @@ -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; | |||
| `; | |||
| @@ -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,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"; | |||
| @@ -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"); | |||
| @@ -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"); | |||