Djordje Mitrovic 3 лет назад
Родитель
Сommit
09e7094156
68 измененных файлов: 2003 добавлений и 354 удалений
  1. 3
    0
      public/index.html
  2. 25
    22
      src/App.js
  3. 14
    6
      src/AppRoutes.js
  4. 3
    0
      src/assets/images/svg/VisibilityOff.svg
  5. 4
    0
      src/assets/images/svg/VisibilityOn.svg
  6. 7
    0
      src/assets/images/svg/big-logo-vertical.svg
  7. 3
    0
      src/assets/images/svg/checkmark.svg
  8. 7
    0
      src/assets/images/svg/logo-vertical.svg
  9. 9
    0
      src/assets/images/svg/mail-sent.svg
  10. 9
    0
      src/assets/images/svg/register-success.svg
  11. 1
    0
      src/assets/styles/_base.scss
  12. 19
    0
      src/components/Buttons/IconButton/IconButton.js
  13. 8
    0
      src/components/Buttons/IconButton/IconButton.styled.js
  14. 4
    3
      src/components/Buttons/LoginButton/LoginButton.js
  15. 2
    2
      src/components/Buttons/LoginButton/LoginButton.styled.js
  16. 17
    9
      src/components/Buttons/PrimaryButton/PrimaryButton.js
  17. 20
    9
      src/components/Buttons/PrimaryButton/PrimaryButton.styled.js
  18. 34
    0
      src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.js
  19. 28
    0
      src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.styled.js
  20. 66
    0
      src/components/CheckBox/CheckBox.js
  21. 26
    0
      src/components/CheckBox/CheckBox.styled.js
  22. 19
    0
      src/components/CheckBox/Label.js
  23. 26
    0
      src/components/CheckBox/Label.styled.js
  24. 20
    0
      src/components/Dropdown/DropdownItem/DropdownItem.js
  25. 8
    0
      src/components/Dropdown/DropdownItem/DropdownItem.styled.js
  26. 59
    0
      src/components/Dropdown/DropdownList/DropdownList.js
  27. 51
    0
      src/components/Dropdown/DropdownList/DropdownList.styled.js
  28. 25
    0
      src/components/Icon/Icon.js
  29. 11
    0
      src/components/Icon/Icon.styled.js
  30. 25
    0
      src/components/Link/Link.js
  31. 17
    0
      src/components/Link/Link.styled.js
  32. 5
    3
      src/components/Loader/FullPageLoader.js
  33. 10
    0
      src/components/Loader/FullPageLoader.styled.js
  34. 43
    0
      src/components/StepProgress/StepProgress.js
  35. 44
    0
      src/components/StepProgress/StepProgress.styled.js
  36. Двоичные данные
      src/components/Styles/fonts/Mulish-Regular.ttf
  37. Двоичные данные
      src/components/Styles/fonts/OpenSans-Regular.ttf
  38. Двоичные данные
      src/components/Styles/fonts/Poppins-Regular.ttf
  39. 29
    0
      src/components/Styles/globalStyles.js
  40. 0
    14
      src/components/TextFields/TextField.styled.js
  41. 33
    11
      src/components/TextFields/TextField/TextField.js
  42. 31
    0
      src/components/TextFields/TextField/TextField.styled.js
  43. 24
    0
      src/components/TextFields/TextFieldWithIcon/TextFieldWithIcon.js
  44. 18
    0
      src/components/TextFields/TextFieldWithIcon/TextFieldWithIcon.styled.js
  45. 4
    1
      src/constants/pages.js
  46. 0
    2
      src/constants/stylesConstants.js
  47. 7
    3
      src/i18n/index.js
  48. 106
    0
      src/i18n/resources/rs.js
  49. 41
    0
      src/pages/ForgotPasswordPage/ForgotPassword.styled.js
  50. 86
    0
      src/pages/ForgotPasswordPage/ForgotPasswordMailSent/MailSent.js
  51. 71
    0
      src/pages/ForgotPasswordPage/ForgotPasswordMailSent/MailSent.styled.js
  52. 75
    84
      src/pages/ForgotPasswordPage/ForgotPasswordPageMUI.js
  53. 54
    0
      src/pages/LoginPage/Login.styled.js
  54. 108
    113
      src/pages/LoginPage/LoginPageMUI.js
  55. 108
    0
      src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.js
  56. 22
    0
      src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.styled.js
  57. 91
    0
      src/pages/RegisterPages/Register/Register.js
  58. 86
    0
      src/pages/RegisterPages/Register/Register.styled.js
  59. 83
    0
      src/pages/RegisterPages/Register/SecondPart/SecondPartOfRegistration.js
  60. 23
    0
      src/pages/RegisterPages/Register/SecondPart/SecondPartOfRegistration.styled.js
  61. 102
    0
      src/pages/RegisterPages/Register/ThirdPart/ThirdPartOfRegistration.js
  62. 22
    0
      src/pages/RegisterPages/Register/ThirdPart/ThirdPartOfRegistration.styled.js
  63. 43
    0
      src/pages/RegisterPages/RegisterSuccessful.js/RegisterSuccessful.js
  64. 38
    0
      src/pages/RegisterPages/RegisterSuccessful.js/RegisterSuccessful.styled.js
  65. 0
    71
      src/request/accountRequest.js
  66. 2
    1
      src/store/actions/app/appActions.js
  67. 14
    0
      src/themes/index.js
  68. 10
    0
      src/themes/primaryTheme/primaryThemeColors.js

+ 3
- 0
public/index.html Просмотреть файл

@@ -3,6 +3,9 @@
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Open+Sans">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Poppins">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Mulish">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta

+ 25
- 22
src/App.js Просмотреть файл

@@ -1,24 +1,27 @@
import React from 'react';
import { Router } from 'react-router-dom';
import { Helmet } from 'react-helmet-async';
import i18next from 'i18next';
import history from './store/utils/history';
import AppRoutes from './AppRoutes';
import React from "react";
import { Router } from "react-router-dom";
import { Helmet } from "react-helmet-async";
import i18next from "i18next";
import history from "./store/utils/history";
import AppRoutes from "./AppRoutes";
import GlobalStyle from "./components/Styles/globalStyles";
import { StyledEngineProvider } from "@mui/material";

const App = () => (
<>
<Router history={history}>
<Helmet>
<title>
{i18next.t('app.title')}
</title>
</Helmet>
<main className="l-page">
<AppRoutes />
</main>
</Router>
const App = () => {
return (
<>
<Router history={history}>
<Helmet>
<title>{i18next.t("app.title")}</title>
</Helmet>
<main className="l-page">
<StyledEngineProvider injectFirst>
<GlobalStyle />
<AppRoutes />
</StyledEngineProvider>
</main>
</Router>
</>
)};

</>
);

export default App;
export default App;

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

@@ -8,25 +8,33 @@ import {
NOT_FOUND_PAGE,
ERROR_PAGE,
BASE_PAGE,
FORGOT_PASSWORD_MAIL_SENT,
REGISTER_PAGE,
REGISTER_SUCCESSFUL_PAGE,
} from './constants/pages';

// import LoginPage from './pages/LoginPage/LoginPage';
import LoginPage from './pages/LoginPage/LoginPageMUI';
// import HomePage from './pages/HomePage/HomePage';
import HomePage from './pages/HomePage/HomePageMUI';
import NotFoundPage from './pages/ErrorPages/NotFoundPage';
import ErrorPage from './pages/ErrorPages/ErrorPage';
// import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage';
import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPageMUI';
import PrivateRoute from './components/Router/PrivateRoute';
import MailSent from './pages/ForgotPasswordPage/ForgotPasswordMailSent/MailSent';
import Register from './pages/RegisterPages/Register/Register';
import RegisterSuccessful from './pages/RegisterPages/RegisterSuccessful.js/RegisterSuccessful';


const AppRoutes = () => (
const AppRoutes = () => {
return (
<Switch>
<Route exact path={BASE_PAGE} component={LoginPage} />
<Route exact path={LOGIN_PAGE} component={LoginPage} />
<Route path={NOT_FOUND_PAGE} component={NotFoundPage} />
<Route path={REGISTER_SUCCESSFUL_PAGE} component={RegisterSuccessful} />
<Route path={REGISTER_PAGE} component={Register} />
<Route path={ERROR_PAGE} component={ErrorPage} />
<Route path={FORGOT_PASSWORD_MAIL_SENT} component={MailSent} />
<Route path={FORGOT_PASSWORD_PAGE} component={ForgotPasswordPage} />
<PrivateRoute
exact
path={HOME_PAGE}
@@ -34,7 +42,7 @@ const AppRoutes = () => (
/>
<Redirect from="*" to={NOT_FOUND_PAGE} />
</Switch>
);
)};


export default AppRoutes;

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

@@ -0,0 +1,3 @@
<svg width="23" height="18" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.24741 12.2086L1.42675 15M7.02641 13.3083C7.51222 13.3992 8.00558 13.4448 8.5 13.4444C12.0193 13.4444 14.998 11.1554 16 8C15.7302 7.15074 15.3147 6.3538 14.7716 5.64411L7.02641 13.3083ZM10.1677 6.35033C9.72551 5.91271 9.12576 5.66686 8.50039 5.66686C7.87502 5.66686 7.27527 5.91271 6.83307 6.35033C6.39087 6.78796 6.14244 7.3815 6.14244 8.00039C6.14244 8.61928 6.39087 9.21282 6.83307 9.65044L10.1677 6.35033ZM10.1677 6.34956L6.83386 9.64889L10.1677 6.34956ZM10.1661 6.35111L12.7518 3.79222L10.1661 6.35111ZM6.83228 9.65044L4.24662 12.2093L6.83228 9.65044ZM15.5732 1L12.7518 3.79222L15.5732 1ZM12.7518 3.79222C11.4846 2.983 10.0081 2.55354 8.5 2.55556C4.98067 2.55556 2.00204 4.84456 1 8C1.55325 9.7348 2.702 11.2236 4.24741 12.2086L12.7518 3.79222Z" stroke="#5A3984" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

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

@@ -0,0 +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>

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


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

@@ -0,0 +1,3 @@
<svg width="12" height="9" viewBox="0 0 12 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 5.2L3.85714 8L11 1" stroke="#FEB005" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

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


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


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


+ 1
- 0
src/assets/styles/_base.scss Просмотреть файл

@@ -3,6 +3,7 @@ body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-anchor: none;
background-color: #F1F1F1;
}

