You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LoginPage.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* eslint-disable */
  2. import React, { useEffect, useState } from "react";
  3. import PropTypes from "prop-types";
  4. import { useFormik } from "formik";
  5. import { useDispatch, useSelector } from "react-redux";
  6. import { NavLink } from "react-router-dom";
  7. import * as Yup from "yup";
  8. import { useTranslation } from "react-i18next";
  9. import {
  10. clearLoginErrors,
  11. fetchUser,
  12. } from "../../store/actions/login/loginActions";
  13. import { selectLoginError } from "../../store/selectors/loginSelectors";
  14. import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages";
  15. import { ReactComponent as VisibilityOn } from "../../assets/images/svg/eye-striked.svg";
  16. import { ReactComponent as VisibilityOff } from "../../assets/images/svg/eye.svg";
  17. import Backdrop from "../../components/MUI/BackdropComponent";
  18. import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
  19. import { LOGIN_USER_LOADING } from "../../store/actions/login/loginActionConstants";
  20. import { TextField } from "../../components/TextFields/TextField/TextField";
  21. import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton";
  22. import { IconButton } from "../../components/Buttons/IconButton/IconButton";
  23. import Link from "../../components/Link/Link";
  24. import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg";
  25. import {
  26. LoginPageContainer,
  27. LoginTitle,
  28. LoginDescription,
  29. LoginFormContainer,
  30. RegisterAltText,
  31. RegisterTextContainer,
  32. ErrorMessage,
  33. } from "./Login.styled";
  34. import selectedTheme from "../../themes";
  35. const LoginPage = ({ history }) => {
  36. const dispatch = useDispatch();
  37. const { t } = useTranslation();
  38. const error = useSelector(selectLoginError);
  39. const [showPassword, setShowPassword] = useState(false);
  40. const handleClickShowPassword = () => setShowPassword(!showPassword);
  41. const handleMouseDownPassword = () => setShowPassword(!showPassword);
  42. // When user refreshes page
  43. // useEffect(() => {
  44. // function redirectClient() {
  45. // if (!tokens.RefreshToken && !tokens.JwtToken) {
  46. // return;
  47. // }
  48. // }
  49. // redirectClient();
  50. // }, [history, tokens]);
  51. const isLoading = useSelector(
  52. selectIsLoadingByActionType(LOGIN_USER_LOADING)
  53. );
  54. useEffect(() => {
  55. dispatch(clearLoginErrors());
  56. }, []);
  57. const handleApiResponseSuccess = () => {
  58. history.push({
  59. pathname: HOME_PAGE,
  60. state: {
  61. from: history.location.pathname,
  62. },
  63. });
  64. };
  65. const handleSubmit = (values) => {
  66. const { email, password: password } = values;
  67. dispatch(clearLoginErrors());
  68. dispatch(
  69. fetchUser({
  70. email,
  71. password,
  72. handleApiResponseSuccess,
  73. })
  74. );
  75. };
  76. const formik = useFormik({
  77. initialValues: {
  78. email: "",
  79. password: "",
  80. },
  81. validationSchema: Yup.object().shape({
  82. email: Yup.string().required(t("login.mailRequired")),
  83. password: Yup.string()
  84. .required(t("login.passwordRequired"))
  85. .min(8, t("login.passwordLength")),
  86. }),
  87. onSubmit: handleSubmit,
  88. validateOnBlur: true,
  89. enableReinitialize: true,
  90. });
  91. useEffect(() => {
  92. if (error) {
  93. if (formik.errors.email || formik.errors.password) {
  94. dispatch(clearLoginErrors());
  95. }
  96. }
  97. }, [formik.errors.email, formik.errors.password])
  98. return (
  99. <LoginPageContainer>
  100. <Logo />
  101. <LoginTitle component="h1" variant="h5">
  102. {t("login.logInTitle")}
  103. </LoginTitle>
  104. <LoginDescription component="h1" variant="h6">
  105. {t("login.welcomeText")}
  106. </LoginDescription>
  107. <LoginFormContainer component="form" onSubmit={formik.handleSubmit}>
  108. <Backdrop position="absolute" isLoading={isLoading} />
  109. <TextField
  110. name="email"
  111. placeholder={t("common.labelEmail")}
  112. margin="normal"
  113. value={formik.values.email}
  114. onChange={formik.handleChange}
  115. error={
  116. (formik.touched.email && formik.errors.email) || error.length > 0
  117. }
  118. helperText={formik.touched.email && formik.errors.email}
  119. autoFocus
  120. fullWidth
  121. />
  122. <TextField
  123. name="password"
  124. placeholder={t("common.labelPassword")}
  125. margin="normal"
  126. type={showPassword ? "text" : "password"}
  127. value={formik.values.password}
  128. onChange={formik.handleChange}
  129. error={
  130. (formik.touched.password && formik.errors.password) ||
  131. error.length > 0
  132. }
  133. helperText={formik.touched.password && formik.errors.password}
  134. fullWidth
  135. InputProps={{
  136. endAdornment: (
  137. <IconButton
  138. onClick={handleClickShowPassword}
  139. onMouseDown={handleMouseDownPassword}
  140. >
  141. {showPassword ? <VisibilityOn /> : <VisibilityOff />}
  142. </IconButton>
  143. ),
  144. }}
  145. />
  146. {formik.errors.password && formik.touched.password && (
  147. <ErrorMessage>{formik.errors.password}</ErrorMessage>
  148. )}
  149. {error.length > 0 && !formik.errors.password && <ErrorMessage>{error}</ErrorMessage>}
  150. <Link
  151. to={FORGOT_PASSWORD_PAGE}
  152. textsize="12px"
  153. component={NavLink}
  154. underline="hover"
  155. align="right"
  156. style={{
  157. marginTop: error.length > 0 ? "0" : "18px",
  158. marginBottom: "18px",
  159. }}
  160. >
  161. {t("login.forgotYourPassword")}
  162. </Link>
  163. <PrimaryButton
  164. type="submit"
  165. variant="contained"
  166. height="48px"
  167. fullWidth
  168. buttoncolor={selectedTheme.primaryPurple}
  169. textcolor="white"
  170. disabled={
  171. formik.values.email.length === 0 ||
  172. formik.values.password.length === 0
  173. }
  174. >
  175. {t("login.logIn")}
  176. </PrimaryButton>
  177. <RegisterTextContainer>
  178. <RegisterAltText>
  179. {t("login.dontHaveAccount").padEnd(2, " ")}
  180. </RegisterAltText>
  181. <Link
  182. to="/register"
  183. component={NavLink}
  184. underline="hover"
  185. align="center"
  186. >
  187. {t("login.signUp")}
  188. </Link>
  189. </RegisterTextContainer>
  190. </LoginFormContainer>
  191. </LoginPageContainer>
  192. );
  193. };
  194. LoginPage.propTypes = {
  195. history: PropTypes.shape({
  196. replace: PropTypes.func,
  197. push: PropTypes.func,
  198. location: PropTypes.shape({
  199. pathname: PropTypes.string,
  200. }),
  201. }),
  202. };
  203. export default LoginPage;