| @@ -0,0 +1,6 @@ | |||
| <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M9.66754 1.08749L15.6675 4.08749C15.9174 4.21167 16.1278 4.40311 16.2748 4.64027C16.4219 4.87744 16.4999 5.15093 16.5 5.42999V12.5775C16.4999 12.8566 16.4219 13.13 16.2748 13.3672C16.1278 13.6044 15.9174 13.7958 15.6675 13.92L9.66754 16.92C9.45914 17.0243 9.22932 17.0786 8.99629 17.0786C8.76326 17.0786 8.53343 17.0243 8.32504 16.92L2.32504 13.92C2.07538 13.7942 1.86585 13.6011 1.72008 13.3626C1.5743 13.1241 1.49809 12.8495 1.50004 12.57V5.42999C1.50018 5.15093 1.57818 4.87744 1.72525 4.64027C1.87231 4.40311 2.08263 4.21167 2.33254 4.08749L8.33254 1.08749C8.53995 0.984422 8.76842 0.930786 9.00004 0.930786C9.23165 0.930786 9.46012 0.984422 9.66754 1.08749V1.08749Z" stroke="#4C4C4C" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M1.74023 4.62L9.00023 8.25L16.2602 4.62" stroke="#4C4C4C" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M9 17.07V8.25" stroke="#4C4C4C" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M5.25 2.625L12.75 6.375" stroke="#4C4C4C" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M16.6663 17.5V15.8333C16.6663 14.9493 16.3152 14.1014 15.69 13.4763C15.0649 12.8512 14.2171 12.5 13.333 12.5H6.66634C5.78229 12.5 4.93444 12.8512 4.30932 13.4763C3.6842 14.1014 3.33301 14.9493 3.33301 15.8333V17.5" stroke="#4D4D4D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M10.0003 9.16667C11.8413 9.16667 13.3337 7.67428 13.3337 5.83333C13.3337 3.99238 11.8413 2.5 10.0003 2.5C8.15938 2.5 6.66699 3.99238 6.66699 5.83333C6.66699 7.67428 8.15938 9.16667 10.0003 9.16667Z" stroke="#4D4D4D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -53,7 +53,6 @@ const ItemDetailsCard = (props) => { | |||
| } | |||
| }, [offer]); | |||
| const date = formatDateLocale(new Date(offer?.offer?._created)); | |||
| const startExchange = () => { | |||
| @@ -74,6 +73,7 @@ const ItemDetailsCard = (props) => { | |||
| sponsored={props.sponsored.toString()} | |||
| halfwidth={props.halfwidth ? 1 : 0} | |||
| className={props.className} | |||
| singleOffer={props.singleOffer} | |||
| > | |||
| <OfferInfo> | |||
| <Info> | |||
| @@ -94,28 +94,28 @@ const ItemDetailsCard = (props) => { | |||
| value={offer?.offer?.views?.count} | |||
| /> | |||
| </Info> | |||
| <DateButtonsContainer> | |||
| <PostDate>{date}</PostDate> | |||
| {props.isMyOffer && ( | |||
| <ButtonsContainer> | |||
| <EditDeleteButtons> | |||
| <EditIconContainer onClick={() => setShowModalEdit(true)}> | |||
| <EditIcon /> | |||
| </EditIconContainer> | |||
| <RemoveIconContainer onClick={() => setShowModalRemove(true)}> | |||
| <RemoveIcon /> | |||
| </RemoveIconContainer> | |||
| </EditDeleteButtons> | |||
| </ButtonsContainer> | |||
| )} | |||
| </DateButtonsContainer> | |||
| <PostDate>{date}</PostDate> | |||
| </OfferInfo> | |||
| <OfferDetails | |||
| offer={offer} | |||
| showExchangeButton={props.showExchangeButton} | |||
| showPublishButton={props.showPublishButton} | |||
| singleOffer={props.singleOffer} | |||
| /> | |||
| <DateButtonsContainer> | |||
| {props.isMyOffer && ( | |||
| <ButtonsContainer> | |||
| <EditDeleteButtons> | |||
| <EditIconContainer onClick={() => setShowModalEdit(true)}> | |||
| <EditIcon /> | |||
| </EditIconContainer> | |||
| <RemoveIconContainer onClick={() => setShowModalRemove(true)}> | |||
| <RemoveIcon /> | |||
| </RemoveIconContainer> | |||
| </EditDeleteButtons> | |||
| </ButtonsContainer> | |||
| )} | |||
| </DateButtonsContainer> | |||
| {!props.halfwidth && props.showExchangeButton && ( | |||
| <CheckButton | |||
| variant={props.sponsored ? "contained" : "outlined"} | |||
| @@ -154,6 +154,7 @@ ItemDetailsCard.propTypes = { | |||
| showBarterButton: PropTypes.bool, | |||
| showPublishButton: PropTypes.bool, | |||
| className: PropTypes.string, | |||
| singleOffer: PropTypes.bool, | |||
| isMyOffer: PropTypes.bool, | |||
| }; | |||
| ItemDetailsCard.defaultProps = { | |||
| @@ -17,7 +17,7 @@ export const ItemDetailsCardContainer = styled(Container)` | |||
| flex-direction: column; | |||
| width: ${(props) => (!props.halfwidth ? "100%" : "49%")}; | |||
| box-sizing: border-box; | |||
| margin: 10px 0; | |||
| margin: ${(props) => (props.singleOffer ? "10px 36px" : "10px 0")}; | |||
| border: 1px solid ${selectedTheme.borderNormal}; | |||
| background-color: ${(props) => | |||
| props.sponsored === "true" | |||
| @@ -31,6 +31,7 @@ export const ItemDetailsCardContainer = styled(Container)` | |||
| /* padding-bottom: 70px; */ | |||
| @media (max-width: 600px) { | |||
| margin: 18px 0; | |||
| padding: 10px; | |||
| padding-bottom: 65px; | |||
| } | |||
| @@ -116,6 +117,14 @@ export const RemoveIcon = styled(Remove)` | |||
| export const DateButtonsContainer = styled(Box)` | |||
| display: flex; | |||
| align-items: center; | |||
| position: absolute; | |||
| right: 220px; | |||
| bottom: 22px; | |||
| @media screen and (max-width: 600px) { | |||
| top: 0; | |||
| right: -10px; | |||
| } | |||
| `; | |||
| export const PostDate = styled(Typography)` | |||
| @@ -7,32 +7,49 @@ import { | |||
| OfferImage, | |||
| OfferLittleDetails, | |||
| OfferTitle, | |||
| Scroller, | |||
| ScrollerHorizontal, | |||
| ScrollerVertical, | |||
| OfferInfoContainer, | |||
| } from "./OfferDetails.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import useScreenDimensions from "../../../../hooks/useScreenDimensions"; | |||
| const OfferDetails = (props) => { | |||
| const offer = props.offer; | |||
| const { t } = useTranslation(); | |||
| const dimension = useScreenDimensions(); | |||
| return ( | |||
| <Details | |||
| hasScrollBar={!props.showPublishButton} | |||
| exchange={props.showExchangeButton} | |||
| singleOffer={props.singleOffer} | |||
| > | |||
| <OfferTitle>{offer?.offer?.name}</OfferTitle> | |||
| <Scroller> | |||
| {offer?.offer?.images?.map((item) => { | |||
| return <OfferImage src={item} key={item} />; | |||
| })} | |||
| </Scroller> | |||
| <OfferLittleDetails> | |||
| <OfferDescriptionTitle> | |||
| {t("itemDetailsCard.description")} | |||
| </OfferDescriptionTitle> | |||
| <OfferDescriptionText showBarterButton={props.showExchangeButton}> | |||
| {offer?.offer?.description} | |||
| </OfferDescriptionText> | |||
| </OfferLittleDetails> | |||
| {dimension.width < 600 || !props.singleOffer ? ( | |||
| <ScrollerHorizontal> | |||
| {offer?.offer?.images?.map((item) => { | |||
| return <OfferImage src={item} key={item} />; | |||
| })} | |||
| </ScrollerHorizontal> | |||
| ) : ( | |||
| <ScrollerVertical> | |||
| {offer?.offer?.images?.map((item) => { | |||
| return <OfferImage src={item} key={item} />; | |||
| })} | |||
| </ScrollerVertical> | |||
| )} | |||
| <OfferInfoContainer> | |||
| <OfferTitle singleOffer={props.singleOffer}> | |||
| {offer?.offer?.name} | |||
| </OfferTitle> | |||
| <OfferLittleDetails singleOffer={props.singleOffer}> | |||
| <OfferDescriptionTitle> | |||
| {t("itemDetailsCard.description")} | |||
| </OfferDescriptionTitle> | |||
| <OfferDescriptionText showBarterButton={props.showExchangeButton}> | |||
| {offer?.offer?.description} | |||
| </OfferDescriptionText> | |||
| </OfferLittleDetails> | |||
| </OfferInfoContainer> | |||
| </Details> | |||
| ); | |||
| }; | |||
| @@ -41,6 +58,7 @@ OfferDetails.propTypes = { | |||
| offer: PropTypes.any, | |||
| showExchangeButton: PropTypes.bool, | |||
| showPublishButton: PropTypes.bool, | |||
| singleOffer: PropTypes.bool, | |||
| }; | |||
| export default OfferDetails; | |||
| @@ -2,10 +2,12 @@ import { Box, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../../themes"; | |||
| import HorizontalScroller from "../../../Scroller/HorizontalScroller"; | |||
| import VerticalScroller from "../../../Scroller/VerticalScroller"; | |||
| export const Details = styled(Box)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| flex-direction: ${(props) => (props.singleOffer ? "row" : "column-reverse")}; | |||
| justify-content: start; | |||
| gap: 12px; | |||
| ${(props) => props.hasScrollBar && !props.exchange && `height: 300px;`} | |||
| overflow-y: auto; | |||
| @@ -19,9 +21,12 @@ export const Details = styled(Box)` | |||
| } | |||
| @media screen and (max-width: 600px) { | |||
| flex-direction: column-reverse; | |||
| margin-top: 15px; | |||
| min-height: 300px; | |||
| ${(props) => | |||
| !props.hasScrollBar && props.exchange && | |||
| !props.hasScrollBar && | |||
| props.exchange && | |||
| ` | |||
| overflow: hidden; | |||
| max-height: none;`} | |||
| @@ -34,9 +39,10 @@ export const OfferTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| padding: 0 60px; | |||
| padding: ${(props) => (props.singleOffer ? 0 : "0 60px")}; | |||
| @media screen and (max-width: 600px) { | |||
| padding: 0; | |||
| padding: 0 8px; | |||
| font-size: 18px; | |||
| } | |||
| `; | |||
| @@ -45,12 +51,32 @@ export const OfferLittleDetails = styled(Box)` | |||
| flex-direction: column; | |||
| flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")}; | |||
| justify-content: space-between; | |||
| padding: 0 60px; | |||
| padding: ${(props) => (props.singleOffer ? 0 : "0 60px")}; | |||
| ${(props) => | |||
| !props.singleOffer && | |||
| ` | |||
| position: absolute; | |||
| bottom: 45px; | |||
| `} | |||
| @media (max-width: 600px) { | |||
| padding: 0; | |||
| padding: 0 8px; | |||
| position: absolute; | |||
| top: 270px; | |||
| left: 18px; | |||
| justify-content: start; | |||
| } | |||
| `; | |||
| export const Scroller = styled(HorizontalScroller)` | |||
| export const ScrollerHorizontal = styled(HorizontalScroller)` | |||
| min-height: 144px; | |||
| min-width: 144px; | |||
| max-width: 100%; | |||
| max-height: 144px; | |||
| align-items: start; | |||
| /* & div { | |||
| margin: 0 9px; | |||
| } */ | |||
| `; | |||
| export const ScrollerVertical = styled(VerticalScroller)` | |||
| min-height: 144px; | |||
| min-width: 144px; | |||
| max-width: 100%; | |||
| @@ -58,6 +84,7 @@ export const Scroller = styled(HorizontalScroller)` | |||
| margin: 0 9px; | |||
| } */ | |||
| `; | |||
| export const OfferInfoContainer = styled(Box)``; | |||
| export const OfferDescriptionTitle = styled(Box)` | |||
| font-family: "Open Sans"; | |||
| font-size: 12px; | |||
| @@ -74,7 +101,8 @@ export const OfferDescriptionText = styled(Box)` | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| line-height: 22px; | |||
| padding-bottom: 20px; | |||
| max-width: ${(props) => props.showBarterButton ? "calc(100% - 230px)" : "100%"}; | |||
| max-width: ${(props) => | |||
| props.showBarterButton ? "calc(100% - 230px)" : "100%"}; | |||
| @media (max-width: 600px) { | |||
| font-size: 14px; | |||
| max-width: 100%; | |||
| @@ -98,4 +126,4 @@ export const OfferImage = styled.img` | |||
| min-width: 144px; | |||
| margin-right: 13px; | |||
| } | |||
| `; | |||
| `; | |||
| @@ -73,7 +73,7 @@ export const ImageUploadedContainer = styled(Box)` | |||
| width: 144px; | |||
| height: 144px; | |||
| overflow: hidden; | |||
| ` | |||
| `; | |||
| export const ImageOverlay = styled(Box)` | |||
| position: absolute; | |||
| top: 0; | |||
| @@ -1,22 +1,22 @@ | |||
| import { Box, Link, Typography} from "@mui/material"; | |||
| import { Box, Link, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| export const HeaderContainer = styled(Box)` | |||
| margin-top: 20px; | |||
| ` | |||
| margin-top: 20px; | |||
| `; | |||
| export const ButtonContainer = styled(Link)` | |||
| width:fit-content; | |||
| cursor:pointer; | |||
| display: flex; | |||
| justify-content: start; | |||
| align-items:center; | |||
| gap:12px; | |||
| ` | |||
| export const HeaderText = styled(Typography) ` | |||
| font-family: "Open Sans"; | |||
| line-height: 22px; | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| text-decoration: underline; | |||
| ` | |||
| width: fit-content; | |||
| cursor: pointer; | |||
| display: flex; | |||
| justify-content: start; | |||
| align-items: center; | |||
| gap: 12px; | |||
| `; | |||
| export const HeaderText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| line-height: 22px; | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| text-decoration: underline; | |||
| `; | |||
| @@ -1,16 +1,23 @@ | |||
| import React, { useMemo } from "react"; | |||
| import { PropTypes } from "prop-types"; | |||
| import Header from "./Header/Header"; | |||
| import { useSelector } from "react-redux"; | |||
| import { ItemDetailsContainer } from "./ItemDetails.styled"; | |||
| import { | |||
| ItemDetailsContainer, | |||
| OfferIconContainer, | |||
| OfferIconText, | |||
| } from "./ItemDetails.styled"; | |||
| import ItemDetailsCard from "../Cards/ItemDetailsCard/ItemDetailsCard"; | |||
| import ItemDetailsHeaderCard from "./ItemDetailsHeaderCard/ItemDetailsHeaderCard"; | |||
| import { selectOffer } from "../../store/selectors/offersSelectors"; | |||
| import { selectUserId } from "../../store/selectors/loginSelectors"; | |||
| // import { useHistory } from 'react-router-dom'; | |||
| import { ReactComponent as OfferIcon } from "../../assets/images/svg/package-gray.svg"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const ItemDetails = () => { | |||
| const ItemDetails = (props) => { | |||
| const offer = useSelector(selectOffer); | |||
| const userId = useSelector(selectUserId); | |||
| const { t } = useTranslation(); | |||
| let isMyProfile = useMemo(() => { | |||
| if (offer?.offer?.userId?.toString() === userId?.toString()) { | |||
| return true; | |||
| @@ -20,10 +27,22 @@ const ItemDetails = () => { | |||
| return ( | |||
| <ItemDetailsContainer> | |||
| <Header /> | |||
| <ItemDetailsHeaderCard offer={offer} isMyProfile={isMyProfile} /> | |||
| <ItemDetailsCard offer={offer} isMyOffer={isMyProfile} /> | |||
| {!props.singleOffer && ( | |||
| <ItemDetailsHeaderCard offer={offer} isMyProfile={isMyProfile} /> | |||
| )} | |||
| {props.singleOffer && ( | |||
| <OfferIconContainer> | |||
| <OfferIcon /> | |||
| <OfferIconText>{t("offer.product")}</OfferIconText> | |||
| </OfferIconContainer> | |||
| )} | |||
| <ItemDetailsCard offer={offer} isMyOffer={isMyProfile} singleOffer /> | |||
| </ItemDetailsContainer> | |||
| ); | |||
| }; | |||
| ItemDetails.propTypes = { | |||
| singleOffer: PropTypes.any, | |||
| }; | |||
| export default ItemDetails; | |||
| @@ -1,6 +1,30 @@ | |||
| import { Box } from "@mui/material"; | |||
| import { Box, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| export const ItemDetailsContainer = styled(Box)` | |||
| export const ItemDetailsContainer = styled(Box)``; | |||
| `; | |||
| export const OfferIconContainer = styled(Box)` | |||
| display: flex; | |||
| align-items: center; | |||
| margin-top: 34px; | |||
| margin-left: 36px; | |||
| @media screen and (max-width: 600px) { | |||
| margin-left: 0; | |||
| margin-top: 228px; | |||
| svg { | |||
| width: 14px; | |||
| } | |||
| } | |||
| `; | |||
| export const OfferIconText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| margin-left: 7.2px; | |||
| @media screen and (max-width: 600px) { | |||
| font-size: 12px; | |||
| } | |||
| `; | |||
| @@ -53,8 +53,8 @@ const ItemDetailsHeaderCard = (props) => { | |||
| <OfferTitle isMyProfile={props.isMyProfile} onClick={handleGoProfile}> | |||
| {offer?.companyData?.company?.name} | |||
| </OfferTitle> | |||
| <PIBDetail offer={props.offer} isMyProfile={props.isMyProfile}/> | |||
| <CategoryDetail offer={props.offer} isMyProfile={props.isMyProfile}/> | |||
| <PIBDetail offer={props.offer} isMyProfile={props.isMyProfile} /> | |||
| <CategoryDetail offer={props.offer} isMyProfile={props.isMyProfile} /> | |||
| </OfferDetails> | |||
| {props.isMyProfile ? ( | |||
| <UserIconContainer onClick={handleGoProfile}> | |||
| @@ -66,8 +66,7 @@ const ItemDetailsHeaderCard = (props) => { | |||
| </MessageIcon> | |||
| )} | |||
| </HeaderTop> | |||
| <StatisticDetails offer={offer} /> | |||
| {!props.singleOffer && <StatisticDetails offer={offer} />} | |||
| </ItemDetailsHeaderContainer> | |||
| ); | |||
| }; | |||
| @@ -88,6 +87,7 @@ ItemDetailsHeaderCard.propTypes = { | |||
| sponsored: PropTypes.bool, | |||
| offer: PropTypes.any, | |||
| isMyProfile: PropTypes.bool, | |||
| singleOffer: PropTypes.bool, | |||
| }; | |||
| ItemDetailsHeaderCard.defaultProps = { | |||
| halfwidth: false, | |||
| @@ -3,8 +3,7 @@ import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { IconButton } from "../../Buttons/IconButton/IconButton"; | |||
| import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | |||
| import { ReactComponent as User} from "../../../assets/images/svg/user.svg"; | |||
| import { ReactComponent as User } from "../../../assets/images/svg/user.svg"; | |||
| export const ItemDetailsHeaderContainer = styled(Box)` | |||
| display: flex; | |||
| @@ -13,13 +12,15 @@ export const ItemDetailsHeaderContainer = styled(Box)` | |||
| box-sizing: border-box; | |||
| margin: 10px 0; | |||
| background-color: ${(props) => | |||
| props.isMyProfile | |||
| ? selectedTheme.primaryPurple | |||
| : "white"}; | |||
| props.isMyProfile ? selectedTheme.primaryPurple : "white"}; | |||
| border-radius: 4px; | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| max-width: 2000px; | |||
| position: relative; | |||
| @media screen and (max-width: 600px) { | |||
| width: 92%; | |||
| } | |||
| `; | |||
| export const HeaderTop = styled(Box)` | |||
| display: flex; | |||
| @@ -46,7 +47,10 @@ export const OfferInfo = styled(Box)` | |||
| export const OfferTitle = styled(Typography)` | |||
| margin-bottom: 12px; | |||
| font-family: "Open Sans"; | |||
| color: ${props => props.isMyProfile ? selectedTheme.primaryYellow : selectedTheme.primaryPurple}; | |||
| color: ${(props) => | |||
| props.isMyProfile | |||
| ? selectedTheme.primaryYellow | |||
| : selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| cursor: pointer; | |||
| @@ -73,7 +77,10 @@ export const OfferLocation = styled(Box)` | |||
| `; | |||
| export const OfferPIB = styled(Box)` | |||
| font-family: "Open Sans"; | |||
| color: ${props => props.isMyProfile ? selectedTheme.primaryDarkTextThird : selectedTheme.primaryText}; | |||
| color: ${(props) => | |||
| props.isMyProfile | |||
| ? selectedTheme.primaryDarkTextThird | |||
| : selectedTheme.primaryText}; | |||
| line-height: 16px; | |||
| font-size: 12px; | |||
| `; | |||
| @@ -82,7 +89,6 @@ export const OfferDetails = styled(Box)` | |||
| flex-direction: column; | |||
| flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")}; | |||
| justify-content: start; | |||
| `; | |||
| export const OfferCategory = styled(Box)` | |||
| @@ -171,7 +177,5 @@ export const MessageIcon = styled(IconButton)` | |||
| `; | |||
| export const UserIconContainer = styled(MessageIcon)` | |||
| background-color: ${selectedTheme.primaryIconBackgroundColor}; | |||
| ` | |||
| export const UserIcon = styled(User)` | |||
| ` | |||
| `; | |||
| export const UserIcon = styled(User)``; | |||
| @@ -0,0 +1,39 @@ | |||
| import React, { useMemo } from "react"; | |||
| import { | |||
| ProfileHeader, | |||
| ProfileHeaderIconContainer, | |||
| ProfileHeaderText, | |||
| } from "./ProfileMini.styled"; | |||
| import { useSelector } from "react-redux"; | |||
| import { selectOffer } from "../../store/selectors/offersSelectors"; | |||
| 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"; | |||
| const ProfileMini = () => { | |||
| const offer = useSelector(selectOffer); | |||
| const userId = useSelector(selectUserId); | |||
| const { t } = useTranslation(); | |||
| let isMyProfile = useMemo(() => { | |||
| if (offer?.offer?.userId?.toString() === userId?.toString()) { | |||
| return true; | |||
| } | |||
| return false; | |||
| }, [offer, userId]); | |||
| return ( | |||
| <ProfileHeader> | |||
| <ProfileHeaderIconContainer> | |||
| <ProfileIcon /> | |||
| <ProfileHeaderText>{t("profile.companyProfile")}</ProfileHeaderText> | |||
| </ProfileHeaderIconContainer> | |||
| <ItemDetailsHeaderCard | |||
| offer={offer} | |||
| isMyProfile={isMyProfile} | |||
| singleOffer | |||
| /> | |||
| </ProfileHeader> | |||
| ); | |||
| }; | |||
| export default ProfileMini; | |||
| @@ -0,0 +1,33 @@ | |||
| import styled from "styled-components"; | |||
| import { Box } from "@mui/system"; | |||
| import { Typography } from "@mui/material"; | |||
| export const ProfileHeader = styled(Box)` | |||
| margin-top: 60px; | |||
| @media screen and (max-width: 600px) { | |||
| width: 100%; | |||
| position: absolute; | |||
| top: 25px; | |||
| } | |||
| `; | |||
| export const ProfileHeaderIconContainer = styled(Box)` | |||
| display: flex; | |||
| align-items: center; | |||
| @media screen and (max-width: 600px) { | |||
| margin-bottom: 18px; | |||
| svg { | |||
| width: 14px; | |||
| } | |||
| } | |||
| `; | |||
| export const ProfileHeaderText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| margin-left: 7.2px; | |||
| @media screen and (max-width: 600px) { | |||
| font-size: 12px; | |||
| } | |||
| `; | |||
| @@ -54,7 +54,10 @@ const HorizontalScroller = (props) => { | |||
| scrollRef.current.scrollBy({ left: -50, behaviour: "smooth" }); | |||
| }; | |||
| return ( | |||
| <HorizontalScrollerContainer style={props.containerStyle} className={props.className}> | |||
| <HorizontalScrollerContainer | |||
| style={props.containerStyle} | |||
| className={props.className} | |||
| > | |||
| {!props.hideArrows && ( | |||
| <ArrowButton | |||
| onClick={handleLeft} | |||
| @@ -9,6 +9,7 @@ export const HorizontalScrollerContainer = styled(Box)` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: row; | |||
| align-items: center; | |||
| flex-wrap: nowrap; | |||
| overflow: hidden; | |||
| padding-right: 5px; | |||
| @@ -0,0 +1,99 @@ | |||
| import React, { useRef, useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| VerticalScrollerContainer, | |||
| ListContainer, | |||
| ArrowIconContainer, | |||
| } from "./VerticalScroller.styled"; | |||
| import { ArrowButton } from "../Buttons/ArrowButton/ArrowButton"; | |||
| const VerticalScroller = (props) => { | |||
| const scrollRef = useRef(null); | |||
| const [isDisabledUpButton, setIsDisabledUpButton] = useState(true); | |||
| const [isDisabledDownButton, setIsDisabledDownButton] = useState(false); | |||
| const handleScroll = (event) => { | |||
| if (!event.external) { | |||
| if (scrollRef.current.scrollTop === 0) { | |||
| if (isDisabledUpButton !== true) setIsDisabledUpButton(true); | |||
| } else { | |||
| if (isDisabledUpButton !== false) setIsDisabledUpButton(false); | |||
| } | |||
| if ( | |||
| scrollRef.current.scrollHeight - scrollRef.current.scrollTop === | |||
| scrollRef.current.clientHeight | |||
| ) { | |||
| if (isDisabledDownButton !== true) setIsDisabledDownButton(true); | |||
| } else { | |||
| if (isDisabledDownButton !== false) setIsDisabledDownButton(false); | |||
| } | |||
| } | |||
| }; | |||
| const handleRight = () => { | |||
| if (scrollRef.current.scrollTop + 50 !== 0) { | |||
| if (isDisabledUpButton !== false) setIsDisabledUpButton(false); | |||
| } | |||
| if ( | |||
| scrollRef.current.scrollHeight - scrollRef.current.scrollTop - 50 <= | |||
| scrollRef.current.clientHeight | |||
| ) { | |||
| if (isDisabledDownButton !== true) setIsDisabledDownButton(true); | |||
| } | |||
| scrollRef.current.scrollBy({ top: 50, behaviour: "smooth" }); | |||
| }; | |||
| const handleLeft = () => { | |||
| if (scrollRef.current.scrollHeight - 50 <= 0) { | |||
| if (isDisabledUpButton !== true) setIsDisabledUpButton(true); | |||
| } | |||
| if ( | |||
| scrollRef.current.scrollHeight - scrollRef.current.scrollTop + 50 !== | |||
| scrollRef.current.clientHeight | |||
| ) { | |||
| if (isDisabledDownButton !== false) setIsDisabledDownButton(false); | |||
| } | |||
| scrollRef.current.scrollBy({ top: -50, behaviour: "smooth" }); | |||
| }; | |||
| return ( | |||
| <VerticalScrollerContainer | |||
| style={props.containerStyle} | |||
| className={props.className} | |||
| > | |||
| {!props.hideArrows && ( | |||
| <ArrowIconContainer side="up"> | |||
| <ArrowButton | |||
| onClick={handleLeft} | |||
| disabled={isDisabledUpButton} | |||
| side={"up"} | |||
| ></ArrowButton> | |||
| </ArrowIconContainer> | |||
| )} | |||
| <ListContainer | |||
| innerRef={scrollRef} | |||
| style={props.listStyle} | |||
| onScroll={handleScroll} | |||
| > | |||
| {props.children} | |||
| </ListContainer> | |||
| {!props.hideArrows && ( | |||
| <ArrowIconContainer> | |||
| <ArrowButton | |||
| onClick={handleRight} | |||
| disabled={isDisabledDownButton} | |||
| side={"down"} | |||
| ></ArrowButton> | |||
| </ArrowIconContainer> | |||
| )} | |||
| </VerticalScrollerContainer> | |||
| ); | |||
| }; | |||
| VerticalScroller.propTypes = { | |||
| children: PropTypes.node, | |||
| className: PropTypes.string, | |||
| containerStyle: PropTypes.any, | |||
| listStyle: PropTypes.any, | |||
| hideArrows: PropTypes.bool, | |||
| }; | |||
| export default VerticalScroller; | |||
| @@ -0,0 +1,91 @@ | |||
| import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import { ReactComponent as DownArrow } from "../../assets/images/svg/arrow-down.svg"; | |||
| import selectedTheme from "../../themes"; | |||
| import ScrollContainer from "react-indiana-drag-scroll"; | |||
| import { IconButton } from "../Buttons/IconButton/IconButton"; | |||
| export const VerticalScrollerContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| flex-wrap: nowrap; | |||
| overflow: hidden; | |||
| padding-right: 5px; | |||
| height: 594px; | |||
| @media screen and (max-width: 600px) { | |||
| width: 100%; | |||
| } | |||
| @media screen and (max-width: 480px) { | |||
| width: 340px; | |||
| } | |||
| `; | |||
| export const Arrow = styled(IconButton)` | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| border-radius: 100%; | |||
| min-width: 40px; | |||
| width: 40px; | |||
| height: 40px; | |||
| display: block; | |||
| box-sizing: border-box; | |||
| cursor: pointer; | |||
| padding-left: 8px; | |||
| padding-top: 10px; | |||
| margin-top: auto; | |||
| margin-bottom: auto; | |||
| transition: 0.2s all ease; | |||
| &:hover { | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| & svg path { | |||
| stroke: white; | |||
| } | |||
| } | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| border 1px solid ${selectedTheme.iconStrokeDisabledColor}; | |||
| & svg path { | |||
| stroke: ${selectedTheme.iconStrokeDisabledColor}; | |||
| transition: 0.2s all ease; | |||
| } | |||
| `} | |||
| `; | |||
| export const ListContainer = styled(ScrollContainer)` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: column; | |||
| flex-wrap: nowrap; | |||
| scroll-behavior: smooth; | |||
| margin: 0 18px; | |||
| user-select: none; | |||
| img { | |||
| margin: 0; | |||
| margin-top: 18px; | |||
| } | |||
| `; | |||
| export const ArrowIconContainer = styled(Box)` | |||
| transform: ${(props) => | |||
| props.side === "up" ? "rotate(-90deg)" : "rotate(90deg)"}; | |||
| `; | |||
| export const ArrowIcon = styled(DownArrow)` | |||
| /* ${(props) => | |||
| props.side === "up" && | |||
| ` | |||
| transform: rotate(-90deg); | |||
| `} */ | |||
| width: 18px; | |||
| height: 18px; | |||
| & path { | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| stroke: ${selectedTheme.iconStrokeDisabledColor} | |||
| `} | |||
| } | |||
| `; | |||
| @@ -85,6 +85,7 @@ UserReviews.propTypes = { | |||
| profileReviews: PropTypes.any, | |||
| className: PropTypes.string, | |||
| givingReview: PropTypes.bool, | |||
| offer: PropTypes.any, | |||
| }; | |||
| UserReviews.defaultProps = { | |||
| isProfileReviews: false, | |||
| @@ -5,68 +5,77 @@ import ThumbDownIcon from "@mui/icons-material/ThumbDown"; | |||
| import selectedTheme from "../../themes"; | |||
| export const ReviewsBox = styled(Box)` | |||
| width: 100%; | |||
| /* One review is 185px in height and 82 px are header title + padding */ | |||
| /* height: ${props => props.numOfReviews > 0 ? props.numOfReviews * 185 + 82 + 'px' : `calc(100% - 90px)`}; */ | |||
| /* max-height: 100vh; */ | |||
| @media (max-width: 1200px) { | |||
| padding: 0 50px; | |||
| } | |||
| @media (max-width: 600px) { | |||
| position: relative; | |||
| top: -45px; | |||
| overflow: hidden; | |||
| max-height: ${props => props.numOfReviews > 2 ? "650px" : props.numOfReviews > 1 ? "450px" : "350px"}; | |||
| padding: 0; | |||
| } | |||
| width: 100%; | |||
| /* One review is 185px in height and 82 px are header title + padding */ | |||
| /* height: ${(props) => | |||
| props.numOfReviews > 0 | |||
| ? props.numOfReviews * 185 + 82 + "px" | |||
| : `calc(100% - 90px)`}; */ | |||
| /* max-height: 100vh; */ | |||
| @media (max-width: 1200px) { | |||
| padding: 0 50px; | |||
| } | |||
| @media (max-width: 600px) { | |||
| position: relative; | |||
| top: -45px; | |||
| overflow: hidden; | |||
| max-height: ${(props) => | |||
| props.numOfReviews > 2 | |||
| ? "650px" | |||
| : props.numOfReviews > 1 | |||
| ? "450px" | |||
| : "350px"}; | |||
| padding: 0; | |||
| margin-top: 60px; | |||
| } | |||
| `; | |||
| export const ReviewsHeader = styled(Grid)` | |||
| @media (max-width: 800px) { | |||
| display: none; | |||
| @media (max-width: 600px) { | |||
| margin-bottom: 18px; | |||
| font-size: 12px; | |||
| } | |||
| ` | |||
| `; | |||
| export const ReviewsTitle = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| @media (max-width: 800px) { | |||
| display: none; | |||
| @media (max-width: 600px) { | |||
| font-size: 12px; | |||
| } | |||
| ` | |||
| `; | |||
| export const ReviewList = styled(List)` | |||
| background: white; | |||
| padding: 2rem; | |||
| border-radius: 4px 0 0 4px; | |||
| padding-right: .4rem; | |||
| height: 100%; | |||
| width: 100%; | |||
| border: 1px solid ${selectedTheme.borderNormal}; | |||
| background: white; | |||
| padding: 2rem; | |||
| border-radius: 4px 0 0 4px; | |||
| padding-right: 0.4rem; | |||
| height: 100%; | |||
| width: 100%; | |||
| border: 1px solid ${selectedTheme.borderNormal}; | |||
| /* overflow-y: auto; */ | |||
| &::-webkit-scrollbar { | |||
| width: 5px; | |||
| } | |||
| &::-webkit-scrollbar-track { | |||
| background: #ddd; | |||
| } | |||
| &::-webkit-scrollbar-thumb { | |||
| background: #777; | |||
| } | |||
| scrollbar-width: thin; | |||
| scrollbar-color: #ddd; | |||
| /* overflow-y: auto; */ | |||
| &::-webkit-scrollbar { | |||
| width: 5px; | |||
| } | |||
| &::-webkit-scrollbar-track { | |||
| background: #ddd; | |||
| } | |||
| &::-webkit-scrollbar-thumb { | |||
| background: #777; | |||
| } | |||
| scrollbar-width: thin; | |||
| scrollbar-color: #ddd; | |||
| `; | |||
| export const ThumbUp = styled(ThumbUpIcon)` | |||
| position: relative; | |||
| left: -8px; | |||
| ` | |||
| `; | |||
| export const ThumbDown = styled(ThumbDownIcon)` | |||
| position: relative; | |||
| left: -8px; | |||
| ` | |||
| export const NoReviewsContainer = styled(Box)` | |||
| ` | |||
| `; | |||
| export const NoReviewsContainer = styled(Box)``; | |||
| export const NoReviewsText = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-size: 24px; | |||
| @@ -74,8 +83,7 @@ export const NoReviewsText = styled(Typography)` | |||
| text-align: center; | |||
| font-weight: 700; | |||
| width: 100%; | |||
| ` | |||
| `; | |||
| export const NoReviewsAltText = styled(Typography)` | |||
| font-size: 12px; | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| @@ -83,49 +91,45 @@ export const NoReviewsAltText = styled(Typography)` | |||
| text-align: center; | |||
| width: 100%; | |||
| margin-bottom: 36px; | |||
| ` | |||
| `; | |||
| export const ProfileImage = styled.img` | |||
| width: 54px; | |||
| height: 54px; | |||
| border-radius: 100%; | |||
| ` | |||
| `; | |||
| export const ProfileImageContainer = styled(Box)` | |||
| width: 54px; | |||
| height: 54px; | |||
| border-radius: 100%; | |||
| margin-right: 14px; | |||
| ` | |||
| `; | |||
| export const ReviewQuote = styled(Grid)` | |||
| position: relative; | |||
| left: 8px; | |||
| ` | |||
| export const ThumbBox = styled(Grid)` | |||
| ` | |||
| export const ReviewQuoteBox = styled(Grid)` | |||
| ` | |||
| `; | |||
| export const ThumbBox = styled(Grid)``; | |||
| export const ReviewQuoteBox = styled(Grid)``; | |||
| export const ReviewQuoteText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 12px; | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| ` | |||
| export const ReviewDetails = styled(Grid)` | |||
| ` | |||
| `; | |||
| export const ReviewDetails = styled(Grid)``; | |||
| export const ReviewDetailsText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 12px; | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| font-style: italic; | |||
| letter-spacing: 0.02em; | |||
| ` | |||
| `; | |||
| export const ReviewDetailsValue = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-style: normal; | |||
| font-weight: 600; | |||
| ` | |||
| `; | |||
| export const ProfileName = styled(Typography)` | |||
| font-weight: 600; | |||
| font-size: 16px; | |||
| font-family: "Open Sans"; | |||
| ` | |||
| export const ReviewContainer = styled(Box)` | |||
| ` | |||
| `; | |||
| export const ReviewContainer = styled(Box)``; | |||
| @@ -74,7 +74,8 @@ export default { | |||
| average: "srednja", | |||
| good: "dobra", | |||
| strong: "jaka", | |||
| strongPassword: "Lozinka mora imati barem jedan veliki karakter, jedan mali karakter i jedan znak!" | |||
| strongPassword: | |||
| "Lozinka mora imati barem jedan veliki karakter, jedan mali karakter i jedan znak!", | |||
| }, | |||
| register: { | |||
| title: "Registruj se", | |||
| @@ -164,6 +165,7 @@ export default { | |||
| review: "Pregled", | |||
| changeOffer: "Izmena Objave", | |||
| newOffer: "Nova Objava", | |||
| product: "Proizvod", | |||
| }, | |||
| apiErrors: { | |||
| somethingWentWrong: "Greska sa serverom!", | |||
| @@ -249,9 +251,10 @@ export default { | |||
| numberOfViews: " ukupnih pregleda", | |||
| successComunication: " korektna komunikacija", | |||
| back: "Nazad na objave", | |||
| companyProfile: "Profil kompanije", | |||
| noOffers: { | |||
| mainText: "Objave nisu pronađene", | |||
| altText: "Nažalost nemate ni jednu objavu" | |||
| } | |||
| altText: "Nažalost nemate ni jednu objavu", | |||
| }, | |||
| }, | |||
| }; | |||
| @@ -1,24 +1,22 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| ContentRightCardContainer, | |||
| Content, | |||
| RightCard, | |||
| ItemDetailsLayoutContainer, | |||
| } from "./ItemDetailsLayout.styled"; | |||
| import { Grid } from "@mui/material"; | |||
| const ItemDetailsLayout = (props) => { | |||
| return ( | |||
| <ItemDetailsLayoutContainer> | |||
| <ItemDetailsLayoutContainer singleOffer={props.singleOffer}> | |||
| {props.children} | |||
| <Grid container maxHeight="xl" spacing={2}> | |||
| <Content item xs={12} lg={9} xl={9.6} md={12}> | |||
| {props.content} | |||
| </Content> | |||
| <RightCard item xs={12} lg={3} xl={2.4} md={12}> | |||
| <ContentRightCardContainer> | |||
| <Content item>{props.content}</Content> | |||
| <RightCard item singleOffer={props.singleOffer}> | |||
| {props.rightCard} | |||
| </RightCard> | |||
| </Grid> | |||
| </ContentRightCardContainer> | |||
| </ItemDetailsLayoutContainer> | |||
| ); | |||
| }; | |||
| @@ -28,6 +26,7 @@ ItemDetailsLayout.propTypes = { | |||
| leftCard: PropTypes.node, | |||
| content: PropTypes.node, | |||
| rightCard: PropTypes.node, | |||
| singleOffer: PropTypes.bool, | |||
| }; | |||
| export default ItemDetailsLayout; | |||
| @@ -1,15 +1,15 @@ | |||
| import { Container, Grid } from "@mui/material"; | |||
| import { Container, Grid, Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| export const ItemDetailsLayoutContainer = styled(Container)` | |||
| padding-left: 60px; | |||
| padding-right: 0; | |||
| padding-left: 36px; | |||
| padding-right: ${(props) => (props.singleOffer ? "76px" : 0)}; | |||
| margin: 0; | |||
| width: 100%; | |||
| max-width: none; | |||
| display: flex; | |||
| /* display: flex; */ | |||
| position: relative; | |||
| flex: 1; | |||
| /* flex: 1; */ | |||
| height: 100%; | |||
| @media (max-width: 1200px) { | |||
| padding-right: 60px; | |||
| @@ -20,10 +20,27 @@ export const ItemDetailsLayoutContainer = styled(Container)` | |||
| } | |||
| `; | |||
| export const ContentRightCardContainer = styled(Box)` | |||
| display: flex; | |||
| @media screen and (max-width: 600px) { | |||
| flex-direction: column; | |||
| } | |||
| `; | |||
| export const RightCard = styled(Grid)` | |||
| margin-top: 34px; | |||
| border-top-right-radius: 4px; | |||
| width: 100%; | |||
| margin-top: 0; | |||
| margin-left: 0; | |||
| padding-left: 0; | |||
| @media screen and (min-width: 600px) { | |||
| margin-top: 34px; | |||
| margin-left: 36px; | |||
| padding-left: ${(props) => (props.singleOffer ? "36px" : 0)}; | |||
| border-top-right-radius: 4px; | |||
| ${(props) => props.singleOffer && `width: 100%`} | |||
| } | |||
| `; | |||
| export const Content = styled(Grid)` | |||
| width: 100%; | |||
| `; | |||
| @@ -12,7 +12,9 @@ export const ItemDetailsPageContainer = styled(Container)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| background-color: ${selectedTheme.offerBackgroundColor}; | |||
| @media screen and (max-width: 600px) { | |||
| margin-top: 55px; | |||
| } | |||
| `; | |||
| export const GridStyled = styled(Grid)` | |||
| `; | |||
| export const GridStyled = styled(Grid)``; | |||
| @@ -7,6 +7,7 @@ import ItemDetailsLayout from "../../layouts/ItemDetailsLayout/ItemDetailsLayout | |||
| 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"; | |||
| const ItemDetailsPage = (props) => { | |||
| const dispatch = useDispatch(); | |||
| @@ -32,8 +33,13 @@ const ItemDetailsPage = (props) => { | |||
| return ( | |||
| <ItemDetailsPageContainer> | |||
| <ItemDetailsLayout | |||
| content={<ItemDetails />} | |||
| rightCard={<UserReviews />} | |||
| singleOffer | |||
| content={<ItemDetails singleOffer />} | |||
| rightCard={ | |||
| <> | |||
| <ProfileMini /> <UserReviews /> | |||
| </> | |||
| } | |||
| /> | |||
| </ItemDetailsPageContainer> | |||
| ); | |||
| @@ -1,13 +1,13 @@ | |||
| import axios from 'axios'; | |||
| import axios from "axios"; | |||
| const JSON_SERVER_ENDPOINT = 'http://localhost:4000'; | |||
| const JSON_SERVER_ENDPOINT = "http://localhost:4000"; | |||
| const request = axios.create({ | |||
| baseURL: JSON_SERVER_ENDPOINT, | |||
| headers: { | |||
| 'Content-Type': 'application/json', | |||
| }, | |||
| baseURL: JSON_SERVER_ENDPOINT, | |||
| headers: { | |||
| "Content-Type": "application/json", | |||
| }, | |||
| }); | |||
| export const getRequest = (url, params = null, options = null) => | |||
| request.get(url, { params, ...options }); | |||
| request.get(url, { params, ...options }); | |||
| @@ -43,7 +43,7 @@ export default ({ dispatch }) => | |||
| token: refresh, | |||
| }); | |||
| const newToken = axiosResponse.data.token; | |||
| response.headers.Authorization = `Bearer ${newToken}` | |||
| response.headers.Authorization = `Bearer ${newToken}`; | |||
| dispatch(refreshUserToken(newToken)); | |||
| } | |||
| @@ -11,7 +11,7 @@ export default Yup.object().shape({ | |||
| ), | |||
| firmWebsite: Yup.string(), | |||
| firmApplink: Yup.string(), | |||
| firmPhone: Yup.string() | |||
| firmPhone: Yup.number() | |||
| .required(i18n.t("editProfile.labelPhoneRequired")) | |||
| .min(6, i18n.t("editProfile.labelPhoneValid")) | |||
| .max(14, i18n.t("editProfile.labelPhoneValid")), | |||