* {

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

@@ -0,0 +1,19 @@
import React from 'react'
import { IconButtonContainer, IconButtonStyled } from "./IconButton.styled"
import PropTypes from "prop-types";

export const IconButton = (props) => {
return <IconButtonContainer style={props.containerStyle} className={props.className}>
<IconButtonStyled onClick={props.onClick} sx={props.style}>
{props.children}
</IconButtonStyled>
</IconButtonContainer>
}

IconButton.propTypes = {
children: PropTypes.node,
onClick: PropTypes.func,
containerStyle: PropTypes.any,
style: PropTypes.any,
className: PropTypes.string,
}

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

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

export const IconButtonContainer = styled(Box)`
`

export const IconButtonStyled = styled(IconButton)`
`

+ 4
- 3
src/components/Buttons/LoginButton/LoginButton.js Просмотреть файл

@@ -1,16 +1,16 @@
import React from "react";
import { ComponentContainer, LoginButtonStyled } from "./LoginButton.styled";
import { LoginButtonContainer, LoginButtonStyled } from "./LoginButton.styled";
import PropTypes from "prop-types";


//Currently not in use
export const LoginButton = (props) => {
return (
<ComponentContainer style={props.containerStyle}>
<LoginButtonContainer style={props.containerStyle}>
<LoginButtonStyled {...props} sx={props.style} variant="contained">
Dugme
</LoginButtonStyled>
</ComponentContainer>
</LoginButtonContainer>
);
};

@@ -22,4 +22,5 @@ LoginButton.propTypes = {
containerStyle: PropTypes.any,
fullWidth: PropTypes.string,
buttonColor: PropTypes.string,
onClick: PropTypes.func
};

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

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


export const ComponentContainer = styled.div`
export const LoginButtonContainer = styled(Box)`
`

export const LoginButtonStyled = styled(Button)`

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

@@ -1,27 +1,35 @@
import React from "react";
import PropTypes from "prop-types";
import {
ComponentContainer,
PrimaryButtonContainer,
PrimaryButtonStyled,
} from "./PrimaryButton.styled";

export const PrimaryButton = (props) => {
return (
<ComponentContainer style={props.containerStyle}>
<PrimaryButtonStyled fullWidth {...props} sx={props.style}>
<PrimaryButtonContainer style={props.containerStyle} className={props.className}>
<PrimaryButtonStyled {...props} sx={props.style}>
{props.children}
</PrimaryButtonStyled>
</ComponentContainer>
</PrimaryButtonContainer>
);
};

PrimaryButton.propTypes = {
children: PropTypes.node,
type: PropTypes.string,
variant: PropTypes.string,
type: PropTypes.oneOf(["button", "reset", "submit"]),
variant: PropTypes.oneOf(["contained", "outlined", "text"]),
style: PropTypes.any,
containerStyle: PropTypes.any,
fullWidth: PropTypes.string,
buttonColor: PropTypes.string,
textColor: PropTypes.string,
fullWidth: PropTypes.bool,
buttoncolor: PropTypes.string,
textcolor: PropTypes.string,
className: PropTypes.string,
onClick: PropTypes.func,
font: PropTypes.string
};

PrimaryButton.defaultProps = {
font: "Open Sans"
}

+ 20
- 9
src/components/Buttons/PrimaryButton/PrimaryButton.styled.js Просмотреть файл

@@ -1,20 +1,31 @@
import { Button } from "@mui/material";
import { Box, Button } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";

export const ComponentContainer = styled.div``;
export const PrimaryButtonContainer = styled(Box)``;

export const PrimaryButtonStyled = styled(Button)`
background-color: ${props => props.variant === "contained" ? props.buttonColor : "transparent"};
border-color: ${props => props.variant === "outlined" ? props.buttonColor : "transparent"};
color: ${props => props.textColor};
background-color: ${(props) => props.disabled ? selectedTheme.primaryPurpleDisabled: (
props.variant === "contained" ? props.buttoncolor : "transparent")} !important;
border-color: ${(props) =>
props.variant === "outlined" ? props.buttoncolor : "transparent"};
color: ${(props) => props.disabled ? selectedTheme.primaryTextDisabled : (
props.textcolor)} !important;
box-shadow: 0 0 0 0;
font-size: 10px;
font-size: 12px;
letter-spacing: 1px;
font-weight: 100;
width: ${props => props.width};
height: ${props => props.height};
width: ${(props) => props.width};
font-family: ${(props) => props.font};

height: ${(props) => props.height};
&:hover {
background-color: ${props => props.variant === "contained" ? props.buttonColor : "transparent"};
background-color: ${(props) =>
props.variant === "contained" ? props.buttoncolor : "transparent"};
box-shadow: 0 0 0 0;
}
&:disabled {
background-color: ${selectedTheme.primaryPurpleDisabled};
color: ${(props) => props.textcolor};
}
`;

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

@@ -0,0 +1,34 @@
import React from "react";
import PropTypes from "prop-types";
import {
PrimaryButtonWithIconContainer,
IconStyled,
PrimaryButtonWithIconStyled,
} from "./PrimaryButtonWithIcon.styled";

const PrimaryButtonWithIcon = (props) => {
return (
<PrimaryButtonWithIconContainer
style={props.containerStyle}
className={props.className}
>
<PrimaryButtonWithIconStyled sx={props.style} {...props.buttonProps} onClick={props.onClick}>
<IconStyled style={props.iconStyle}>{props.icon}</IconStyled>
{props.children}
</PrimaryButtonWithIconStyled>
</PrimaryButtonWithIconContainer>
);
};

PrimaryButtonWithIcon.propTypes = {
children: PropTypes.node,
icon: PropTypes.node,
className: PropTypes.string,
containerStyle: PropTypes.any,
style: PropTypes.any,
iconStyle: PropTypes.any,
buttonProps: PropTypes.any,
onClick: PropTypes.func,
};

export default PrimaryButtonWithIcon;

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

@@ -0,0 +1,28 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import { Icon } from "../../Icon/Icon";
import { PrimaryButton } from "../PrimaryButton/PrimaryButton";

export const PrimaryButtonWithIconContainer = styled(Box)``;

export const PrimaryButtonWithIconStyled = styled(PrimaryButton)`
position: relative;
`;

export const IconStyled = styled(Icon)`
position: absolute;
padding: 0;
left: 10px;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
line-height: 21px;
& span {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
}
`;

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

@@ -0,0 +1,66 @@
import React, { useState } from "react";
import {
CheckBoxStyled,
CheckBoxContainer,
FormControlLabelStyled,
} from "./CheckBox.styled";
import PropTypes from "prop-types";
import { Label } from "./Label";
import selectedTheme from "../../themes";

export const CheckBox = (props) => {
const [checked, setChecked] = useState(false);

const handleClick = () => {
if (props.onChange) props.onChange(!checked);
setChecked((prevState) => !prevState);
};

return (
<CheckBoxContainer
style={props.containerStyle}
fullWidth={props.fullWidth}
className={props.className}
>
<FormControlLabelStyled
fullWidth={props.fullWidth}
control={
<CheckBoxStyled
sx={props.checkBoxStyle}
boxcolor={props.color}
checked={props.value ? props.value : checked}
onClick={handleClick}
/>
}
label={
<Label
sx={props.labelStyle}
onClick={handleClick}
leftText={props.leftText}
rightText={props.rightText}
maxWidth={props.maxWidth}
/>
}
/>
</CheckBoxContainer>
);
};

CheckBox.propTypes = {
fullWidth: PropTypes.bool,
color: PropTypes.string,
name: PropTypes.string,
leftText: PropTypes.string,
rightText: PropTypes.string,
maxWidth: PropTypes.string,
value: PropTypes.bool,
onChange: PropTypes.func,
containerStyle: PropTypes.any,
checkBoxStyle: PropTypes.any,
labelStyle: PropTypes.any,
className: PropTypes.string,
};

CheckBox.defaultProps = {
color: selectedTheme.primaryPurple,
};

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

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

export const CheckBoxContainer = styled(Box)`
${props => props.fullWidth && (`
width: 100%;
display: flex;
flex: 1;
`)}
`

export const CheckBoxStyled = styled(Checkbox)`
color: ${props => props.boxcolor} !important;
padding: 6px;
`
export const FormControlLabelStyled = styled(FormControlLabel)`
${props => props.fullWidth && (`
width: 100%;
display: flex;
flex: 1;
`)}
margin-right: 0;
& span:nth-child(2) {
flex: 1;
}
`

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

@@ -0,0 +1,19 @@
import React from "react";
import { LabelContainer, LeftLabel, RightLabel } from "./Label.styled";
import PropTypes from "prop-types";

export const Label = (props) => {
return (
<LabelContainer onClick={props.onClick} maxWidth={props.maxWidth}>
<LeftLabel>{props.leftText}</LeftLabel>
{props.rightText && <RightLabel>{props.rightText}</RightLabel>}
</LabelContainer>
);
};

Label.propTypes = {
onClick: PropTypes.func,
leftText: PropTypes.string,
rightText: PropTypes.string,
maxWidth: PropTypes.string,
};

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

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

export const LabelContainer = styled(Box)`
display: flex;
flex: 1;
justify-content: space-between;
max-width: ${props => props.maxWidth};
`

export const LeftLabel = styled(FormLabel)`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 200px;
flex: 1;
cursor: pointer;
`
export const RightLabel = styled(FormLabel)`
margin-left: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 100px;
cursor: pointer;
`

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

@@ -0,0 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import { DropdownItemContainer, DropdownItemStyled } from './DropdownItem.styled'

const DropdownItem = (props) => {
return (
<DropdownItemContainer onClick={props.onClick}>
<DropdownItemStyled>
{props.children}
</DropdownItemStyled>
</DropdownItemContainer>
)
}

DropdownItem.propTypes = {
children: PropTypes.node,
onClick: PropTypes.func,
}

export default DropdownItem;

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

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

export const DropdownItemContainer = styled(Box)`
`

export const DropdownItemStyled = styled(Box)`
`

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

@@ -0,0 +1,59 @@
import React, { useState } from "react";
import {
DropdownListContainer,
DropdownHeader,
DropdownIcon,
DropdownTitle,
ListContainer,
ToggleIconClosed,
ToggleIconOpened,
} from "./DropdownList.styled";
import PropTypes from "prop-types";

const DropdownList = (props) => {
const [listShown, setListShown] = useState(props.defaultOpen);
return (
<DropdownListContainer fullWidth={props.fullWidth}>
<DropdownHeader>
{props.dropdownIcon && (
<DropdownIcon>{props.dropdownIcon}</DropdownIcon>
)}
<DropdownTitle onClick={() => setListShown((prevState) => !prevState)}>
{props.title}
</DropdownTitle>
{listShown ? (
<ToggleIconOpened
onClick={() => setListShown((prevState) => !prevState)}
>
{props.toggleIconOpened}
</ToggleIconOpened>
) : (
<ToggleIconClosed
onClick={() => setListShown((prevState) => !prevState)}
>
{props.toggleIconClosed}
</ToggleIconClosed>
)}
</DropdownHeader>

<ListContainer shouldShow={listShown}>{props.children}</ListContainer>
</DropdownListContainer>
);
};

export default DropdownList;

DropdownList.propTypes = {
title: PropTypes.string,
dropdownIcon: PropTypes.node,
toggleIconOpened: PropTypes.node,
toggleIconClosed: PropTypes.node,
children: PropTypes.node,
fullWidth: PropTypes.bool,
defaultOpen: PropTypes.bool
};

DropdownList.defaultProps = {
fullWidth: false,
defaultOpen: true
};

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

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

export const DropdownListContainer = styled(Box)`

width: ${props => props.fullWidth ? '100%' : (props.width ? props.width : '250px')};
padding: 8px;
`

export const DropdownTitle = styled(Typography)`
display: flex;
flex: 1;
cursor: pointer;
padding-left: 9px;
font-size: 18px;
font-weight: 100;
padding-bottom: 10px;
`

export const ToggleIconOpened = styled(Icon)`
cursor: pointer;
color: ${selectedTheme.primaryPurple};
`

export const ToggleIconClosed = styled(Icon)`
cursor: pointer;
color: ${selectedTheme.primaryPurple};
`

export const DropdownIcon = styled(Icon)`
font-size: 24px !important;

& span {
font-size: 24px;
& svg {
font-size: 24px;
}
}
`

export const ListContainer = styled(Box)`
padding-left: 15px;
display: ${props => props.shouldShow ? "block" : "none"};
`

export const DropdownHeader = styled(Box)`
display: flex;
flex-direction: row;
`

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

@@ -0,0 +1,25 @@
import React from 'react';
import { IconContainer, IconStyled } from './Icon.styled';
import PropTypes from "prop-types";


export const Icon = (props) => {
return (
<IconContainer style={props.containerStyle} className={props.className} onClick={props.onClick}>
<IconStyled sx={props.style} color={props.color} size={props.size} fontSize={props.iconsize}>
{props.children}
</IconStyled>
</IconContainer>
)
}

Icon.propTypes = {
children: PropTypes.node,
containerStyle: PropTypes.any,
style: PropTypes.any,
color: PropTypes.string,
size: PropTypes.string,
iconsize: PropTypes.string,
className: PropTypes.any,
onClick: PropTypes.func,
}

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

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

export const IconContainer = styled(Box)`
`

export const IconStyled = styled(Icon)`
color: ${props => props.color};
width: ${props => props.size};
height: ${props => props.size};
`

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

@@ -0,0 +1,25 @@
import React from 'react'
import PropTypes from 'prop-types';
import { LinkStyled } from './Link.styled';

const Link = props => {
return (
<LinkStyled {...props} href={props.href}>{props.children}</LinkStyled>
)
}

Link.propTypes = {
href: PropTypes.string,
children: PropTypes.node,
font: PropTypes.string,
align: PropTypes.oneOf(["left", "right", "center"]),
textsize: PropTypes.string,
lineheight: PropTypes.string,
}
Link.defaultProps = {
font: "Poppins",
align: "left",
textsize: "14px"
}

export default Link

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

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

export const LinkStyled = styled(Link)`
color: ${selectedTheme.primaryPurple};
font-family: ${(props) => props.font};
font-style: normal;
font-weight: 400;
font-size: ${props => props.textsize ? props.textsize : "14px"};
line-height: ${props => props.lineheight ? props.lineheight : "14px"};
text-decoration-line: underline;
display: block;
text-align: ${props => props.align === "right" ? "right" : (props.align === "center" ? "center" : "left")};
/* ${props => props.align === "right" && "display: block; text-align: right;"}
${props => props.align === "center" && "display: block; text-align: center;"} */
`;

+ 5
- 3
src/components/Loader/FullPageLoader.js Просмотреть файл

@@ -1,10 +1,12 @@
import React from 'react';
import {ReactComponent as Logo} from "../../assets/images/svg/big-logo-vertical.svg";
import { FullPageLoaderContainer } from './FullPageLoader.styled';

const FullPageLoader = () => {
return (
<div className="c-loader c-loader--page">
<div className="c-loader__icon" />
</div>
<FullPageLoaderContainer>
<Logo />
</FullPageLoaderContainer>
);
};


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

@@ -0,0 +1,10 @@

import { Container } from "@mui/material";
import styled from "styled-components";

export const FullPageLoaderContainer = styled(Container)`
height: 100%;
width: 100vw;
padding-top: 250px;
text-align: center;
`

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

@@ -0,0 +1,43 @@
import React from "react";
import PropTypes from "prop-types";
import { StepProgressContainer, Progress, StepBar, StepLine } from "./StepProgress.styled";
import { ReactComponent as Checkmark } from "../../assets/images/svg/checkmark.svg";

const StepProgress = (props) => {
const steps = [];
for (let i = 1; i <= props.numberOfSteps; i++) {
steps.push({
done: i < props.current,
current: i === props.current,
});
}
return (
<StepProgressContainer done>
{steps.map((item, index) =>
index === 0 ? (
<StepBar current={item.current} done={item.done} key={index}>
{item.done ? <Checkmark /> : index+1}
</StepBar>
) : (
<React.Fragment key={index}>
<StepLine done={item.done || item.current} >
<Progress done={item.done || item.current} />
</StepLine>
<StepBar current={item.current} done={item.done}>
{item.done ? <Checkmark /> : index+1}
</StepBar>
</React.Fragment>
)
)}
</StepProgressContainer>
);
};

StepProgress.propTypes = {
children: PropTypes.node,
handleNext: PropTypes.node,
current: PropTypes.number,
numberOfSteps: PropTypes.number,
};

export default StepProgress;

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

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

export const StepProgressContainer = styled(Box)`
display: flex;
height: 35px;
flex-direction: row;
position: relative;
left: 2px;
width: 100%;
`;

export const StepLine = styled(Box)`
margin-top: 13px;
background-color: white;
width: 100%;
margin-left: -1px;
height: 9px;
`;

export const StepBar = styled(Box)`
flex: 0 0 35px;
background-color: ${(props) =>
props.done ? selectedTheme.primaryPurple : selectedTheme.primaryDarkGrayText};
border-radius: 100%;
font-family: "Open Sans";
text-align: center;
border: 5px solid
${(props) => (props.current || props.done ? selectedTheme.primaryPurple : "white")};
padding-top: 2px;
line-height: 19px;
margin-left: -2px;
font-size: 14px;
color: #1d1d1d;
z-index: 1;
transition: background-color 1s ease;
`;
export const Progress = styled(Box)`
height: 9px;
width: ${(props) => (props.done ? "100%" : "0")};
background-color: ${selectedTheme.primaryPurple};
transition: width 1s;
`;

Двоичные данные
src/components/Styles/fonts/Mulish-Regular.ttf Просмотреть файл


Двоичные данные
src/components/Styles/fonts/OpenSans-Regular.ttf Просмотреть файл


Двоичные данные
src/components/Styles/fonts/Poppins-Regular.ttf Просмотреть файл


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

@@ -0,0 +1,29 @@
import { createGlobalStyle } from 'styled-components';
// import OpenSans from "./fonts/OpenSans-Regular.ttf"
// import Poppins from "./fonts/Poppins-Regular.ttf"
// import Mulish from "./fonts/Mulish-Regular.ttf"
const GlobalStyle = createGlobalStyle`
${'' /* @font-face {
font-family: 'Open Sans';
src: url(${OpenSans}) format('truetype');
font-weight: 400;
font-style: normal;
font-display: auto;
}
@font-face {
font-family: 'Poppins';
src: url(${Poppins}) format('truetype');
font-weight: 400;
font-style: normal;
font-display: auto;
}
@font-face {
font-family: "Mulish";
src: url(${Mulish}) format('truetype');
font-weight: 400;
font-style: normal;
font-display: auto;
} */}
`;

export default GlobalStyle;

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

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

const backgroundColor = `rgb(241, 241, 241)`;

export const ComponentContainer = styled.div`
width: 100%;
`;

export const TextFieldMUIStyled = styled(TextField)`
background-color: ${backgroundColor};
width: ${(props) => props.width};
font-style: ${(props) => (props.italic === true ? "italic" : "normal")};
`;

src/components/TextFields/TextField.js → src/components/TextFields/TextField/TextField.js Просмотреть файл

@@ -1,11 +1,11 @@
import React, { useEffect, useState } from "react";
import { ComponentContainer, TextFieldMUIStyled } from "./TextField.styled";
import { TextFieldContainer, TextFieldStyled } from "./TextField.styled";
import PropTypes from "prop-types";

export const TextField = (props) => {
const [isFieldEmpty, setIsFieldEmpty] = useState(true);

//for italicPlaceholder
// for italicPlaceholder
useEffect(() => {
if (props.value.length === 0) {
setIsFieldEmpty(true);
@@ -15,14 +15,29 @@ export const TextField = (props) => {
}, [props.value]);

return (
<ComponentContainer style={props.containerStyle}>
<TextFieldMUIStyled
{...props}
<TextFieldContainer style={props.containerStyle} className={props.className}>
<TextFieldStyled
placeholder={props.placeholder}
width={props.width}
height={props.height}
name={props.name}
value={props.value}
onChange={props.onChange}
error={props.error}
// helperText={props.helperText}
autoFocus={props.autoFocus}
fullWidth={props.fullWidth}
type={props.type}
textsize={props.textsize}
font={props.font}
InputProps={props.InputProps}
sx={props.style}
label={props.showAnimation ? props.placeholder : ""}
italic={props.italicPlaceholder && isFieldEmpty}
/>
</ComponentContainer>
>
{props.children}
</TextFieldStyled>
</TextFieldContainer>
);
};

@@ -34,6 +49,8 @@ TextField.propTypes = {
pathname: PropTypes.string,
}),
}),
children: PropTypes.node,
className: PropTypes.string,
placeholder: PropTypes.string,
style: PropTypes.any,
showAnimation: PropTypes.bool,
@@ -43,19 +60,24 @@ TextField.propTypes = {
height: PropTypes.string,
name: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
onChange: PropTypes.func,
error: PropTypes.string,
error: PropTypes.bool,
helperText: PropTypes.string,
autoFocus: PropTypes.bool,
fullWidth: PropTypes.bool,
type: PropTypes.string,
InputProps: {
textsize: PropTypes.string,
font: PropTypes.string,
InputProps: PropTypes.shape({
startAdornment: PropTypes.node,
endAdornment: PropTypes.node,
},
style: PropTypes.any,
}),
};

