Просмотр исходного кода

Initial commit

feature/code-cleanup-joca
jovan.cirkovic 3 лет назад
Родитель
Сommit
7ae52e4c26
57 измененных файлов: 1682 добавлений и 112 удалений
  1. 3
    0
      src/AppRoutes.js
  2. 9
    0
      src/assets/images/svg/dummyImages/DummyAuthorImage1.svg
  3. 3
    3
      src/assets/images/svg/eye-striked.svg
  4. 4
    0
      src/assets/images/svg/mailColor.svg
  5. 4
    0
      src/assets/images/svg/pib.svg
  6. 17
    0
      src/components/Buttons/ArrowButton/ArrowButton.js
  7. 53
    0
      src/components/Buttons/ArrowButton/ArrowButton.styled.js
  8. 2
    0
      src/components/Buttons/IconButton/IconButton.styled.js
  9. 16
    6
      src/components/Cards/CreateOfferCard/CreateOffer.js
  10. 53
    8
      src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.js
  11. 4
    6
      src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.styled.js
  12. 7
    3
      src/components/Cards/CreateOfferCard/SecondPart/SecondPartCreateOffer.js
  13. 1
    2
      src/components/Cards/CreateOfferCard/SecondPart/SecondPartCreateOffer.styled.js
  14. 121
    0
      src/components/Cards/CreateOfferCard/ThirdPart/ThirdPartCreateOffer.js
  15. 86
    0
      src/components/Cards/CreateOfferCard/ThirdPart/ThirdPartCreateOffer.styled.js
  16. 9
    5
      src/components/Cards/FilterCard/FilterCard.js
  17. 140
    0
      src/components/Cards/ItemDetailsCard/ItemDetailsCard.js
  18. 165
    0
      src/components/Cards/ItemDetailsCard/ItemDetailsCard.styled.js
  19. 36
    0
      src/components/Cards/ItemDetailsCard/MockupOfferDetails.js
  20. 7
    0
      src/components/Cards/OfferCard/OfferCard.js
  21. 19
    17
      src/components/ImagePicker/ImagePicker.styled.js
  22. 44
    0
      src/components/ItemDetails/Header/Header.js
  23. 22
    0
      src/components/ItemDetails/Header/Header.styled.js
  24. 19
    0
      src/components/ItemDetails/ItemDetails.js
  25. 6
    0
      src/components/ItemDetails/ItemDetails.styled.js
  26. 90
    0
      src/components/ItemDetails/ItemDetailsHeaderCard/ItemDetailsHeaderCard.js
  27. 186
    0
      src/components/ItemDetails/ItemDetailsHeaderCard/ItemDetailsHeaderCard.styled.js
  28. 59
    0
      src/components/ItemDetails/MockupdataDetails.js
  29. 12
    9
      src/components/Scroller/HorizontalScroller.js
  30. 3
    2
      src/components/Scroller/HorizontalScroller.styled.js
  31. 24
    0
      src/components/UserReviewsCard/Mockupdata.js
  32. 103
    0
      src/components/UserReviewsCard/UserReviewsCard.js
  33. 31
    0
      src/components/UserReviewsCard/UserReviewsCard.styled.js
  34. 5
    4
      src/constants/pages.js
  35. 1
    0
      src/i18n/resources/rs.js
  36. 3
    0
      src/initialValues/forgotPasswordInitialValues.js
  37. 4
    0
      src/initialValues/loginInitialValues.js
  38. 4
    0
      src/initialValues/registerInitialValues/firstPartInitialValues.js
  39. 4
    0
      src/initialValues/registerInitialValues/secondPartInitialValues.js
  40. 5
    0
      src/initialValues/registerInitialValues/thirdPartInitialValues.js
  41. 4
    0
      src/initialValues/resetPasswordInitialValues.js
  42. 30
    0
      src/layouts/ItemDetailsLayout/ItemDetailsLayout.js
  43. 20
    0
      src/layouts/ItemDetailsLayout/ItemDetailsLayout.styled.js
  44. 17
    0
      src/pages/ItemDetailsPage/ItemDetailsPage.styled.js
  45. 84
    0
      src/pages/ItemDetailsPage/ItemDetailsPageMUI.js
  46. 4
    10
      src/pages/LoginPage/LoginPage.js
  47. 7
    7
      src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.js
  48. 4
    4
      src/request/index.js
  49. 4
    4
      src/store/middleware/accessTokensMiddleware.js
  50. 18
    18
      src/themes/primaryTheme/primaryThemeColors.js
  51. 8
    0
      src/validations/forgotPasswordValidation.js
  52. 9
    0
      src/validations/loginValidation.js
  53. 10
    0
      src/validations/registerValidations/firstPartValidation.js
  54. 10
    0
      src/validations/registerValidations/secondPartValidation.js
  55. 10
    0
      src/validations/registerValidations/thirdPartValidation.js
  56. 6
    0
      src/validations/resetPasswordValidation.js
  57. 53
    4
      yarn.lock

+ 3
- 0
src/AppRoutes.js Просмотреть файл

@@ -13,6 +13,7 @@ import {
REGISTER_SUCCESSFUL_PAGE,
RESET_PASSWORD_PAGE,
CREATE_OFFER_PAGE,
ITEM_DETAILS_PAGE
} from './constants/pages';
import LoginPage from './pages/LoginPage/LoginPage';
import HomePage from './pages/HomePage/HomePageMUI';
@@ -25,6 +26,7 @@ import Register from './pages/RegisterPages/Register/Register';
import RegisterSuccessful from './pages/RegisterPages/RegisterSuccessful.js/RegisterSuccessful';
import ResetPasswordPage from './pages/ResetPasswordPage/ResetPasswordPage';
import CreateOffer from './pages/CreateOffer/CreateOffer';
import ItemDetailsPage from './pages/ItemDetailsPage/ItemDetailsPageMUI';


const AppRoutes = () => {
@@ -40,6 +42,7 @@ const AppRoutes = () => {
<Route path={FORGOT_PASSWORD_PAGE} component={ForgotPasswordPage} />
<Route path={RESET_PASSWORD_PAGE} component={ResetPasswordPage}/>
<Route path={CREATE_OFFER_PAGE} component={CreateOffer}/>
<Route path={ITEM_DETAILS_PAGE} component={ItemDetailsPage} />
<PrivateRoute
exact

+ 9
- 0
src/assets/images/svg/dummyImages/DummyAuthorImage1.svg
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 3
- 3
src/assets/images/svg/eye-striked.svg Просмотреть файл

@@ -1,4 +1,4 @@
<svg width="22" height="16" viewBox="0 0 22 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.9999 7.99994C13.9999 8.79557 13.6838 9.55862 13.1212 10.1212C12.5586 10.6838 11.7956 10.9999 10.9999 10.9999C10.2043 10.9999 9.44126 10.6838 8.87866 10.1212C8.31606 9.55862 8 8.79557 8 7.99994C8 7.20431 8.31606 6.44126 8.87866 5.87866C9.44126 5.31606 10.2043 5 10.9999 5C11.7956 5 12.5586 5.31606 13.1212 5.87866C13.6838 6.44126 13.9999 7.20431 13.9999 7.99994V7.99994Z" stroke="#5A3984" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.45898 7.99986C2.73296 3.94294 6.52388 1 11.0008 1C15.4787 1 19.2686 3.94294 20.5426 7.99986C19.2686 12.0568 15.4787 14.9997 11.0008 14.9997C6.52388 14.9997 2.73296 12.0568 1.45898 7.99986Z" stroke="#5A3984" stroke-linecap="round" stroke-linejoin="round"/>
<svg width="22" height="16" viewBox="0 0 22 16" fill="none" stroke="black" xmlns="http://www.w3.org/2000/svg">
<path d="M13.9999 7.99994C13.9999 8.79557 13.6838 9.55862 13.1212 10.1212C12.5586 10.6838 11.7956 10.9999 10.9999 10.9999C10.2043 10.9999 9.44126 10.6838 8.87866 10.1212C8.31606 9.55862 8 8.79557 8 7.99994C8 7.20431 8.31606 6.44126 8.87866 5.87866C9.44126 5.31606 10.2043 5 10.9999 5C11.7956 5 12.5586 5.31606 13.1212 5.87866C13.6838 6.44126 13.9999 7.20431 13.9999 7.99994V7.99994Z" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.45898 7.99986C2.73296 3.94294 6.52388 1 11.0008 1C15.4787 1 19.2686 3.94294 20.5426 7.99986C19.2686 12.0568 15.4787 14.9997 11.0008 14.9997C6.52388 14.9997 2.73296 12.0568 1.45898 7.99986Z" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 4
- 0
src/assets/images/svg/mailColor.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="M3.33366 3.33334H16.667C17.5837 3.33334 18.3337 4.08334 18.3337 5.00001V15C18.3337 15.9167 17.5837 16.6667 16.667 16.6667H3.33366C2.41699 16.6667 1.66699 15.9167 1.66699 15V5.00001C1.66699 4.08334 2.41699 3.33334 3.33366 3.33334Z" stroke="#FEB005" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M18.3337 5L10.0003 10.8333L1.66699 5" stroke="#FEB005" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 4
- 0
src/assets/images/svg/pib.svg Просмотреть файл

@@ -0,0 +1,4 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.66634 2.75H18.333C18.8192 2.75 19.2856 2.94315 19.6294 3.28697C19.9732 3.63079 20.1663 4.0971 20.1663 4.58333V10.0833C20.1663 12.5145 19.2006 14.8461 17.4815 16.5651C15.7624 18.2842 13.4308 19.25 10.9997 19.25C9.79589 19.25 8.60389 19.0129 7.49174 18.5522C6.37959 18.0916 5.36907 17.4163 4.51786 16.5651C2.79878 14.8461 1.83301 12.5145 1.83301 10.0833V4.58333C1.83301 4.0971 2.02616 3.63079 2.36998 3.28697C2.7138 2.94315 3.18011 2.75 3.66634 2.75V2.75Z" stroke="#C4C4C4" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.33301 9.16666L10.9997 12.8333L14.6663 9.16666" stroke="#C4C4C4" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 17
- 0
src/components/Buttons/ArrowButton/ArrowButton.js Просмотреть файл

@@ -0,0 +1,17 @@
import React from 'react'
import { ArrowContainer, ArrowIcon } from "./ArrowButton.styled"
import PropTypes from "prop-types";

export const ArrowButton = (props) => {

return <ArrowContainer onClick={props.onClick} className={props.className} disabled={props.disabled}>
<ArrowIcon side={props.side} disabled={props.disabled}/>
</ArrowContainer>
}

ArrowButton.propTypes = {
onClick: PropTypes.func,
className: PropTypes.string,
side:PropTypes.string,
disabled:PropTypes.bool,
}

+ 53
- 0
src/components/Buttons/ArrowButton/ArrowButton.styled.js Просмотреть файл

@@ -0,0 +1,53 @@
import IconButton from "../../IconButton/IconButton"
import {ReactComponent as DownArrow} from "../../../assets/images/svg/arrow-down.svg"
import styled from "styled-components";
import selectedTheme from "../../../themes";



export const ArrowIcon = styled(DownArrow)`
${props => props.side === 'left' && `
transform: rotate(180deg);
`}
width: 18px;
height: 18px;
& path {
${props => props.disabled && `
stroke: ${selectedTheme.iconStrokeDisabledColor}
`}
}
`
export const ArrowContainer = styled(IconButton)`
border: 1px solid ${selectedTheme.primaryPurple};
border-radius: 100%;
min-width: 40px;
width: 40px;
height: 40px;
display: flex;
box-sizing: border-box;
cursor: pointer;
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};
&:hover {
background-color: inherit;
& svg path {
stroke: ${selectedTheme.iconStrokeDisabledColor};
}
}
& svg path {
stroke: ${selectedTheme.iconStrokeDisabledColor};
transition: 0.2s all ease;
}
`}
`

+ 2
- 0
src/components/Buttons/IconButton/IconButton.styled.js Просмотреть файл

@@ -1,5 +1,6 @@
import { Box, IconButton } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";

export const IconButtonContainer = styled(Box)`
`
@@ -13,4 +14,5 @@ export const IconButtonStyled = styled(IconButton)`
stroke: ${props.iconcolor};
}
`}
border: ${props => props.border ? "1px solid " + selectedTheme.backgroundSponsoredColor : "none"}
`

