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.

LoginPageMUI.js 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 HrLogo from "../../assets/images/hrcenter.png";
  10. import DiligLogo from "../../assets/images/logo_horizontal_black.png";
  11. import googleLogo from "../../assets/images/google1.png";
  12. import {
  13. clearLoginErrors,
  14. fetchUser,
  15. } from "../../store/actions/login/loginActions";
  16. import { selectLoginError } from "../../store/selectors/loginSelectors";
  17. import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages";
  18. import {
  19. Box,
  20. Button,
  21. Container,
  22. Grid,
  23. IconButton,
  24. InputAdornment,
  25. Link,
  26. TextField,
  27. Typography,
  28. } from "@mui/material";
  29. import { Visibility, VisibilityOff } from "@mui/icons-material";
  30. import Backdrop from "../../components/MUI/BackdropComponent";
  31. import ErrorMessage from "../../components/MUI/ErrorMessageComponent";
  32. import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors";
  33. import { LOGIN_USER_LOADING } from "../../store/actions/login/loginActionConstants";
  34. const LoginPage = ({ history }) => {
  35. const dispatch = useDispatch();
  36. const { t } = useTranslation();
  37. const error = useSelector(selectLoginError);
  38. const [showPassword, setShowPassword] = useState(false);
  39. const handleClickShowPassword = () => setShowPassword(!showPassword);
  40. const handleMouseDownPassword = () => setShowPassword(!showPassword);
  41. useEffect(() => {
  42. function redirectClient() {
  43. let token = localStorage.getItem("JwtToken")
  44. if (!token) {
  45. return;
  46. }
  47. handleApiResponseSuccess()
  48. }
  49. redirectClient();
  50. }, [history]);
  51. const isLoading = useSelector(
  52. selectIsLoadingByActionType(LOGIN_USER_LOADING)
  53. );
  54. const handleApiResponseSuccess = () => {
  55. history.push({
  56. pathname: HOME_PAGE,
  57. state: {
  58. from: history.location.pathname,
  59. },
  60. });
  61. };
  62. const handleSubmit = (values) => {
  63. const { username,password } = values;
  64. dispatch(clearLoginErrors());
  65. dispatch(
  66. fetchUser({
  67. username,
  68. password,
  69. handleApiResponseSuccess,
  70. })
  71. );
  72. };
  73. const formik = useFormik({
  74. initialValues: {
  75. username: "",
  76. password: "",
  77. },
  78. validationSchema: Yup.object().shape({
  79. username: Yup.string().required(t("login.usernameRequired")),
  80. password: Yup.string().required(t("login.passwordRequired")),
  81. }),
  82. onSubmit: handleSubmit,
  83. validateOnBlur: true,
  84. enableReinitialize: true,
  85. });
  86. return (
  87. <Container
  88. component="main"
  89. maxWidth="xl"
  90. className="c-login-container"
  91. fullwidth="true"
  92. >
  93. <div className="l-t-rectangle"></div>
  94. <div className="r-b-rectangle"></div>
  95. <Box
  96. sx={{
  97. marginTop: 2,
  98. width: 289,
  99. height: 684,
  100. display: "flex",
  101. flexDirection: "column",
  102. alignItems: "center",
  103. }}
  104. >
  105. <img src={HrLogo} className="login-logo" />
  106. <Typography variant="h5" sx={{ m: 2, mt: 3 }}>
  107. {t("login.welcome")}
  108. </Typography>
  109. {error && <ErrorMessage error={error} />}
  110. <Box
  111. component="form"
  112. onSubmit={formik.handleSubmit}
  113. sx={{ position: "relative" }}
  114. >
  115. <Backdrop position="absolute" isLoading={isLoading} />
  116. <TextField
  117. name="username"
  118. label={t("common.labelUsername")}
  119. margin="normal"
  120. value={formik.values.username}
  121. onChange={formik.handleChange}
  122. error={formik.touched.username && Boolean(formik.errors.username)}
  123. helperText={formik.touched.username && formik.errors.username}
  124. autoFocus
  125. fullWidth
  126. />
  127. <TextField
  128. className="rounded-input"
  129. name="password"
  130. label={t("common.labelPassword")}
  131. margin="normal"
  132. type={showPassword ? "text" : "password"}
  133. value={formik.values.password}
  134. onChange={formik.handleChange}
  135. error={formik.touched.password && Boolean(formik.errors.password)}
  136. helperText={formik.touched.password && formik.errors.password}
  137. fullWidth
  138. InputProps={{
  139. endAdornment: (
  140. <InputAdornment position="end">
  141. <IconButton
  142. onClick={handleClickShowPassword}
  143. onMouseDown={handleMouseDownPassword}
  144. >
  145. {showPassword ? <Visibility /> : <VisibilityOff />}
  146. </IconButton>
  147. </InputAdornment>
  148. ),
  149. }}
  150. />
  151. <Grid container>
  152. <Grid item sm={12} sx={{ textAlign: "end" }}>
  153. <Link
  154. to={FORGOT_PASSWORD_PAGE}
  155. component={NavLink}
  156. variant="body2"
  157. underline="hover"
  158. className="text-end"
  159. sx={{ fontSize: 12 }}
  160. >
  161. {t("login.forgotYourPassword")}
  162. </Link>
  163. </Grid>
  164. </Grid>
  165. <Button
  166. type="submit"
  167. variant="contained"
  168. sx={{ mt: 3, mb: 2 }}
  169. fullWidth
  170. className="c-btn c-btn--primary"
  171. >
  172. {t("login.logIn")}
  173. </Button>
  174. <div className="flex-center">
  175. <div className="hr hr-s"></div>
  176. <div className="hr-mid">{t("common.or")}</div>
  177. <div className="hr hr-e"></div>
  178. </div>
  179. <Button
  180. className="c-btn c-btn--gray flex-center"
  181. sx={{ width: "100%", mt: 2 }}
  182. >
  183. <img src={googleLogo} style={{ marginRight: "15px" }} />
  184. <Typography sx={{ m: 0, p: 0 }} variant="buttonText">
  185. {t("login.signInWithGoogle")}
  186. </Typography>
  187. </Button>
  188. <div className="flex-center">
  189. <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} />
  190. </div>
  191. </Box>
  192. </Box>
  193. </Container>
  194. );
  195. };
  196. LoginPage.propTypes = {
  197. history: PropTypes.shape({
  198. replace: PropTypes.func,
  199. push: PropTypes.func,
  200. location: PropTypes.shape({
  201. pathname: PropTypes.string,
  202. }),
  203. }),
  204. };
  205. export default LoginPage;