TextField.defaultProps = {
italicPlaceholder: false,
showAnimation: false,
// font: "Open Sans"
};

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

@@ -0,0 +1,31 @@
import { Box, TextField } from "@mui/material";
import styled from "styled-components";
import { PRIMARY_BACKGROUND_COLOR } from "../../../constants/stylesConstants";

export const TextFieldContainer = styled(Box)`
width: 100%;
height: 48px;
box-sizing: border-box;
margin: 16px 0;
padding-left: 0;
`;

export const TextFieldStyled = styled(TextField)`
background-color: ${PRIMARY_BACKGROUND_COLOR};
width: ${(props) => props.width};
font-style: ${(props) => (props.italic === true ? "italic" : "normal")};
padding-left: 0;
margin: 0;
padding: 0;
height: 100%;
box-sizing: border-box;
& div {
padding-left: 2px;
}
& div input {
height: 48px;
box-sizing: border-box;
font-size: ${props => props.textsize ? props.textsize : "16px"} !important;
font-family: ${props => props.font ? props.font : ""}
}
`;

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

@@ -0,0 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
import { TextFieldWithIconContainer, IconStyled, TextFieldStyled } from './TextFieldWithIcon.styled';
import { Visibility } from '@mui/icons-material';

const TextFieldWithIcon = (props) => {
return (
<TextFieldWithIconContainer>
<TextFieldStyled {...props.textFieldProps}>
<IconStyled color="green">
<Visibility color="green"/>
</IconStyled>
{props.children}
</TextFieldStyled>
</TextFieldWithIconContainer>
)
}