+ 16
- 6
src/components/Cards/CreateOfferCard/CreateOffer.js Просмотреть файл

@@ -30,6 +30,7 @@ import StepProgress from "../../StepProgress/StepProgress";
import { Label } from "../../CheckBox/Label";
import FirstPartCreateOffer from "./FirstPart/FirstPartCreateOffer";
import SecondPartCreateOffer from "./SecondPart/SecondPartCreateOffer";
import ThirdPartCreateOffer from "./ThirdPart/ThirdPartCreateOffer";

const CreateOffer = ({ history }) => {
const dispatch = useDispatch();
@@ -76,20 +77,29 @@ const CreateOffer = ({ history }) => {
};

const handleNext = (values) => {
setInformations({...values});
setCurrentStep(prevState => prevState+1)
}
if (currentStep === 2) {
setInformations({ ...informations, images: [...values] });
} else {
setInformations({ ...informations, ...values });
}
setCurrentStep((prevState) => prevState + 1);
};

return (
<CreateOfferContainer>
<CreateOfferTitle component="h1" variant="h5">
Nova Objava
{currentStep === 3 ? "Pregled" : "Nova Objava"}
</CreateOfferTitle>

<StepProgress current={currentStep} numberOfSteps={3} />
{currentStep === 1 && <FirstPartCreateOffer handleNext={handleNext}/>}
{currentStep === 1 && <FirstPartCreateOffer handleNext={handleNext} />}
{currentStep === 2 && <SecondPartCreateOffer handleNext={handleNext} />}
{currentStep === 3 && (
<ThirdPartCreateOffer
handleNext={handleNext}
informations={informations}
/>
)}
</CreateOfferContainer>
);
};

+ 53
- 8
src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.js Просмотреть файл