TextFieldWithIcon.propTypes = {
children: PropTypes.node,
textFieldProps: PropTypes.any,
}

export default TextFieldWithIcon;

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

@@ -0,0 +1,18 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import { Icon } from "../../Icon/Icon";
import { TextField } from "../TextField/TextField";

export const TextFieldWithIconContainer = styled(Box)`
`

export const TextFieldStyled = styled(TextField)`
position: relative;
`

export const IconStyled = styled(Icon)`
position: absolute;
top: 5px;
left: 5px;
background-color: blue;
`

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

@@ -3,4 +3,7 @@ export const LOGIN_PAGE = '/login';
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 NOT_FOUND_PAGE = '/not-found';
export const FORGOT_PASSWORD_MAIL_SENT = '/forgot-password/mail-sent'
export const REGISTER_PAGE = "/register"
export const REGISTER_SUCCESSFUL_PAGE = "/register/success";

+ 0
- 2
src/constants/stylesConstants.js Просмотреть файл

@@ -1,2 +0,0 @@
export const PRIMARY_PURPLE_COLOR = `rgb(90, 57, 131)`;
export const PRIMARY_YELLOW_COLOR = `rgb(247, 178, 38)`;

+ 7
- 3
src/i18n/index.js Просмотреть файл

@@ -3,13 +3,17 @@ import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import enTranslations from './resources/en';
import rsTranslations from './resources/rs'

i18n.use(initReactI18next).init({
lng: 'en',
fallbackLng: 'en',
lng: 'rs',
fallbackLng: 'rs',
debug: false,
supportedLngs: ['en'],
supportedLngs: ['rs', 'en'],
resources: {
rs: {
translation: rsTranslations,
},
en: {
translation: enTranslations,
},

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

@@ -0,0 +1,106 @@
export default {
app: {
title: 'Trampa'
},
refresh: {
title: 'Jel si aktivan?',
cta:
"You were registered as not active, please confirm that you are active in the next minute, if you don't you will be logged out.",
},
common: {
close: 'Zatvori',
send: "Pošalji",
sendAgain: "Pošalji ponovo.",
trademark: 'TM',
search: 'Pretraga',
error: 'Greška',
continue: 'Nastavi',
labelUsername: 'Username',
labelEmail: 'Email',
labelPassword: 'Lozinka',
labelFirm: "Ime Firme",
labelPIB: "PIB",
labelPhone: "Telefon",
labelLocation: "Lokacija",
labelWebsite: "Adresa Websajta",
next: 'Sledeće',
nextPage: 'Sledeća strana',
previousPage: 'Prethodna strana',
back: 'Nazad',
goBack: 'Idi nazad',
ok: 'Ok',
done: 'Gotovo',
confirm: 'Potvrdi',
printDownload: 'Print/Download',
cancel: 'Obustavi',
remove: 'Izbriši',
invite: 'Pozovi',
save: 'Sačuvaj',
complete: 'Završi',
download: 'Download',
yes: 'Da',
no: 'Ne',
to: 'do',
select: 'Izaberi...',
none: 'Ni jedan',
date: {
range: '{{start}} do {{end}}',
},
},
login: {
welcome: 'React template',
welcomeText: 'Trampa sa kolegama na dohvat ruke',
dontHaveAccount: "Nemate nalog? ",
emailFormat: 'Nevalidan format email adrese!',
emailRequired: 'Email adresa je obavezna!',
noUsers: 'Ne postoji korisnik sa zadatom email adresom.',
passwordStrength: 'Your password is {{strength}}.',
passwordLength: 'Lozinka mora imati izmedju 8 i 50 karaktera!',
signUpRecommendation: 'Registrujte se.',
email: 'Unesite email adresu kako biste se prijavili',
logInTitle: 'Uloguj se',
logIn: 'Uloguj se',
signUp: 'Registrujte se.',
usernameRequired: 'Username je obavezan!',
passwordRequired: 'Lozinka je obavezna!',
forgotYourPassword: 'Zaboravili ste lozinku?',
forgotPasswordEmail:'Email',
useDifferentEmail: 'Iskoristite drugačiju lozinku.',
},
password: {
weak: 'slaba',
average: 'srednja',
good: 'dobra',
strong: 'jaka',
},
register: {
title: "Registruj se",
descriptionMain: "Trampa sa kolegama na dohvat ruke",
descriptionFirst: "Email i Lozinka biće Vam primarni način da se ulogujete u aplikaciju",
descriptionSecond: 'Ovaj korak nije obavezan za razgledanje artikla ali za proces trampe je obavezan. Uvek možete popuniti ova polja u podešavanjima naloga kasnije',
descriptionThird: 'Ovaj korak nije obavezan za razgledanje artikla ali za proces trampe je obavezan. Uvek možete popuniti ova polja u podešavanjima naloga kasnije',
loginText: "Već posedujete nalog?",
login: "Ulogujte se.",
acceptTerms: `Pri klikom na dugme "Registruj se", prihvatate naše`,
terms: "Uslove Korišćenja",
success: 'Registracija Uspešna',
welcome: 'Dobro došli na trampu, želimo vam uspešno trampovanje!'
},
forgotPassword: {
title: 'Povrati lozinku',
description: 'Molimo vas unesite email sa koji cemo vam poslati link za povratak lozinke',
label: 'Pošalji email',
emailRequired: 'Email je obavezan!',
emailFormat: 'Nevalidan format email adrese!',
mailSent: "E-Mail poslat!",
mailSentDescription: "Poslat vam je email sa instrukcijama kako da resetujete lozinku",
notRecievedMail: "Niste dobili email?",
checkSpam: "U slučaju da Vam ne stigne email, pogledajte <strong>Spam</strong> folder email provajdera",
forgotPassword: {
title: 'Zaboravili ste lozinku',
subtitle:
'Odgovorite na tajno pitanje kako biste povratili svoj nalog: ',
label: 'Obnovite lozinku',
},
},
}

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

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

export const ForgotPasswordPageContainer = styled(Container)`
margin-top: 200px;
display: flex;
flex-direction: column;
align-items: center;
`;
export const ForgotPasswordTitle = styled(Typography)`
font-family: "Open Sans";
width: 328px;
height: 33px;
text-align: center;
flex: 1;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 33px;
color: ${selectedTheme.primaryPurple};
margin-top: 36px;
`;
export const ForgotPasswordDescription = styled(Typography)`
font-family: "Open Sans";
margin-top: 9px;
width: 221px;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 22px;
display: flex;
align-items: center;
text-align: center;
color: ${selectedTheme.primaryGrayText};
margin-bottom: 20px;
`;
export const FormContainer = styled(Box)`
width: 335px;
height: 216px;
`;

+ 86
- 0
src/pages/ForgotPasswordPage/ForgotPasswordMailSent/MailSent.js Просмотреть файл

@@ -0,0 +1,86 @@
import React from "react";
import PropTypes from "prop-types";
import {
MailSentContainer,
Description,
Footer,
FooterText,
FormContainer,
SendAgainTextContainer,
StandardText,
Title,
} from "./MailSent.styled";
import { ReactComponent as MailSentImage } from "../../../assets/images/svg/mail-sent.svg";
import { PrimaryButton } from "../../../components/Buttons/PrimaryButton/PrimaryButton";
import { NavLink, useHistory } from "react-router-dom";
import Link from "../../../components/Link/Link";
import { Trans, useTranslation } from "react-i18next";
import { LOGIN_PAGE } from "../../../constants/pages";
import selectedTheme from "../../../themes";

const MailSent = () => {
const { t } = useTranslation();
const history = useHistory();

const navigateLogin = () => {
history.replace(LOGIN_PAGE);
};

return (
<MailSentContainer>

<MailSentImage />

<Title component="h1" variant="h5">
{t("forgotPassword.mailSent")}
</Title>

<Description component="h1" variant="h6">
{t("forgotPassword.mailSentDescription")}
</Description>

<FormContainer>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
onClick={navigateLogin}
>
{t("login.logIn")}
</PrimaryButton>

<SendAgainTextContainer>

<StandardText>
{t("forgotPassword.notRecievedMail")}
</StandardText>

<Link to="#" component={NavLink} underline="hover" align="center" textsize="16px">
{t("common.sendAgain")}
</Link>

</SendAgainTextContainer>

</FormContainer>

<Footer>

<FooterText>
<Trans i18nKey="forgotPassword.checkSpam" />
</FooterText>

</Footer>
</MailSentContainer>
);
};

MailSent.propTypes = {
children: PropTypes.node,
};

export default MailSent;

+ 71
- 0
src/pages/ForgotPasswordPage/ForgotPasswordMailSent/MailSent.styled.js Просмотреть файл

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

export const MailSentContainer = styled(Container)`
margin-top: 300px;
display: flex;
flex-direction: column;
align-items: center;
`;
export const Title = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
width: 328px;
height: 33px;
text-align: center;
flex: 1;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 33px;
color: ${selectedTheme.primaryPurple};
margin-top: 6px;
`;
export const Description = styled(Typography)`
font-family: "Open Sans";
margin-top: 9px;
width: 279px;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 22px;
display: flex;
align-items: center;
text-align: center;
color: ${selectedTheme.primaryGrayText};
margin-bottom: 36px;
`;
export const FormContainer = styled(Box)`
width: 335px;
height: 216px;
`;
export const StandardText = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
font-size: 16px;
padding-right: 6px;
line-height: 14px;
text-align: center;
`
export const SendAgainTextContainer = styled(Box)`
display: flex;
flex-direction: row;
margin-top: 36px;
justify-content: center;
`
export const Footer = styled(Box)`
position: absolute;
bottom: 36px;
display: flex;
width: 100%;
flex-direction: row;
justify-content: center;
`
export const FooterText = styled(StandardText)`
width: 340px;
line-height: 22px;
font-weight: 400;
padding: 0;
font-size: 16px;
`

+ 75
- 84
src/pages/ForgotPasswordPage/ForgotPasswordPageMUI.js Просмотреть файл

@@ -1,96 +1,87 @@
import React from 'react';
import { useFormik } from 'formik';
import { useTranslation } from 'react-i18next';
import * as Yup from 'yup';
import i18next from 'i18next';
import React from "react";
import { useFormik } from "formik";
import { useTranslation } from "react-i18next";
import * as Yup from "yup";
import i18next from "i18next";
import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg";
import {
Box,
Container,
Typography,
Button,
TextField,
Link,
Grid,
} from '@mui/material';
import Backdrop from '../../components/MUI/BackdropComponent';
import { LOGIN_PAGE } from '../../constants/pages';
import { NavLink } from 'react-router-dom';
ForgotPasswordPageContainer,
ForgotPasswordDescription,
ForgotPasswordTitle,
FormContainer,
} from "./ForgotPassword.styled";
import { TextField } from "../../components/TextFields/TextField/TextField";
import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton";
import { useHistory } from "react-router-dom";
import { FORGOT_PASSWORD_MAIL_SENT } from "../../constants/pages";
import selectedTheme from "../../themes";

const forgotPasswordValidationSchema = Yup.object().shape({
email: Yup.string()
.required(i18next.t('forgotPassword.emailRequired'))
.email(i18next.t('forgotPassword.emailFormat')),
email: Yup.string()
.required(i18next.t("forgotPassword.emailRequired"))
.email(i18next.t("forgotPassword.emailFormat")),
});

const ForgotPasswordPage = () => {
const { t } = useTranslation();
const history = useHistory();
const { t } = useTranslation();

const handleSubmit = (values) => {
console.log('Values', values);
};
const handleSubmit = (values) => {
console.log("Values", values);
history.push(FORGOT_PASSWORD_MAIL_SENT);
};

const formik = useFormik({
initialValues: {
email: '',
},
validationSchema: forgotPasswordValidationSchema,
onSubmit: handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});
const formik = useFormik({
initialValues: {
email: "",
},
validationSchema: forgotPasswordValidationSchema,
onSubmit: handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});

return (
<Container component="main" maxWidth="md">
<Box
sx={{
marginTop: 32,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Typography component="h1" variant="h5">
{t('forgotPassword.title')}
</Typography>
<Box
component="form"
onSubmit={formik.handleSubmit}
sx={{ position: 'relative', mt: 1, p: 1 }}
>
<Backdrop position="absolute" isLoading={false} />
<TextField
name="email"
label={t('login.forgotPasswordEmail')}
margin="normal"
value={formik.values.email}
onChange={formik.handleChange}
error={formik.touched.email && Boolean(formik.errors.email)}
helperText={formik.touched.email && formik.errors.email}
autoFocus
fullWidth
/>
<Button
type="submit"
variant="contained"
sx={{ mt: 3, mb: 2 }}
fullWidth
>
{t('forgotPassword.label')}
</Button>
<Grid container justifyContent="center">
<Link
to={LOGIN_PAGE}
component={NavLink}
variant="body2"
underline="hover"
>
{t('common.back')}
</Link>
</Grid>
</Box>
</Box>
</Container>
);
return (
<ForgotPasswordPageContainer>
<Logo />

<ForgotPasswordTitle component="h1" variant="h5">
{t("forgotPassword.title")}
</ForgotPasswordTitle>

<ForgotPasswordDescription component="h1" variant="h6">
{t("forgotPassword.description")}
</ForgotPasswordDescription>

<FormContainer component="form" onSubmit={formik.handleSubmit}>
{/* <Backdrop position="absolute" isLoading={isLoading} /> */}

<TextField
name="email"
placeholder={t("common.labelEmail")}
margin="normal"
value={formik.values.email}
error={formik.touched.email && Boolean(formik.errors.email)}
helperText={formik.touched.email && formik.errors.email}
onChange={formik.handleChange}
autoFocus
fullWidth
/>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
disabled={formik.values.email?.length === 0}
>
{t("common.send")}
</PrimaryButton>
</FormContainer>
</ForgotPasswordPageContainer>
);
};

export default ForgotPasswordPage;

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

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

export const LoginPageContainer = styled(Container)`
margin-top: 150px;
display: flex;
flex-direction: column;
align-items: center;
`;
export const LoginTitle = styled(Typography)`
font-family: "Open Sans";
width: 328px;
height: 33px;
text-align: center;
flex: 1;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 33px;
color: ${selectedTheme.primaryPurple};
margin-top: 36px;
`;
export const LoginDescription = styled(Typography)`
font-family: "Open Sans";
margin-top: 9px;
width: 221px;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 22px;
display: flex;
align-items: center;
text-align: center;
color: ${selectedTheme.primaryGrayText};
margin-bottom: 20px;
`;
export const LoginFormContainer = styled(Box)`
width: 335px;
height: 216px;
`;
export const RegisterAltText = styled(Typography)`
font-family: "Poppins";
color: ${selectedTheme.primaryText};
font-size: 14px;
padding-right: 6px;
line-height: 14px;
`
export const RegisterTextContainer = styled(Box)`
display: flex;
flex-direction: row;
margin-top: 36px;
justify-content: center;
`

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

@@ -1,36 +1,36 @@
/* eslint-disable */
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { useFormik } from "formik";
import { useDispatch, useSelector } from "react-redux";
import { NavLink } from "react-router-dom";
import * as Yup from "yup";
import { useTranslation } from "react-i18next";
import i18next from "i18next";
import {
clearLoginErrors,
fetchUser,
} from "../../store/actions/login/loginActions";
import { selectLoginError } from "../../store/selectors/loginSelectors";
import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages";
import {
Box,
Button,
Container,
Grid,
IconButton,
InputAdornment,
Link,
Typography,
} from "@mui/material";
import { Visibility, VisibilityOff } from "@mui/icons-material";
import { ReactComponent as VisibilityOn } from "../../assets/images/svg/VisibilityOn.svg";
import { ReactComponent as VisibilityOff } from "../../assets/images/svg/VisibilityOff.svg";
import Backdrop from "../../components/MUI/BackdropComponent";
import ErrorMessage from "../../components/MUI/ErrorMessageComponent";
import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
import { LOGIN_USER_LOADING } from "../../store/actions/login/loginActionConstants";
import { TextField } from "../../components/TextFields/TextField";
import { TextField } from "../../components/TextFields/TextField/TextField";
import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton";
import { PRIMARY_PURPLE_COLOR } from "../../constants/stylesConstants";
import { IconButton } from "../../components/Buttons/IconButton/IconButton";
import Link from "../../components/Link/Link";
import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg";
import {
LoginPageContainer,
LoginTitle,
LoginDescription,
LoginFormContainer,
RegisterAltText,
RegisterTextContainer,
} from "./Login.styled";
import selectedTheme from "../../themes";

const LoginPage = ({ history }) => {
const dispatch = useDispatch();
@@ -92,105 +92,100 @@ const LoginPage = ({ history }) => {
});

return (
<Container component="main" maxWidth="md">
<Box
sx={{
marginTop: 32,
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography component="h1" variant="h5">
{t("login.logInTitle")}
</Typography>
{error && <ErrorMessage error={error} />}
<Box
component="form"
onSubmit={formik.handleSubmit}
sx={{ position: "relative", mt: 1, p: 1 }}
<LoginPageContainer>
<Logo />

<LoginTitle component="h1" variant="h5">
{t("login.logInTitle")}
</LoginTitle>

<LoginDescription component="h1" variant="h6">
{t("login.welcomeText")}
</LoginDescription>

<LoginFormContainer component="form" onSubmit={formik.handleSubmit}>
<Backdrop position="absolute" isLoading={isLoading} />

<TextField
name="username"
placeholder={t("common.labelEmail")}
margin="normal"
value={formik.values.username}
onChange={formik.handleChange}
error={formik.touched.username && Boolean(formik.errors.username)}
helperText={formik.touched.username && formik.errors.username}
autoFocus
fullWidth
/>

<TextField
name="password"
placeholder={t("common.labelPassword")}
margin="normal"
type={showPassword ? "text" : "password"}
value={formik.values.password}
onChange={formik.handleChange}
error={formik.touched.password && Boolean(formik.errors.password)}
helperText={formik.touched.password && formik.errors.password}
fullWidth={true}
InputProps={{
endAdornment: (
<IconButton
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <VisibilityOn /> : <VisibilityOff />}
</IconButton>
),
}}
/>

<Link
to={FORGOT_PASSWORD_PAGE}
textsize="12px"
component={NavLink}
underline="hover"
align="right"
style={{ marginTop: "18px", marginBottom: "18px" }}
>
<Backdrop position="absolute" isLoading={isLoading} />
<TextField
name="username"
placeholder={t("common.labelUsername")}
margin="normal"
value={formik.values.username}
onChange={formik.handleChange}
error={formik.touched.username && Boolean(formik.errors.username)}
helperText={formik.touched.username && formik.errors.username}
autoFocus
fullWidth
/>
<TextField
name="password"
placeholder={t("common.labelPassword")}
margin="normal"
type={showPassword ? "text" : "password"}
value={formik.values.password}
onChange={formik.handleChange}
error={formik.touched.password && Boolean(formik.errors.password)}
helperText={formik.touched.password && formik.errors.password}
fullWidth
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
),
}}
/>
<PrimaryButton
type="submit"
variant="contained"
height="40px"
sx={{ mt: 3, mb: 2 }}
fullWidth
buttonColor={PRIMARY_PURPLE_COLOR}
textColor="white"
{t("login.forgotYourPassword")}
</Link>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
disabled={
formik.values.username.length === 0 ||
formik.values.password.length === 0
}
>
{t("login.logIn")}
</PrimaryButton>

<RegisterTextContainer>

<RegisterAltText>
{t("login.dontHaveAccount").padEnd(2, " ")}
</RegisterAltText>

<Link
to="/register"
component={NavLink}
underline="hover"
align="center"
>
{t("login.logIn")}
</PrimaryButton>
<Grid container>
<Grid
item
xs={12}
md={6}
sx={{ textAlign: { xs: "center", md: "left" } }}
>
<Link
to={FORGOT_PASSWORD_PAGE}
component={NavLink}
variant="body2"
underline="hover"
>
{t("login.forgotYourPassword")}
</Link>
</Grid>
<Grid
item
xs={12}
md={6}
sx={{ textAlign: { xs: "center", md: "right" } }}
>
<Link
to="#"
component={NavLink}
variant="body2"
underline="hover"
>
{t("login.dontHaveAccount")}
</Link>
</Grid>
</Grid>
</Box>
</Box>
</Container>
{t("login.signUp")}
</Link>

</RegisterTextContainer>

</LoginFormContainer>

</LoginPageContainer>
);
};


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

@@ -0,0 +1,108 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
FormContainer,
RegisterDescription,
} from "./FirstPartOfRegistration.styled";
import { useFormik } from "formik";
import * as Yup from "yup";
import { useTranslation } from "react-i18next";
import { TextField } from "../../../../components/TextFields/TextField/TextField";
import { IconButton } from "../../../../components/Buttons/IconButton/IconButton";
import { ReactComponent as VisibilityOn } from "../../../../assets/images/svg/VisibilityOn.svg";
import { ReactComponent as VisibilityOff } from "../../../../assets/images/svg/VisibilityOff.svg";
import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton";
import selectedTheme from "../../../../themes";