@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import { useFormik } from "formik";
import {
@@ -15,8 +15,18 @@ import selectedTheme from "../../../../themes";
import { useTranslation } from "react-i18next";
import Option from "../../../Select/Option/Option";
import { SelectField } from "../CreateOffer.styled";
import { useSelector } from "react-redux";

const FirstPartCreateOffer = (props) => {
const [subcat, setSubcat] = useState([]);
const locations = useSelector((state) => state.locations.locations);
const categories = useSelector((state) => state.categories.categories);

const handleSubcategories = (category) => {
const filtered = categories.filter((cat) => cat.name === category);
setSubcat(filtered);
};

const { t } = useTranslation();
const handleSubmit = (values) => {
console.log(values);
@@ -26,15 +36,18 @@ const FirstPartCreateOffer = (props) => {
initialValues: {
nameOfProduct: "",
description: "",
category: "",
},
validationSchema: Yup.object().shape({
nameOfProduct: Yup.string().required(t("login.nameOfProductRequired")),
description: Yup.string().required(t("login.descriptionRequired")).min(8),
category: Yup.string().oneOf(["Automobili", "Audio", "Racunari"]),
}),
onSubmit: handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});

return (
<CreateOfferFormContainer component="form" onSubmit={formik.handleSubmit}>
{/* <Backdrop position="absolute" isLoading={isLoading} /> */}
@@ -71,26 +84,58 @@ const FirstPartCreateOffer = (props) => {

<FieldLabel leftText={"LOKACIJA"} />
<SelectField defaultValue={1}>
<Option value={1}>Opcija 1</Option>
{locations.map((location, i) => {
return (
<Option key={location._if} value={i + 1}>
{location.city}
</Option>
);
})}
{/* <Option value={1}>Opcija 1</Option>
<Option value={2}>Opcija 2</Option>
<Option value={3}>Opcija 3</Option>
<Option value={4}>Opcija 4</Option>
<Option value={4}>Opcija 4</Option> */}
</SelectField>

<FieldLabel leftText={"KATEGORIJA"} />
<SelectField defaultValue={1}>
<Option value={1}>Opcija 1</Option>
<SelectField
defaultValue={1}
onChange={(value) => {
formik.setFieldValue("category", value.target.value.name);
console.log(value.target);
}}
>
{categories.map((cat, i) => {
return (
<Option
key={i}
value={cat}
onClick={() => handleSubcategories(cat.name)}
>
{cat.name}
</Option>
);
})}
{/* <Option value={1}>Opcija 1</Option>
<Option value={2}>Opcija 2</Option>
<Option value={3}>Opcija 3</Option>
<Option value={4}>Opcija 4</Option>
<Option value={4}>Opcija 4</Option> */}
</SelectField>

<FieldLabel leftText={"PODKATEGORIJA"} />
<SelectField defaultValue={1}>
<Option value={1}>Opcija 1</Option>
{subcat?.length > 0 &&
subcat[0].subcategories.map((sub, i) => {
return (
<Option key={i} value={i + 1}>
{sub.name}
</Option>
);
})}
{/* <Option value={1}>Opcija 1</Option>
<Option value={2}>Opcija 2</Option>
<Option value={3}>Opcija 3</Option>
<Option value={4}>Opcija 4</Option>
<Option value={4}>Opcija 4</Option> */}
</SelectField>

<NextButton

+ 4
- 6
src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.styled.js Просмотреть файл

@@ -50,13 +50,11 @@ export const FieldLabel = styled(Label)`
cursor: auto;
letter-spacing: 0.2px;
}
`
`;
export const DescriptionField = styled(TextField)`
margin-bottom: 4px;
`
export const TitleField = styled(TextField)`

`
`;
export const TitleField = styled(TextField)``;
export const NextButton = styled(PrimaryButton)`
margin-top: 16px;
`
`;

+ 7
- 3
src/components/Cards/CreateOfferCard/SecondPart/SecondPartCreateOffer.js Просмотреть файл

@@ -14,7 +14,7 @@ import { NextButton } from "../FirstPart/FirstPartCreateOffer.styled";
import selectedTheme from "../../../../themes";
import { conditionSelectEnum } from "../../../../enums/conditionEnum";

const SecondPartCreateOffer = () => {
const SecondPartCreateOffer = (props) => {
const [images, setImages] = useState([null, null, null]); // 3 images
const setImage = (index, image) => {
console.log(images);
@@ -25,8 +25,12 @@ const SecondPartCreateOffer = () => {
});
};

const handleSubmit = () => {
props.handleNext(images);
};

return (
<CreateOfferFormContainer>
<CreateOfferFormContainer component="form" onSubmit={handleSubmit}>
<Scroller>
{images.map((item, index) => (
<ImagePicker
@@ -70,7 +74,7 @@ const SecondPartCreateOffer = () => {

SecondPartCreateOffer.propTypes = {
children: PropTypes.node,
handleOffer: PropTypes.func,
handleNext: PropTypes.func,
};

export default SecondPartCreateOffer;

+ 1
- 2
src/components/Cards/CreateOfferCard/SecondPart/SecondPartCreateOffer.styled.js Просмотреть файл

@@ -46,9 +46,8 @@ export const Trash = styled(TrashIcon)`
cursor: pointer;
margin: auto;
width: 22px;
height: 22px;
height: 22px;
& path {
stroke: white;
}
`;

+ 121
- 0
src/components/Cards/CreateOfferCard/ThirdPart/ThirdPartCreateOffer.js Просмотреть файл

@@ -0,0 +1,121 @@
import React from "react";
import PropTypes from "prop-types";
import { NextButton } from "../FirstPart/FirstPartCreateOffer.styled";
import selectedTheme from "../../../../themes";
import {
CreateOfferFormContainer,
HeaderInfo,
HeaderItem,
HeaderItemIcon,
HeaderItemText,
HeaderOfferContainer,
HeaderPostDate,
OfferDetails,
OfferDetailsTitle,
OfferImage,
OfferDescriptionContainer,
OfferDescriptionTitle,
OfferDescription,
ButtonContainer,
} from "./ThirdPartCreateOffer.styled";
import { ReactComponent as Category } from "../../../../assets/images/svg/category.svg";
import { ReactComponent as Subcategory } from "../../../../assets/images/svg/subcategory.svg";
import { ReactComponent as Quantity } from "../../../../assets/images/svg/quantity.svg";
import { ReactComponent as Eye } from "../../../../assets/images/svg/eye-striked.svg";
import HorizontalScroller from "../../../Scroller/HorizontalScroller";

const ThirdPartCreateOffer = (props) => {
console.log(props.informations);
let date = new Date();
return (
<CreateOfferFormContainer>
<HeaderOfferContainer>
<HeaderInfo>
<HeaderItem>
<HeaderItemIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Category width={"14px"} />
</HeaderItemIcon>
<HeaderItemText>Automobili</HeaderItemText>
</HeaderItem>
<HeaderItem>
<HeaderItemIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Subcategory width={"14px"} />
</HeaderItemIcon>
<HeaderItemText>Novi</HeaderItemText>
</HeaderItem>
<HeaderItem>
<HeaderItemIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Quantity width={"14px"} />
</HeaderItemIcon>
<HeaderItemText>Novo</HeaderItemText>
</HeaderItem>
<HeaderItem>
<HeaderItemIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Eye width={"14px"} />
</HeaderItemIcon>
<HeaderItemText>45</HeaderItemText>
</HeaderItem>
</HeaderInfo>
<HeaderPostDate>
Objavljeno:
{" " +
`${date.getDate()}.${date.getMonth() + 1}.${date.getFullYear()}.`}
</HeaderPostDate>
</HeaderOfferContainer>
<OfferDetails>
<OfferDetailsTitle>
{props.informations.nameOfProduct}
</OfferDetailsTitle>
<HorizontalScroller>
<OfferImage src={props.informations[0] && props.informations[0]} />
<OfferImage src={props.informations[1] && props.informations[1]} />
<OfferImage src={props.informations[2] && props.informations[2]} />
</HorizontalScroller>
<OfferDescriptionContainer>
<OfferDescriptionTitle>Opis:</OfferDescriptionTitle>
<OfferDescription>{props.informations.description}</OfferDescription>
</OfferDescriptionContainer>
</OfferDetails>
<ButtonContainer>
<NextButton
type="submit"
variant="contained"
height="48px"
width="350px"
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
// disabled={
// formik.values.username.length === 0 ||
// formik.values.password.length === 0
// }
>
OBJAVI
</NextButton>
</ButtonContainer>
</CreateOfferFormContainer>
);
};

ThirdPartCreateOffer.propTypes = {
children: PropTypes.any,
handleNext: PropTypes.func,
informations: PropTypes.object,
};

export default ThirdPartCreateOffer;

+ 86
- 0
src/components/Cards/CreateOfferCard/ThirdPart/ThirdPartCreateOffer.styled.js Просмотреть файл

@@ -0,0 +1,86 @@
import { Box, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";

export const CreateOfferFormContainer = styled(Box)`
width: 650px;
padding-top: 20px;
margin-top: 20px;
`;

export const HeaderOfferContainer = styled(Box)`
display: flex;
justify-content: space-between;
`;

export const HeaderInfo = styled(Box)`
display: flex;
gap: 18px;
`;

export const HeaderItem = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
`;

export const HeaderItemIcon = styled(Box)`
display: flex;
align-items: center;
`;

export const HeaderItemText = styled(Typography)`
font-family: "Open Sans";
font-size: 14px;
`;

export const HeaderPostDate = styled(Typography)`
font-family: "Open Sans";
font-size: 12px;
`;

export const OfferDetails = styled(Box)`
display: flex;
flex-direction: column;
margin-top: 20px;
`;

export const OfferDetailsTitle = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryPurple};
font-weight: 700;
font-size: 24px;
padding: 0 60px;
margin-bottom: 10px;
`;

export const OfferImage = styled.img`
width: 144px;
height: 144px;
margin-right: 10px;
object-fit: cover;
border-radius: 5px;
`;

export const OfferDescriptionContainer = styled(Box)`
display: flex;
flex-direction: column;
padding: 0 60px;
margin-top: 20px;
`;

export const OfferDescriptionTitle = styled(Box)`
font-family: "Open Sans";
font-size: 12px;
`;

export const OfferDescription = styled(Box)`
font-family: "Open Sans";
font-size: 16px;
`;

export const ButtonContainer = styled(Box)`
display: flex;
justify-content: center;
`;

+ 9
- 5
src/components/Cards/FilterCard/FilterCard.js Просмотреть файл

@@ -32,16 +32,16 @@ const FilterCard = () => {
} else {
setIsDisabled(false);
}
}, [filters.selectedCategory])
}, [filters.selectedCategory]);

const handleSelectCategory = (category) => {
filters.setSelectedCategory(category);
filters.setSelectedSubcategory();
}
};

const handleOpen = () => {
setIsOpened(prevState => !prevState);
}
setIsOpened((prevState) => !prevState);
};

const handleFilters = () => {
filters.applyFilters();
@@ -105,7 +105,11 @@ const FilterCard = () => {
<FilterCheckboxDropdown
searchPlaceholder={t("filters.location.placeholder")}
data={[...filters.locations]}
filters={[...filters.selectedLocations]}
filters={
filters?.selectedLocations?.length > 0
? [filters.selectedLocations]
: []
}
icon={<Location />}
title={t("filters.location.title")}
setItemsSelected={filters.setSelectedLocations}

+ 140
- 0
src/components/Cards/ItemDetailsCard/ItemDetailsCard.js Просмотреть файл

@@ -0,0 +1,140 @@
import React from "react";
import PropTypes from "prop-types";
import {
CheckButton,
ItemDetailsCardContainer,
OfferInfo,
Info,
PostDate,
InfoIcon,
InfoText,
InfoGroup,
OfferTitle,
OfferDescriptionText,
OfferDescriptionTitle,
Details,
OfferDetails,
} from "./ItemDetailsCard.styled";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
import { ReactComponent as Subcategory } from "../../../assets/images/svg/subcategory.svg";
import { ReactComponent as Quantity } from "../../../assets/images/svg/quantity.svg";
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import selectedTheme from "../../../themes";
import { Offer as offer } from "./MockupOfferDetails";
import HorizontalScroller from "../../Scroller/HorizontalScroller";
import { ReactComponent as DummyImage1 } from "../../../assets/images/svg/dummyImages/offer-1.svg";

const ItemDetailsCard = (props) => {
return (
<ItemDetailsCardContainer
sponsored={props.sponsored.toString()}
halfwidth={props.halfwidth ? 1 : 0}
>
<OfferInfo>
<Info>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Category width={"14px"} />
</InfoIcon>
<InfoText>{offer.category}</InfoText>
</InfoGroup>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Subcategory width={"14px"} />
</InfoIcon>
<InfoText>{offer.subcategory}</InfoText>
</InfoGroup>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Quantity width={"22px"} height={"16px"} />
</InfoIcon>
<InfoText>{offer.status}</InfoText>
</InfoGroup>
<InfoGroup>
<InfoIcon color={"black"} component="span" size="12px">
<Eye width={"18px"} height={"20px"} />
</InfoIcon>
<InfoText>{offer.numberOfViews}</InfoText>
</InfoGroup>
</Info>
<PostDate>Objavljeno: 04.04.2022</PostDate>
</OfferInfo>
<Details>
<OfferTitle>{offer.title}</OfferTitle>
<HorizontalScroller>
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
<DummyImage1 />
</HorizontalScroller>
<OfferDetails>
<OfferDescriptionTitle>Opis:</OfferDescriptionTitle>
<OfferDescriptionText>{offer.description}</OfferDescriptionText>
</OfferDetails>
</Details>
{!props.halfwidth ? (
<React.Fragment>
<CheckButton
variant={props.sponsored ? "contained" : "outlined"}
buttoncolor={selectedTheme.primaryPurple}
textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple}
style={{ fontWeight: "600" }}
>
Trampi
</CheckButton>
</React.Fragment>
) : (
<></>
)}

{/* {props.image}
{props.title}
{props.description}
{props.category}
{props.author}
{props.location}
{props.quantity}
{props.package}
{props.numberOfViews} */}
</ItemDetailsCardContainer>
);
};

ItemDetailsCard.propTypes = {
children: PropTypes.node,
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
category: PropTypes.string,
author: PropTypes.string,
location: PropTypes.string,
image: PropTypes.node,
quantity: PropTypes.number,
package: PropTypes.string,
numberOfViews: PropTypes.number,
halfwidth: PropTypes.bool,
sponsored: PropTypes.bool,
};
ItemDetailsCard.defaultProps = {
halfwidth: false,
sponsored: false,
};

export default ItemDetailsCard;

+ 165
- 0
src/components/Cards/ItemDetailsCard/ItemDetailsCard.styled.js Просмотреть файл

@@ -0,0 +1,165 @@
import { Box, Container, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";
//import { IconButton } from "../../Buttons/IconButton/IconButton";
import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import { Icon } from "../../Icon/Icon";

export const ItemDetailsCardContainer = styled(Container)`
display: flex;
flex-direction: column;
width: ${(props) => (!props.halfwidth ? "100%" : "49%")};
box-sizing: border-box;
margin: 10px 0;
border: 1px solid ${selectedTheme.borderNormal};
background-color: ${(props) =>
props.sponsored === "true"
? selectedTheme.backgroundSponsoredColor
: "white"};
border-radius: 4px;
padding: 18px;
max-width: 2000px;
position: relative;
`;
export const OfferImage = styled(Box)``;
export const OfferInfo = styled(Box)`
display: flex;
flex: 2;
flex-direction: row;
justify-content: space-between;
margin: 18px 0;
`;
export const InfoGroup = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
`;
export const PostDate = styled(Typography)`
font-family: "Open Sans";
font-size: 12px;
color: ${selectedTheme.primaryText};
`;
export const Info = styled(Box)`
display: flex;
gap: 18px;
`;
export const InfoIcon = styled(Box)`
display: flex;
align-items: center;
`;
export const InfoText = styled(Typography)`
font-family: "Open Sans";
`;
export const OfferTitle = styled(Typography)`
font-family: "Open Sans";
flex: 1;
color: ${selectedTheme.primaryPurple};
font-weight: 700;
font-size: 24px;
padding: 0 72px;
`;
export const OfferAuthor = styled(Box)`
display: flex;
flex: 1;
flex-direction: column;
`;
export const OfferAuthorName = styled(Typography)`
font-family: "Open Sans";
line-height: 22px;
font-size: 16px;
color: ${selectedTheme.primaryDarkText};
`;
export const OfferLocation = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
`;
export const OfferDetails = styled(Box)`
display: flex;
flex-direction: column;
flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")};
justify-content: space-between;
padding: 0 72px;
`;
export const OfferCategory = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 33%;
`;
export const OfferPackage = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 34%;
`;
export const OfferViews = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 34%;
`;
export const OfferDescriptionTitle = styled(Box)`
font-family: "Open Sans";
font-size: 12px;
color: ${selectedTheme.primaryDarkText};
line-height: 16px;
`;
export const OfferDescriptionText = styled(Box)`
font-family: "Open Sans";
font-size: 16px;
color: ${selectedTheme.primaryDarkText};
line-height: 22px;
max-width: calc(100% - 230px);
max-height: 120px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
`;
export const OfferDescription = styled(Box)`
flex: 3;
`;
export const Line = styled(Box)`
border-left: 1px solid rgba(0, 0, 0, 0.15);
height: 100px;
width: 0;
margin: auto 0;
`;
export const DetailIcon = styled(Icon)`
& svg {
width: 14px;
position: relative;
top: -1px;
}
`;
export const DetailText = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
position: relative;
top: -2px;
left: 3px;
`;
export const CheckButton = styled(PrimaryButton)`
width: 180px;
height: 48px;
position: absolute;
bottom: 9px;
right: 9px;
&:hover button {
background-color: ${selectedTheme.primaryPurple} !important;
color: white !important;
}
`;
export const Details = styled(Box)`
display: flex;
flex-direction: column;
gap: 12px;
`;

+ 36
- 0
src/components/Cards/ItemDetailsCard/MockupOfferDetails.js Просмотреть файл

@@ -0,0 +1,36 @@
import React from "react"
import {ReactComponent as DummyImage1 } from "../../../assets/images/svg/dummyImages/offer-1.svg"

export const Offer = {
id: 0,
title: "Vino",
category: "Hrana i pice",
subcategory:"Farbe",
status:"novo",
quantity:150,
numberOfViews:45,
description: "Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.",
images: [
{
id:0,
image: <DummyImage1 />
},
{
id:1,
image: <DummyImage1 />
},
{
id:2,
image: <DummyImage1 />
},
{
id:3,
image: <DummyImage1 />
},
{
id:4,
image: <DummyImage1 />
},
],
postDate: "12.04.2022",
}

+ 7
- 0
src/components/Cards/OfferCard/OfferCard.js Просмотреть файл

@@ -24,8 +24,14 @@ import { ReactComponent as Category } from "../../../assets/images/svg/category.
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import { ReactComponent as Message } from "../../../assets/images/svg/mail.svg";
import selectedTheme from "../../../themes";
import { useHistory } from "react-router-dom";

const OfferCard = (props) => {
const id = 434;
const history = useHistory();
const routeToItem = () => {
history.push(`/proizvodi/${id}`)
}
return (
<OfferCardContainer sponsored={props.offer.pinned.toString()} halfwidth={props.halfwidth ? 1 : 0}>
<OfferImage src={props.offer.images[0]}></OfferImage>
@@ -63,6 +69,7 @@ const OfferCard = (props) => {
buttoncolor={selectedTheme.primaryPurple}
textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple}
style={{fontWeight: "600"}}
onClick = {routeToItem}
>
Pogledaj proizvod
</CheckButton>

+ 19
- 17
src/components/ImagePicker/ImagePicker.styled.js Просмотреть файл

@@ -1,7 +1,7 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../themes";
import {ReactComponent as Plus} from "../../assets/images/svg/plus.svg";
import { ReactComponent as Plus } from "../../assets/images/svg/plus.svg";

export const ImagePickerContainer = styled(Box)`
flex: 1;
@@ -41,27 +41,29 @@ export const ImagePickerContainer = styled(Box)`
&:last-of-type {
margin-right: 0;
}
${props => props.hasImage && `
${(props) =>
props.hasImage &&
`
background-image: none;
border: 1px solid ${selectedTheme.primaryPurple};
`}
`;
export const AddIcon = styled(Plus)`
margin: auto;
`
margin: auto;
`;
export const AddFile = styled.input`
display: none;
`
display: none;
`;
export const ImageUploaded = styled.img`
width: 216px;
height: 144px;
object-fit: scale-down;
`
width: 216px;
height: 144px;
object-fit: scale-down;
`;
export const Tooltip = styled(Box)`
background-color: rgba(255, 255, 255, 0.5);
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
`
background-color: rgba(255, 255, 255, 0.5);
width: 100px;
height: 100px;
position: absolute;
left: 0;
top: 0;
`;

+ 44
- 0
src/components/ItemDetails/Header/Header.js Просмотреть файл

@@ -0,0 +1,44 @@
import React from 'react';
import PropTypes from "prop-types";
import { useHistory } from "react-router-dom";
//import { IconButton } from "../../Buttons/IconButton/IconButton";
import { HeaderContainer, HeaderText, ButtonContainer } from './Header.styled';
import { ArrowButton } from '../../Buttons/ArrowButton/ArrowButton';

// const DownArrow = (props) => (
// <IconStyled {...props}>
// <Down />
// </IconStyled>
// );

const Header = () => {

const history = useHistory();

const handleBackButton = () => {
history.push('/home');
};

return (
<HeaderContainer onClick={handleBackButton}>
<ButtonContainer>
<ArrowButton side={"left"}></ArrowButton>
<HeaderText>Nazad na objave</HeaderText>
</ButtonContainer>
</HeaderContainer>
);
};

Header.propTypes = {
children: PropTypes.node,
setIsGrid: PropTypes.func,
isGrid: PropTypes.bool,
filters: PropTypes.array,
category: PropTypes.string,
};
Header.defaultProps = {
isGrid: false,
};

export default Header;

+ 22
- 0
src/components/ItemDetails/Header/Header.styled.js Просмотреть файл

@@ -0,0 +1,22 @@
import { Box, Link, Typography} from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";

export const HeaderContainer = styled(Box)`
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;
`

+ 19
- 0
src/components/ItemDetails/ItemDetails.js Просмотреть файл

@@ -0,0 +1,19 @@
import React from 'react';
import Header from "./Header/Header";
import { ItemDetailsContainer } from './ItemDetails.styled';
import ItemDetailsCard from "../Cards/ItemDetailsCard/ItemDetailsCard";
import ItemDetailsHeaderCard from "./ItemDetailsHeaderCard/ItemDetailsHeaderCard";



const ItemDetails = () => {
return (
<ItemDetailsContainer>
<Header/>
<ItemDetailsHeaderCard />
<ItemDetailsCard/>
</ItemDetailsContainer>
)
}

export default ItemDetails;

+ 6
- 0
src/components/ItemDetails/ItemDetails.styled.js Просмотреть файл

@@ -0,0 +1,6 @@
import { Box } from "@mui/material";
import styled from "styled-components";

export const ItemDetailsContainer = styled(Box)`

`;

+ 90
- 0
src/components/ItemDetails/ItemDetailsHeaderCard/ItemDetailsHeaderCard.js Просмотреть файл

@@ -0,0 +1,90 @@
import React from "react";
import PropTypes from "prop-types";
import {
DetailIcon,
DetailText,
MessageIcon,
OfferDetails,
OfferImage,
OfferTitle,
DetailContainer,
HeaderTop,
HeaderDetails,
BottomDetails,
StatusText
} from "./ItemDetailsHeaderCard.styled";
import { ItemDetailsHeaderContainer } from "./ItemDetailsHeaderCard.styled";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
//import { ReactComponent as Quantity } from "../../../assets/images/svg/quantity.svg";
//import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import { ReactComponent as PIB} from "../../../assets/images/svg/pib.svg";
import { ReactComponent as MessageColor } from "../../../assets/images/svg/mailColor.svg";
import selectedTheme from "../../../themes";
import { Author as author } from "../MockupdataDetails";

const ItemDetailsHeaderCard = (props) => {
return (
<ItemDetailsHeaderContainer sponsored={props.sponsored.toString()} halfwidth={props.halfwidth ? 1 : 0}>
<HeaderTop>
<OfferImage>{author.image}</OfferImage>
<OfferDetails>
<OfferTitle>{author.title}</OfferTitle>
<DetailContainer>
<DetailIcon color={selectedTheme.iconStrokeColor} component="span" size="22px">
<PIB width={"22px"} />
</DetailIcon>
<DetailText>PIB - {author.pib}</DetailText>
</DetailContainer>
<DetailContainer>
<DetailIcon color={selectedTheme.iconStrokeColor} component="span" size="22px">
<Category width={"22px"} />
</DetailIcon>
<DetailText>{author.location}</DetailText>
</DetailContainer>
</OfferDetails>
<MessageIcon>
<MessageColor />
</MessageIcon>
</HeaderTop>
<HeaderDetails>
<BottomDetails>
<StatusText>
<b>{author.numberOfOffers}</b> objava
</StatusText>
<StatusText>
<b>{author.numberOfViews}</b> ukupnih pregleda
</StatusText>
<StatusText>
<b>{author.successSwapsProcent}</b> uspesnih trampi
</StatusText>
<StatusText>
<b>{author.goodCommunicationProcent}</b> korektna komunikacija
</StatusText>
</BottomDetails>
</HeaderDetails>
</ItemDetailsHeaderContainer>
);
};

ItemDetailsHeaderCard.propTypes = {
children: PropTypes.node,
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
category: PropTypes.string,
author: PropTypes.string,
location: PropTypes.string,
image: PropTypes.node,
quantity: PropTypes.number,
package: PropTypes.string,
numberOfViews: PropTypes.number,
halfwidth: PropTypes.bool,
sponsored: PropTypes.bool,
};
ItemDetailsHeaderCard.defaultProps = {
halfwidth: false,
sponsored: false,
};

export default ItemDetailsHeaderCard;

+ 186
- 0
src/components/ItemDetails/ItemDetailsHeaderCard/ItemDetailsHeaderCard.styled.js Просмотреть файл

@@ -0,0 +1,186 @@
import { Box, Grid, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";
import { IconButton } from "../../Buttons/IconButton/IconButton";
import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import { Icon } from "../../Icon/Icon";

export const ItemDetailsHeaderContainer = styled(Box)`
display: flex;
flex-direction: column;
width: ${(props) => (!props.halfwidth ? "100%" : "49%")};
box-sizing: border-box;
margin: 10px 0;
background-color: ${(props) =>
props.sponsored === 'true' ? selectedTheme.backgroundSponsoredColor : "white"};
border-radius: 4px;
border: 1px solid ${selectedTheme.borderNormal};
max-width: 2000px;
position: relative;
`;
export const DetailContainer = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
gap:7px;
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
`;
export const HeaderTop = styled(Box)`
display:flex;
flex-direction: row;
padding:18px;
gap:18px;
`;
export const HeaderDetails = styled(Box)`
background-color: ${selectedTheme.primaryIconBackgroundColor};
`;
export const BottomDetails = styled(Box)`
max-width:fit-content;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 12px;
grid-row-gap: 12px;
padding: 18px;
`;
export const OfferImage = styled(Box)`
border-radius: 50%;
`;
export const OfferInfo = styled(Box)`
display: flex;
flex: 2;
flex-direction: column;
justify-content: space-between;
margin-left: 18px;
`;
export const OfferTitle = styled(Typography)`
margin-bottom:12px;
font-family: "Open Sans";
color: ${selectedTheme.primaryPurple};
font-weight: 700;
font-size: 24px;
`;
export const OfferAuthor = styled(Box)`
display: flex;
flex: 1;
flex-direction: column;
`;
export const OfferAuthorName = styled(Typography)`
font-family: "Open Sans";
line-height: 22px;
font-size: 16px;
color: ${selectedTheme.primaryDarkText};
`;
export const OfferLocation = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
`;
export const OfferPIB = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
`;
export const OfferDetails = styled(Box)`
display: flex;
flex-direction: column;
flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")};
justify-content: start;
`;

export const StatusText = styled(Grid)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
`
export const OfferCategory = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 33%;
`;
export const OfferPackage = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 34%;
`;
export const OfferViews = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
width: 34%;
`;
export const OfferDescriptionTitle = styled(Box)`
font-family: "Open Sans";
font-size: 12px;
color: ${selectedTheme.primaryDarkText};
line-height: 16px;
`;
export const OfferDescriptionText = styled(Box)`
font-family: "Open Sans";
font-size: 16px;
color: ${selectedTheme.primaryDarkText};
line-height: 22px;
max-width: calc(100% - 230px);
max-height: 120px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
`;
export const OfferDescription = styled(Box)`
flex: 3;
margin: auto 0;
padding-left: 35px;
`;
export const Line = styled(Box)`
border-left: 1px solid rgba(0, 0, 0, 0.15);
height: 100px;
width: 0;
margin: auto 0;
`;
export const DetailIcon = styled(Icon)`
display:flex;
align-items:center;
& svg {
width: 22px;
position: relative;
}
`;
export const DetailText = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 16px;
position: relative;
`;
export const CheckButton = styled(PrimaryButton)`
width: 180px;
height: 48px;
position: absolute;
bottom: 9px;
right: 9px;
&:hover button {
background-color: ${selectedTheme.primaryPurple} !important;
color: white !important;
}
`;
export const MessageIcon = styled(IconButton)`
width: 40px;
height: 40px;
position: absolute;
top: 10px;
right: 10px;
background-color: ${selectedTheme.primaryPurple};
border-radius: 100%;
padding-top: 2px;
text-align: center;
`;

+ 59
- 0
src/components/ItemDetails/MockupdataDetails.js Просмотреть файл

@@ -0,0 +1,59 @@
import React from 'react'
import {ReactComponent as DummyImage1 } from "../../assets/images/svg/dummyImages/offer-1.svg"
import {ReactComponent as DummyAuthorImage1} from "../../assets/images/svg/dummyImages/DummyAuthorImage1.svg"
// import {ReactComponent as DummyImage2 } from "../../assets/images/svg/dummyImages/offer-2.svg"
// import {ReactComponent as DummyImage3 } from "../../assets/images/svg/dummyImages/offer-3.svg"
// import {ReactComponent as DummyImage4 } from "../../assets/images/svg/dummyImages/offer-4.svg"

export const packageEnum = {
package: "PACKAGE",
palette: "PALETTE",
piece: "PIECE"
}

export const Author = {
id: 0,
image: <DummyAuthorImage1 />,
title: "Women's Beauty House",
pib: 123456789,
location: "Nis, Serbia",
numberOfOffers: 9,
numberOfViews: 1200,
successSwapsProcent: "75%",
goodCommunicationProcent: "90%",
}

export const Offer = {
id: 0,
title: "Vino",
category: "Hrana i pice",
subcategory:"Farbe",
status:"novo",
quantity:150,
numberOfViews:45,
description: "Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.Vinarija Aleksić osnovana je u Vranju 2006. godine, otvorivši time put oživljavanju vinogradarstva na jugu Srbije.",
images: [
{
id:0,
image: <DummyImage1 />
},
{
id:1,
image: <DummyImage1 />
},
{
id:2,
image: <DummyImage1 />
},
{
id:3,
image: <DummyImage1 />
},
{
id:4,
image: <DummyImage1 />
},
],
package: packageEnum.package,
postDate: "12.04.2022",
}

+ 12
- 9
src/components/Scroller/HorizontalScroller.js Просмотреть файл

@@ -2,10 +2,9 @@ import React, { useRef, useState } from "react";
import PropTypes from "prop-types";
import {
HorizontalScrollerContainer,
Arrow,
ListContainer,
ArrowIcon,
} from "./HorizontalScroller.styled";
import { ArrowButton } from "../Buttons/ArrowButton/ArrowButton";

const HorizontalScroller = (props) => {
const scrollRef = useRef(null);
@@ -55,10 +54,12 @@ const HorizontalScroller = (props) => {
scrollRef.current.scrollBy({ left: -50, behaviour: "smooth" });
};
return (
<HorizontalScrollerContainer style={props.containerStyle} className={props.className}>
<Arrow onClick={handleLeft} disabled={isDisabledLeftButton}>
<ArrowIcon side={"left"} />
</Arrow>
<HorizontalScrollerContainer style={props.containerStyle}>
<ArrowButton
onClick={handleLeft}
disabled={isDisabledLeftButton}
side={"left"}
></ArrowButton>
<ListContainer
innerRef={scrollRef}
style={props.listStyle}
@@ -66,9 +67,11 @@ const HorizontalScroller = (props) => {
>
{props.children}
</ListContainer>
<Arrow onClick={handleRight} disabled={isDisabledRightButton}>
<ArrowIcon side={"right"} />
</Arrow>
<ArrowButton
onClick={handleRight}
disabled={isDisabledRightButton}
side={"right"}
></ArrowButton>
</HorizontalScrollerContainer>
);
};

+ 3
- 2
src/components/Scroller/HorizontalScroller.styled.js Просмотреть файл

@@ -1,8 +1,9 @@
import { Box, Button } from "@mui/material";
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 HorizontalScrollerContainer = styled(Box)`
@@ -12,7 +13,7 @@ export const HorizontalScrollerContainer = styled(Box)`
flex-wrap: nowrap;
overflow: hidden;
`
export const Arrow = styled(Button)`
export const Arrow = styled(IconButton)`
border: 1px solid ${selectedTheme.primaryPurple};
border-radius: 100%;
min-width: 40px;

+ 24
- 0
src/components/UserReviewsCard/Mockupdata.js Просмотреть файл

@@ -0,0 +1,24 @@
export default [{
id: 0,
name: "Coca-Cola",
quote: "Odlična saradnja. Sve preporuke za kompaniju",
isGood: true,
isGoodCommunication: "DA",
isSuccessfulSwap: "DA"
}
,{
id: 1,
name: "Voda Vrnjci",
quote: "Sasvim korektna saradnja, rado bih ponovio poslovanje sa Vama.",
isGood: true,
isGoodCommunication: "DA",
isSuccessfulSwap: "DA"
}
,{
id: 2,
name: "Women's Beauty House",
quote: "Nismo se najbolje razumeli, ali generalno ok",
isGood: false,
isGoodCommunication: "NE",
isSuccessfulSwap: "NE"
}];

+ 103
- 0
src/components/UserReviewsCard/UserReviewsCard.js Просмотреть файл

@@ -0,0 +1,103 @@
import React from "react";
import PropTypes from "prop-types";
import { ReviewList, ReviewsBox } from "./UserReviewsCard.styled";

import {
Avatar,
Grid,
ListItem,
ListItemAvatar,
Typography,
Divider,
} from "@mui/material";

import Mockupdata from "./Mockupdata";

import ThumbUpIcon from "@mui/icons-material/ThumbUp";
import ThumbDownIcon from "@mui/icons-material/ThumbDown";
import StarBorderIcon from "@mui/icons-material/StarBorder";
import { PRIMARY_PURPLE_COLOR } from "../../constants/stylesConstants";

const UserReviewsCard = (props) => {
var dataMockupdata = JSON.parse(JSON.stringify(Mockupdata));

return (
<>
<ReviewsBox>
<Grid
container
direction="row"
justifyContent="start"
alignItems="center"
sx={{ mb: 1.4 }}
>
<StarBorderIcon color="action" sx={{ mr: 0.9 }} />
<Typography>{props.heading}</Typography>
</Grid>
<ReviewList>
{dataMockupdata.map((review) => (
<>
<ListItem
alignItems="flex-start"
sx={{ alignItems: "center", mt: 2 }}
>
<ListItemAvatar sx={{ mt: 0 }}>
<Avatar alt={review.name} src="/static/images/avatar/1.jpg" />
</ListItemAvatar>
<Typography sx={{ color: PRIMARY_PURPLE_COLOR }}>
<b>{review.name}</b>
</Typography>
</ListItem>
<Grid
container
direction="row"
justifyContent="start"
alignItems="center"
spacing={2}
sx={{ pl: 2, py: 2 }}
>
<Grid item xs={1}>
{review.isGood ? (
<ThumbUpIcon color="success" />
) : (
<ThumbDownIcon color="error" />
)}
</Grid>
<Grid item xs={11}>
<Typography
sx={{ display: "inline" }}
component="span"
variant="body2"
color="text.primary"
>
&quot;{review.quote}&quot;
</Typography>
</Grid>
</Grid>
<Grid sx={{ pl: 2, pb: 2 }}>
<Typography variant="body2" sx={{ display: "block" }}>
Korektna komunikacija: <b>{review.isGoodCommunication}</b>
</Typography>
<Typography variant="body2" sx={{ display: "block" }}>
Uspešna trampa: <b>{review.isSuccessfulSwap}</b>
</Typography>
</Grid>
{review.id < dataMockupdata.length - 1 ? (
<Divider variant="inset" component="li" sx={{ ml: 0 }} />
) : (
<></>
)}
</>
))}
</ReviewList>
</ReviewsBox>
</>
);
};

UserReviewsCard.propTypes = {
children: PropTypes.node,
heading: PropTypes.string,
};

export default UserReviewsCard;

+ 31
- 0
src/components/UserReviewsCard/UserReviewsCard.styled.js Просмотреть файл

@@ -0,0 +1,31 @@
import styledComponents from "styled-components";
import { List, Box } from "@mui/material";
//import { PRIMARY_PURPLE_COLOR, PRIMARY_YELLOW_COLOR } from '../../constants/stylesConstants';

export const ReviewsBox = styledComponents(Box)`
width: 100%;
max-width: 360px;
position: fixed;
right: 0;
bottom: 0;
height: calc(100% - 90px);
`;

export const ReviewList = styledComponents(List)`
background: white;
padding: 2rem;
border-radius: 4px 0 0 4px;
height: 100%;
overflow-y: auto;
&::-webkit-scrollbar {
width: 5px;
}
&::-webkit-scrollbar-track {
background: #ddd;
}
&::-webkit-scrollbar-thumb {
background: #777;
}
scrollbar-width: thin;
scrollbar-color: #ddd;
`;

+ 5
- 4
src/constants/pages.js Просмотреть файл

@@ -4,8 +4,9 @@ export const FORGOT_PASSWORD_PAGE = '/forgot-password';
export const HOME_PAGE = '/home';
export const ERROR_PAGE = '/error-page';
export const NOT_FOUND_PAGE = '/not-found';
export const FORGOT_PASSWORD_MAIL_SENT = '/forgot-password/mail-sent'
export const REGISTER_PAGE = "/register"
export const FORGOT_PASSWORD_MAIL_SENT = '/forgot-password/mail-sent';
export const REGISTER_PAGE = "/register";
export const REGISTER_SUCCESSFUL_PAGE = "/register/success";
export const RESET_PASSWORD_PAGE = "/reset-password/:token"
export const CREATE_OFFER_PAGE = "/create-offer"
export const RESET_PASSWORD_PAGE = "/reset-password/:token";
export const CREATE_OFFER_PAGE = "/create-offer";
export const ITEM_DETAILS_PAGE = "/proizvodi/:idProizvod";

+ 1
- 0
src/i18n/resources/rs.js Просмотреть файл

@@ -88,6 +88,7 @@ export default {
terms: "Uslove Korišćenja",
success: 'Registracija Uspešna',
PIBTaken: "PIB je zauzet!",
PIBnoOfCharacters: "PIB mora imati 9 karaktera!",
welcome: 'Dobro došli na trampu, želimo vam uspešno trampovanje!',
},
forgotPassword: {

+ 3
- 0
src/initialValues/forgotPasswordInitialValues.js Просмотреть файл

@@ -0,0 +1,3 @@
export default {
email: "",
};

+ 4
- 0
src/initialValues/loginInitialValues.js Просмотреть файл

@@ -0,0 +1,4 @@
export default {
email: "",
password: "",
};

+ 4
- 0
src/initialValues/registerInitialValues/firstPartInitialValues.js Просмотреть файл

@@ -0,0 +1,4 @@
export default {
mail: "",
password: "",
};

+ 4
- 0
src/initialValues/registerInitialValues/secondPartInitialValues.js Просмотреть файл

@@ -0,0 +1,4 @@
export default {
nameOfFirm: "",
PIB: "",
};

+ 5
- 0
src/initialValues/registerInitialValues/thirdPartInitialValues.js Просмотреть файл

@@ -0,0 +1,5 @@
export default {
phoneNumber: "",
location: "",
website: "",
};

+ 4
- 0
src/initialValues/resetPasswordInitialValues.js Просмотреть файл

@@ -0,0 +1,4 @@
export default {
password: "",
passwordConfirm: "",
};

+ 30
- 0
src/layouts/ItemDetailsLayout/ItemDetailsLayout.js Просмотреть файл

@@ -0,0 +1,30 @@
import React from "react";
import PropTypes from "prop-types";
import { Content, RightCard, ItemDetailsLayoutContainer } from "./ItemDetailsLayout.styled";
import { Grid } from "@mui/material";

const ItemDetailsLayout = (props) => {
return (
<ItemDetailsLayoutContainer>
{props.children}
<Grid container maxHeight="xl">
<Content item xs={10} lg={9} xl={9.6} md={8} >
{props.content}
</Content>
<RightCard item xs={2} lg={3} xl={2.4} md={4} >
{props.rightCard}
</RightCard>
</Grid>
</ItemDetailsLayoutContainer>
);
};

ItemDetailsLayout.propTypes = {
children: PropTypes.node,
leftCard: PropTypes.node,
content: PropTypes.node,
rightCard: PropTypes.node,
};

export default ItemDetailsLayout;

+ 20
- 0
src/layouts/ItemDetailsLayout/ItemDetailsLayout.styled.js Просмотреть файл

@@ -0,0 +1,20 @@
import { Container, Grid } from "@mui/material";
import styled from "styled-components";

export const ItemDetailsLayoutContainer = styled(Container)`
padding-left: 60px;
padding-right: 0;
margin: 0;
width: 100%;
max-width: none;
display: flex;
flex: 1;
height: 100%;
`

export const RightCard = styled(Grid)`
margin-top: 30px;
border-top-right-radius: 4px;
`
export const Content = styled(Grid)`
`

+ 17
- 0
src/pages/ItemDetailsPage/ItemDetailsPage.styled.js Просмотреть файл

@@ -0,0 +1,17 @@
import styled from "styled-components";
import { Container, Grid } from "@mui/material";
import selectedTheme from "../../themes";
export const ItemDetailsPageContainer = styled(Container)`
padding: 0;
margin: 0;
height: 100%;
width: 100%;
max-width: none;
flex: 1;
display: flex;
flex-direction: column;
background-color: ${selectedTheme.offerBackgroundColor};
`;
export const GridStyled = styled(Grid)`
`;

+ 84
- 0
src/pages/ItemDetailsPage/ItemDetailsPageMUI.js Просмотреть файл

@@ -0,0 +1,84 @@
import React, { useEffect } from "react";
import Navbar from "../../components/MUI/NavbarComponent";
import { ItemDetailsPageContainer } from "./ItemDetailsPage.styled";
import { useDispatch } from "react-redux";
import { logoutUser } from "../../store/actions/login/loginActions";
import Mockupdata from "../../components/Cards/FilterCard/Mockupdata";
import qs from "query-string";
import { useHistory } from "react-router-dom";
import { setFilters } from "../../store/actions/filters/filtersActions";
import ItemDetails from "../../components/ItemDetails/ItemDetails";
import ItemDetailsLayout from "../../layouts/ItemDetailsLayout/ItemDetailsLayout";

const ItemDetailsPage = () => {
const dispatch = useDispatch();

//const routetMatch = useRouteMatch();
const history = useHistory();

useEffect(() => {
const queryString = history.location.search.substring(1);
const queryObject = qs.parse(queryString);
let category = null;
if (queryObject.category) {
category = Mockupdata[1].find(
(item) => item.string === queryObject.category.toString()
).id;
}
let cities = [];
if (queryObject.city) {
if (Array.isArray(queryObject.city)) {
queryObject.city.forEach((item) => {
cities.push(Mockupdata[0].find((p) => p.string === item).id);
});
} else {
cities.push(
Mockupdata[0].find((p) => p.string === queryObject.city).id
);
}
}
let subcategory = null;
if (queryObject.subcategory) {
subcategory = Mockupdata[1].find(
(item) => item.string === queryObject.subcategory.toString()
).id;
}
console.log("iz useeffect: ", { category, subcategory, cities });
dispatch(setFilters({ category, subcategory, cities }));
}, [history.location.search]);
const handleCl = () => {
dispatch(logoutUser());
};
return (
<ItemDetailsPageContainer>
<button onClick={handleCl}>Dugme</button>
<Navbar />
{/* right card mora mi bude Review Card */}
<ItemDetailsLayout content={<ItemDetails />} />

{/* <Box sx={{ mt: 4, mx: 4 }}>
<GridStyled container justifyContent="space-between">
<GridStyled item xs={12} md={3}>
asdasdasd
</GridStyled>
<GridStyled item xs={12} md={6}>
<GridStyled xs={12} md={12}>
<HomeListCard></HomeListCard>
</GridStyled>
</GridStyled> */}
{/* <GridStyled item xs={12} md={9}>
<PagingSortingFiltering />
</GridStyled>
<GridStyled item xs={12} md={9}>
{/* Move to higher components? */}
{/* <RandomDataProvider>
<PagingSortingFilteringServerSide />
</RandomDataProvider>
</GridStyled> */}
{/* </GridStyled>
</Box> */}
</ItemDetailsPageContainer>
);
};

export default ItemDetailsPage;

+ 4
- 10
src/pages/LoginPage/LoginPage.js Просмотреть файл

@@ -32,6 +32,8 @@ import {
ErrorMessage,
} from "./Login.styled";
import selectedTheme from "../../themes";
import loginValidation from "../../validations/loginValidation";
import loginInitialValues from "../../initialValues/loginInitialValues";

const LoginPage = ({ history }) => {
const dispatch = useDispatch();
@@ -83,16 +85,8 @@ const LoginPage = ({ history }) => {
};

const formik = useFormik({
initialValues: {
email: "",
password: "",
},
validationSchema: Yup.object().shape({
email: Yup.string().required(t("login.mailRequired")),
password: Yup.string()
.required(t("login.passwordRequired"))
.min(8, t("login.passwordLength")),
}),
initialValues: loginInitialValues,
validationSchema: loginValidation,
onSubmit: handleSubmit,
validateOnBlur: true,
enableReinitialize: true,

+ 7
- 7
src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.js Просмотреть файл

@@ -68,12 +68,6 @@ const FirstPartOfRegistration = (props) => {
fullWidth
/>

{formik.errors.mail && formik.touched.mail ? (
<ErrorMessage>{formik.errors.mail}</ErrorMessage>
) : (
<></>
)}

<TextField
name="password"
placeholder={t("common.labelPassword")}
@@ -94,11 +88,17 @@ const FirstPartOfRegistration = (props) => {
),
}}
/>
{formik.errors.password && formik.touched.password ? (


{formik.errors.mail && formik.touched.mail ? (
<ErrorMessage>{formik.errors.mail}</ErrorMessage>
) : formik.errors.password && formik.touched.password ? (

<ErrorMessage>{formik.errors.password}</ErrorMessage>
) : (
<></>
)}

{props.error && <ErrorMessage>{props.errorMessage}</ErrorMessage>}

<PrimaryButton

+ 4
- 4
src/request/index.js Просмотреть файл

@@ -2,8 +2,8 @@ import axios from "axios";
import queryString from "qs";

const request = axios.create({
// baseURL: "http://192.168.88.150:3001/",
baseURL: "http://192.168.88.176:3001/",
baseURL: "http://192.168.88.150:3001/",
// baseURL: "http://192.168.88.176:3001/",
headers: {
"Content-Type": "application/json",
},
@@ -13,9 +13,9 @@ const request = axios.create({
});

export const getRequest = (url, params = null, options = null) => {
console.log('url: ', url);
console.log("url: ", url);
return request.get(url, { params, ...options });
}
};

export const postRequest = (url, data, params = null, options = null) =>
request.post(url, data, { params, ...options });

+ 4
- 4
src/store/middleware/accessTokensMiddleware.js Просмотреть файл

@@ -13,8 +13,8 @@ import { logoutUser, refreshUserToken } from "../actions/login/loginActions";
// import { setUserAccessToken } from "../actions/user/userActions";

//Change URL with .env
//const baseURL = "http://192.168.88.150:3001/";
const baseURL = "http://192.168.88.175:3005/";
const baseURL = "http://192.168.88.150:3001/";
// const baseURL = "http://192.168.88.175:3005/";

//Interceptor unique name
export const accessTokensMiddlewareInterceptorName = "ACCESS_TOKEN_INTERCEPTOR";
@@ -31,7 +31,7 @@ export default ({ dispatch }) =>
if (!response.headers?.Authorization) {
response.headers.Authorization = `Bearer ${jwtToken}`;
}
// If refresh token is expired, log out user
if (new Date() > new Date(refreshTokenDecoded?.exp * 1000)) {
dispatch(logoutUser());
@@ -45,7 +45,7 @@ export default ({ dispatch }) =>
const newToken = axiosResponse.data.token;
dispatch(refreshUserToken(newToken));
}
return Promise.resolve(response);
}, accessTokensMiddlewareInterceptorName);


+ 18
- 18
src/themes/primaryTheme/primaryThemeColors.js Просмотреть файл

@@ -1,19 +1,19 @@
export const primaryThemeColors = {
primaryPurple: "#5A3984",
primaryYellow: "#f7b126",
primaryPurpleDisabled: "#4D4D4D",
primaryBackgroundColor: "#F1F1F1",
primaryTextDisabled: "#F1F1F1",
primaryText: "#4D4D4D",
primaryGrayText: "#818181",
primaryDarkGrayText: "#DCDCDC",
primaryIconBackgroundColor: "#E4E4E4",
borderSponsoredColor: "#E5D0FF",
backgroundSponsoredColor: "#F5EDFF",
offerBackgroundColor: "#F5F5F5",
selectOptionTextColor: "#1D1D1D",
primaryDarkText: "#505050",
iconStrokeColor: "#8C8C8C",
iconStrokeDisabledColor: '#C4C4C4',
imagePickerBackground: "#E4E4E4"
}
primaryPurple: "#5A3984",
primaryYellow: "#f7b126",
primaryPurpleDisabled: "#4D4D4D",
primaryBackgroundColor: "#F1F1F1",
primaryTextDisabled: "#F1F1F1",
primaryText: "#4D4D4D",
primaryGrayText: "#818181",
primaryDarkGrayText: "#DCDCDC",
primaryIconBackgroundColor: "#E4E4E4",
borderNormal: "#D4D4D4",
borderSponsoredColor: "#E5D0FF",
backgroundSponsoredColor: "#F5EDFF",
offerBackgroundColor: "#F5F5F5",
selectOptionTextColor: "#1D1D1D",
primaryDarkText: "#505050",
iconStrokeColor: "#8C8C8C",
// iconStrokeDisabledColor: "#818181",
};

+ 8
- 0
src/validations/forgotPasswordValidation.js Просмотреть файл

@@ -0,0 +1,8 @@
import * as Yup from "yup";
import i18n from "../i18n";

export default Yup.object().shape({
email: Yup.string()
.required(i18n.t("forgotPassword.emailRequired"))
.email(i18n.t("forgotPassword.emailFormat")),
});

+ 9
- 0
src/validations/loginValidation.js Просмотреть файл

@@ -0,0 +1,9 @@
import * as Yup from "yup";
import i18n from "../i18n";

export default Yup.object().shape({
email: Yup.string().email(i18n.t("login.emailFormat")).required(i18n.t("login.mailRequired")),
password: Yup.string()
.required(i18n.t("login.passwordRequired"))
.min(8, i18n.t("login.passwordLength")),
});

+ 10
- 0
src/validations/registerValidations/firstPartValidation.js Просмотреть файл

@@ -0,0 +1,10 @@
import * as Yup from "yup";
import i18n from "../../i18n";
export default Yup.object().shape({
mail: Yup.string()
.email(i18n.t("forgotPassword.emailFormat"))
.required(i18n.t("login.usernameRequired")),
password: Yup.string()
.required(i18n.t("login.passwordRequired"))
.min(8, i18n.t("login.passwordLength")),
});

+ 10
- 0
src/validations/registerValidations/secondPartValidation.js Просмотреть файл

@@ -0,0 +1,10 @@
import * as Yup from "yup";
import i18n from "../../i18n";

export default Yup.object().shape({
nameOfFirm: Yup.string().required(i18n.t("login.usernameRequired")),
PIB: Yup.number()
.required(i18n.t("login.passwordRequired"))
.min(100000000, i18n.t("register.PIBnoOfCharacters"))
.max(999999999, i18n.t("register.PIBnoOfCharacters")),
});

+ 10
- 0
src/validations/registerValidations/thirdPartValidation.js Просмотреть файл

@@ -0,0 +1,10 @@
import * as Yup from "yup";
import i18n from "../../i18n";

export default Yup.object().shape({
phoneNumber: Yup.number().required(i18n.t("login.usernameRequired")),
location: Yup.string().required(i18n.t("login.passwordRequired")),
website: Yup.string().matches(
/^((ftp|http|https):\/\/)?(www.)?(?!.*(ftp|http|https|www.))[a-zA-Z0-9_-]+(\.[a-zA-Z]+)+((\/)[\w#]+)*(\/\w+\?[a-zA-Z0-9_]+=\w+(&[a-zA-Z0-9_]+=\w+)*)?$/gm
),
});

+ 6
- 0
src/validations/resetPasswordValidation.js Просмотреть файл

@@ -0,0 +1,6 @@
import * as Yup from "yup";

export default Yup.object().shape({
password: Yup.string().required().min(8),
passwordConfirm: Yup.string().oneOf([Yup.ref("password"), null]),
});

+ 53
- 4
yarn.lock Просмотреть файл

@@ -3778,6 +3778,11 @@
"isobject" "^3.0.0"
"static-extend" "^0.1.1"

"classnames@^2.2.6":
"integrity" "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
"resolved" "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz"
"version" "2.3.1"

"clean-css@^4.2.3":
"integrity" "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA=="
"resolved" "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz"
@@ -4485,6 +4490,11 @@
"resolved" "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz"
"version" "2.28.0"

"debounce@^1.2.0":
"integrity" "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
"resolved" "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz"
"version" "1.2.1"

"debug@*", "debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@4":
"integrity" "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ=="
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
@@ -4880,6 +4890,11 @@
"readable-stream" "^2.0.0"
"stream-shift" "^1.0.0"

"easy-bem@^1.1.1":
"integrity" "sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A=="
"resolved" "https://registry.npmjs.org/easy-bem/-/easy-bem-1.1.1.tgz"
"version" "1.1.1"

"ecdsa-sig-formatter@1.0.11":
"integrity" "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="
"resolved" "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
@@ -5710,6 +5725,11 @@
dependencies:
"to-regex-range" "^5.0.1"

"filter-obj@^1.1.0":
"integrity" "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="
"resolved" "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz"
"version" "1.1.0"

"finalhandler@~1.1.2":
"integrity" "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="
"resolved" "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz"
@@ -10107,13 +10127,23 @@
"version" "6.7.0"

"query-string@^4.1.0":
"integrity" "sha1-u7aTucqRXCMlFbIosaArYJBD2+s="
"integrity" "sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q=="
"resolved" "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz"
"version" "4.3.4"
dependencies:
"object-assign" "^4.1.0"
"strict-uri-encode" "^1.0.0"

"query-string@^7.1.1":
"integrity" "sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w=="
"resolved" "https://registry.npmjs.org/query-string/-/query-string-7.1.1.tgz"
"version" "7.1.1"
dependencies:
"decode-uri-component" "^0.2.0"
"filter-obj" "^1.1.0"
"split-on-first" "^1.0.0"
"strict-uri-encode" "^2.0.0"

"querystring-es3@^0.2.0":
"integrity" "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
"resolved" "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz"
@@ -10228,7 +10258,7 @@
"strip-ansi" "6.0.0"
"text-table" "0.2.0"

"react-dom@*", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16.6.0":
"react-dom@*", "react-dom@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0", "react-dom@^17.0.0 || ^18.0.0", "react-dom@^17.0.2", "react-dom@>= 16.8.0", "react-dom@>=16.6.0":
"integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA=="
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
"version" "17.0.2"
@@ -10272,6 +10302,15 @@
"html-escaper" "^2.0.2"
"html-parse-stringify" "^3.0.1"

"react-indiana-drag-scroll@^2.2.0":
"integrity" "sha512-+W/3B2OQV0FrbdnsoIo4dww/xpH0MUQJz6ziQb7H+oBko3OCbXuzDFYnho6v6yhGrYDNWYPuFUewb89IONEl/A=="
"resolved" "https://registry.npmjs.org/react-indiana-drag-scroll/-/react-indiana-drag-scroll-2.2.0.tgz"
"version" "2.2.0"
dependencies:
"classnames" "^2.2.6"
"debounce" "^1.2.0"
"easy-bem" "^1.1.1"

"react-input-autosize@^3.0.0":
"integrity" "sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg=="
"resolved" "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz"
@@ -10439,7 +10478,7 @@
"loose-envify" "^1.4.0"
"prop-types" "^15.6.2"

"react@*", "react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@^16.3.0 || ^17.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", "react@^17.0.2", "react@^17.0.2 || ^18.0.0", "react@>= 16", "react@>= 16.8.0", "react@>=15", "react@>=16.6.0", "react@>=16.8.0", "react@17.0.2":
"react@*", "react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.0 || ^17.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0", "react@^16.8.3 || ^17 || ^18", "react@^16.9.0 || ^17.0.0 || ^18", "react@^17.0.0 || ^18.0.0", "react@^17.0.2", "react@^17.0.2 || ^18.0.0", "react@>= 16", "react@>= 16.8.0", "react@>=15", "react@>=16.6.0", "react@>=16.8.0", "react@17.0.2":
"integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA=="
"resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
"version" "17.0.2"
@@ -11607,6 +11646,11 @@
"select-hose" "^2.0.0"
"spdy-transport" "^3.0.0"

"split-on-first@^1.0.0":
"integrity" "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
"resolved" "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz"
"version" "1.1.0"

"split-string@^3.0.1", "split-string@^3.0.2":
"integrity" "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw=="
"resolved" "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz"
@@ -11703,10 +11747,15 @@
"version" "1.0.1"

"strict-uri-encode@^1.0.0":
"integrity" "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
"integrity" "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ=="
"resolved" "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz"
"version" "1.1.0"

"strict-uri-encode@^2.0.0":
"integrity" "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="
"resolved" "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz"
"version" "2.0.0"

"string_decoder@^1.0.0", "string_decoder@~1.1.1":
"integrity" "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="
"resolved" "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"

Загрузка…
Отмена
Сохранить