const FirstPartOfRegistration = (props) => {
const [showPassword, setShowPassword] = useState(false);
const { t } = useTranslation();

const formik = useFormik({
initialValues: {
mail: "",
password: "",
},
validationSchema: Yup.object().shape({
mail: Yup.string().email().required(t("login.usernameRequired")),
password: Yup.string().required(t("login.passwordRequired")),
}),
onSubmit: props.handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});

const handleClickShowPassword = () => {
setShowPassword((prevState) => !prevState);
};
return (
<FormContainer component="form" onSubmit={formik.handleSubmit}>
<RegisterDescription component="p" variant="p">
{t("register.descriptionFirst")}
</RegisterDescription>

<TextField
name="mail"
placeholder={t("common.labelEmail")}
margin="normal"
value={formik.values.mail}
onChange={(value) =>
formik.setFieldValue("mail", value.target.value)
}
error={formik.touched.mail && Boolean(formik.errors.mail)}
helperText={formik.touched.mail && formik.errors.mail}
autoFocus
fullWidth
/>

<TextField
name="password"
placeholder={t("common.labelPassword")}
margin="normal"
type={showPassword ? "text" : "password"}
value={formik.values.password}
onChange={(value) =>
formik.setFieldValue("password", value.target.value)
}
error={
formik.touched.passwordRegistration &&
Boolean(formik.errors.passwordRegistration)
}
helperText={
formik.touched.passwordRegistration &&
formik.errors.passwordRegistration
}
fullWidth
InputProps={{
endAdornment: (
<IconButton onClick={handleClickShowPassword}>
{showPassword ? <VisibilityOn /> : <VisibilityOff />}
</IconButton>
),
}}
/>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
disabled={
formik.values.mail.length === 0 ||
formik.values.password.length === 0
}
>
{t("common.continue")}
</PrimaryButton>
</FormContainer>
);
};

FirstPartOfRegistration.propTypes = {
children: PropTypes.node,
handleSubmit: PropTypes.func,
};

export default FirstPartOfRegistration;

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

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

export const FormContainer = styled.form`
width: 335px;
`;
export const RegisterDescription = styled(Typography)`
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
display: flex;
align-items: center;
color: ${selectedTheme.primaryGrayText};
font-size: 12px;
width: 100%;
text-align: left;
line-height: 16px;
margin-top: 31px;
margin-bottom: 2px;
letter-spacing: 0.02em;
`;

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

@@ -0,0 +1,91 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
RegisterPageContainer,
Footer,
FooterText,
LoginAltText,
LoginTextContainer,
ProgressContainer,
RegisterDescription,
RegisterTitle,
} from "./Register.styled";
import { ReactComponent as Logo } from "../../../assets/images/svg/logo-vertical.svg";
import { NavLink, useHistory } from "react-router-dom";
import { Trans, useTranslation } from "react-i18next";
import Link from "../../../components/Link/Link";
import StepProgress from "../../../components/StepProgress/StepProgress";
import { REGISTER_SUCCESSFUL_PAGE } from "../../../constants/pages";
import FirstPartOfRegistration from "./FirstPart/FirstPartOfRegistration";
import SecondPartOfRegistration from "./SecondPart/SecondPartOfRegistration";
import ThirdPartOfRegistration from "./ThirdPart/ThirdPartOfRegistration";

const Register = () => {
const { t } = useTranslation();
const history = useHistory();
const [currentStep, setCurrentStep] = useState(1);
const [informations, setInformations] = useState({});

const handleSubmit = (values) => {
setInformations({ ...informations, ...values });
console.log({ ...informations, ...values });
if (currentStep !== 3) {
setCurrentStep((prevState) => prevState + 1);
} else {
history.push(REGISTER_SUCCESSFUL_PAGE);
}
};
return (
<RegisterPageContainer>
<Logo />

<RegisterTitle component="h1" variant="h5">
{t("register.title")}
</RegisterTitle>

<RegisterDescription component="h1" variant="h6">
{t("register.descriptionMain")}
</RegisterDescription>

<ProgressContainer>
<StepProgress current={currentStep} numberOfSteps={3} />
</ProgressContainer>

{currentStep === 1 && (
<FirstPartOfRegistration handleSubmit={handleSubmit} />
)}
{currentStep === 2 && (
<SecondPartOfRegistration handleSubmit={handleSubmit} />
)}
{currentStep === 3 && (
<ThirdPartOfRegistration handleSubmit={handleSubmit} />
)}

<LoginTextContainer>
<LoginAltText>{t("register.loginText")}</LoginAltText>

<Link to="/login" component={NavLink} underline="hover" align="center">
{t("register.login")}
</Link>
</LoginTextContainer>

<Footer>
<FooterText>
<Trans i18nKey="register.acceptTerms" />{" "}
<NavLink
to="#"
style={{ color: "black", fontWeight: "500", cursor: "pointer" }}
>
<Trans i18nKey="register.terms" />
</NavLink>
</FooterText>
</Footer>
</RegisterPageContainer>
);
};

Register.propTypes = {
children: PropTypes.node,
};

export default Register;

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

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

export const RegisterPageContainer = styled(Container)`
margin-top: 100px;
display: flex;
flex-direction: column;
align-items: center;
width: 335px;
padding: 0;
`;
export const RegisterTitle = styled(Typography)`
font-family: "Open Sans";
width: 328px;
height: 33px;
text-align: center;
flex: 1;
font-style: normal;
font-weight: 400;
font-size: 24px;
line-height: 33px;
color: ${selectedTheme.primaryPurple};
margin-top: 34px;
`;
export const RegisterDescription = styled(Typography)`
font-family: "Open Sans";
margin-top: 9px;
width: 221px;
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 22px;
display: flex;
align-items: center;
text-align: center;
color: ${selectedTheme.primaryGrayText};
margin-bottom: 20px;
`;
export const FormContainer = styled(Box)`
width: 335px;
`;
export const LoginAltText = styled(Typography)`
font-family: "Poppins";
color: ${selectedTheme.primaryText};
font-size: 14px;
padding-right: 6px;
line-height: 14px;
`
export const LoginTextContainer = styled(Box)`
display: flex;
flex-direction: row;
margin-top: 36px;
justify-content: center;
`
export const ProgressContainer = styled(Container)`
width: 100%;
padding: 0;
`
export const Footer = styled(Box)`
position: absolute;
bottom: 36px;
display: flex;
width: 100%;
flex-direction: row;
justify-content: center;
`
export const FooterText = styled(Typography)`
font-family: "Open Sans";
color: #505050;
text-align: center;
width: 330px;
line-height: 16px;
font-weight: 400;
padding: 0;
font-size: 12px;
`
export const RegisterDescriptionPart = styled(RegisterDescription)`
font-size: 12px;
width: 100%;
text-align: left;
line-height: 16px;
margin-top: 31px;
margin-bottom: 2px;
letter-spacing: 0.02em;
`

+ 83
- 0
src/pages/RegisterPages/Register/SecondPart/SecondPartOfRegistration.js Просмотреть файл

@@ -0,0 +1,83 @@
import React from "react";
import PropTypes from "prop-types";
import {
FormContainer,
RegisterDescription,
} from "./SecondPartOfRegistration.styled";
import { useFormik } from "formik";
import * as Yup from "yup";
import { useTranslation } from "react-i18next";
import { TextField } from "../../../../components/TextFields/TextField/TextField";
import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton";
import selectedTheme from "../../../../themes";

const SecondPartOfRegistration = (props) => {
const { t } = useTranslation();

const formik = useFormik({
initialValues: {
nameOfFirm: "",
PIB: "",
},
validationSchema: Yup.object().shape({
nameOfFirm: Yup.string().required(t("login.usernameRequired")),
PIB: Yup.number().required(t("login.passwordRequired")),
}),
onSubmit: props.handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});
return (
<FormContainer component="form" onSubmit={formik.handleSubmit}>
<RegisterDescription component="p" variant="p">
{t("register.descriptionSecond")}
</RegisterDescription>

<TextField
name="nameOfFirm"
placeholder={t("common.labelFirm")}
margin="normal"
value={formik.values.nameOfFirm}
onChange={formik.handleChange}
error={formik.touched.nameOfFirm && Boolean(formik.errors.nameOfFirm)}
helperText={formik.touched.nameOfFirm && formik.errors.nameOfFirm}
autoFocus
fullWidth
/>

<TextField
name="PIB"
placeholder={t("common.labelPIB")}
margin="normal"
type="number"
value={formik.values.PIB}
onChange={formik.handleChange}
error={formik.touched.PIB && Boolean(formik.errors.PIB)}
helperText={formik.touched.PIB && formik.errors.PIB}
fullWidth={true}
/>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
disabled={
formik.values.PIB.length === 0 ||
formik.values.nameOfFirm.length === 0
}
>
{t("common.continue")}
</PrimaryButton>
</FormContainer>
);
};

SecondPartOfRegistration.propTypes = {
children: PropTypes.node,
handleSubmit: PropTypes.func,
};

export default SecondPartOfRegistration;

+ 23
- 0
src/pages/RegisterPages/Register/SecondPart/SecondPartOfRegistration.styled.js Просмотреть файл

@@ -0,0 +1,23 @@
import { Typography } from "@mui/material";
import styled from "styled-components";
import { PRIMARY_GRAY_TEXT_COLOR } from "../../../../constants/stylesConstants";


export const FormContainer = styled.form`
width: 335px;
`;
export const RegisterDescription = styled(Typography)`
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
display: flex;
align-items: center;
color: ${PRIMARY_GRAY_TEXT_COLOR};
font-size: 12px;
width: 100%;
text-align: left;
line-height: 16px;
margin-top: 31px;
margin-bottom: 2px;
letter-spacing: 0.02em;
`;

+ 102
- 0
src/pages/RegisterPages/Register/ThirdPart/ThirdPartOfRegistration.js Просмотреть файл

@@ -0,0 +1,102 @@
import React from "react";
import PropTypes from "prop-types";
import {
FormContainer,
RegisterDescription,
} from "./ThirdPartOfRegistration.styled";
import { useFormik } from "formik";
import * as Yup from "yup";
import { useTranslation } from "react-i18next";
import { TextField } from "../../../../components/TextFields/TextField/TextField";
import { PrimaryButton } from "../../../../components/Buttons/PrimaryButton/PrimaryButton";
import selectedTheme from "../../../../themes";

const ThirdPartOfRegistration = (props) => {
const { t } = useTranslation();

const formik = useFormik({
initialValues: {
phoneNumber: "",
location: "",
website: "",
},
validationSchema: Yup.object().shape({
phoneNumber: Yup.number().required(t("login.usernameRequired")),
location: Yup.string().required(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
),
}),
onSubmit: props.handleSubmit,
validateOnBlur: true,
enableReinitialize: true,
});

return (
<FormContainer component="form" onSubmit={formik.handleSubmit}>
<RegisterDescription component="p" variant="p">
{t("register.descriptionThird")}
</RegisterDescription>

<TextField
name="phoneNumber"
placeholder={t("common.labelPhone")}
margin="normal"
type="number"
value={formik.values.phoneNumber}
onChange={formik.handleChange}
error={formik.touched.phoneNumber && Boolean(formik.errors.phoneNumber)}
helperText={formik.touched.phoneNumber && formik.errors.phoneNumber}
autoFocus
fullWidth
/>

<TextField
name="location"
placeholder={t("common.labelLocation")}
margin="normal"
type="text"
value={formik.values.location}
onChange={formik.handleChange}
error={formik.touched.location && Boolean(formik.errors.location)}
helperText={formik.touched.location && formik.errors.location}
fullWidth={true}
/>

<TextField
name="website"
placeholder={t("common.labelWebsite")}
margin="normal"
type="text"
value={formik.values.website}
onChange={formik.handleChange}
error={formik.touched.website && Boolean(formik.errors.website)}
helperText={formik.touched.website && formik.errors.website}
fullWidth={true}
/>

<PrimaryButton
type="submit"
variant="contained"
height="48px"
fullWidth={true}
buttoncolor={selectedTheme.primaryPurple}
textcolor="white"
disabled={
formik.values.location.length === 0 &&
formik.values.phoneNumber.length === 0 &&
formik.values.website.length === 0
}
>
{t("common.continue")}
</PrimaryButton>
</FormContainer>
);
};

ThirdPartOfRegistration.propTypes = {
children: PropTypes.node,
handleSubmit: PropTypes.func,
};

export default ThirdPartOfRegistration;

+ 22
- 0
src/pages/RegisterPages/Register/ThirdPart/ThirdPartOfRegistration.styled.js Просмотреть файл

@@ -0,0 +1,22 @@
import { Typography } from "@mui/material";
import styled from "styled-components";
import { PRIMARY_GRAY_TEXT_COLOR } from "../../../../constants/stylesConstants";

export const FormContainer = styled.form`
width: 335px;
`;
export const RegisterDescription = styled(Typography)`
font-family: "Open Sans";
font-style: normal;
font-weight: 400;
display: flex;
align-items: center;
color: ${PRIMARY_GRAY_TEXT_COLOR};
font-size: 12px;
width: 100%;
text-align: left;
line-height: 16px;
margin-top: 31px;
margin-bottom: 2px;
letter-spacing: 0.02em;
`;

+ 43
- 0
src/pages/RegisterPages/RegisterSuccessful.js/RegisterSuccessful.js Просмотреть файл

@@ -0,0 +1,43 @@
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import {
RegisterSuccessfulContainer,
RegisterDescription,
RegisterTitle,
} from "./RegisterSuccessful.styled";
import { ReactComponent as Success } from "../../../assets/images/svg/register-success.svg";
import { useTranslation } from "react-i18next";
import { useHistory } from "react-router-dom";
import { LOGIN_PAGE } from "../../../constants/pages";

const RegisterSuccessful = () => {
const { t } = useTranslation();
const history = useHistory();

//Redirect to Login page when registration is successful
useEffect(() => {
setTimeout(() => {
history.replace(LOGIN_PAGE);
}, 2500);
}, []);

return (
<RegisterSuccessfulContainer>
<Success />

<RegisterTitle component="h1" variant="h5">
{t("register.success")}
</RegisterTitle>

<RegisterDescription component="h1" variant="h6">
{t("register.welcome")}
</RegisterDescription>
</RegisterSuccessfulContainer>
);
};

RegisterSuccessful.propTypes = {
children: PropTypes.node,
};

export default RegisterSuccessful;

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

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

export const RegisterSuccessfulContainer = styled(Container)`
margin-top: 300px;
display: flex;
flex-direction: column;
align-items: center;
width: 536px;
padding: 0;
`;
export const RegisterTitle = styled(Typography)`
font-family: "Mulish";
width: 430px;
text-align: center;
flex: 1;
font-style: normal;
font-weight: 400;
font-size: 39px;
line-height: 48px;
color: ${selectedTheme.primaryPurple};
margin-top: 32px;
`;
export const RegisterDescription = styled(Typography)`
font-family: "Open Sans";
margin-top: 36px;
width: 430px;
font-style: normal;
font-weight: 400;
font-size: 25px;
line-height: 36px;
display: block;
align-items: center;
text-align: center;
color: ${selectedTheme.primaryGrayText};
margin-bottom: 20px;
`;

+ 0
- 71
src/request/accountRequest.js Просмотреть файл

@@ -1,71 +0,0 @@
import {
deleteRequest,
getRequest,
patchRequest,
replaceInUrl,
postRequest,
} from './index';
import apiEndpoints from './apiEndpoints';

export const getAccount = (accountUid) =>
getRequest(replaceInUrl(apiEndpoints.accounts.get, { accountUid }));

export const getAccountUsers = (accountUid) =>
getRequest(replaceInUrl(apiEndpoints.accounts.getUsers, { accountUid }));

export const getUserPermissions = (currentAccountUid, currentUserUid) =>
getRequest(
replaceInUrl(apiEndpoints.accounts.getCurrentUserPermissions, {
currentAccountUid,
currentUserUid,
}),
);

export const getAccountAddresses = (accountUid) =>
getRequest(replaceInUrl(apiEndpoints.accounts.getAddresses, { accountUid }));

export const getAccountSettingsRequest = (accountUid) =>
getRequest(replaceInUrl(apiEndpoints.accounts.getSettings, { accountUid }));

export const updateAccountAddressRequest = (accountUid, addressUid, data) =>
patchRequest(
replaceInUrl(apiEndpoints.accounts.updateAddress, {
accountUid,
addressUid,
}),
data,
);

export const deleteAccountAddressRequest = (accountUid, addressUid) =>
deleteRequest(
replaceInUrl(apiEndpoints.accounts.deleteAddress, {
accountUid,
addressUid,
}),
);

export const postNewAccountUserRequest = (accountUid, data) =>
postRequest(
replaceInUrl(apiEndpoints.accounts.createUser, {
accountUid,
}),
data,
);

export const updateAccountUserRequest = (
accountUid,
userUid,
actionType,
data,
) =>
patchRequest(
replaceInUrl(apiEndpoints.accounts.updateUser, {
accountUid,
userUid,
actionType,
}),
data,
);

export const postAgreementRequest = (data) =>
postRequest(apiEndpoints.accounts.agreement, data);

+ 2
- 1
src/store/actions/app/appActions.js Просмотреть файл

@@ -1,5 +1,6 @@
import { APP_LOADING } from './appActionConstants';

export const setAppReady = () => ({
export const setAppReady = (payload) => ({
type: APP_LOADING,
payload: payload
});

+ 14
- 0
src/themes/index.js Просмотреть файл

@@ -0,0 +1,14 @@
import { primaryThemeColors } from "./primaryTheme/primaryThemeColors";

let selectedThemeNumber = 0;

const getTheme = () => {
if (selectedThemeNumber === 0) {
return {...primaryThemeColors}
}
}

const selectedTheme = getTheme();

export default selectedTheme;


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

@@ -0,0 +1,10 @@
export const primaryThemeColors = {
primaryPurple: "#5A3984",
primaryYellow: "#f7b126",
primaryPurpleDisabled: "#4D4D4D",
primaryBackgroundColor: "#F1F1F1",
primaryTextDisabled: "#F1F1F1",
primaryText: "#4D4D4D",
primaryGrayText: "#818181",
primaryDarkGrayText: "#DCDCDC"
}

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