forgot-password-page в master 4 лет назад
| @@ -15,7 +15,8 @@ import LoginPage from './pages/LoginPage/LoginPageMUI'; | |||
| import HomePage from './pages/HomePage/HomePage'; | |||
| import NotFoundPage from './pages/ErrorPages/NotFoundPage'; | |||
| import ErrorPage from './pages/ErrorPages/ErrorPage'; | |||
| import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage'; | |||
| // import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage'; | |||
| import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPageMUI'; | |||
| import PrivateRoute from './components/Router/PrivateRoute'; | |||
| const AppRoutes = () => ( | |||
| @@ -0,0 +1,15 @@ | |||
| import React from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import { Typography } from '@mui/material'; | |||
| const CustomErrorMessage = ({ error }) => ( | |||
| <Typography variant="body1" color="error" my={2}> | |||
| {error} | |||
| </Typography> | |||
| ); | |||
| CustomErrorMessage.propTypes = { | |||
| error: PropTypes.string.isRequired, | |||
| }; | |||
| export default CustomErrorMessage; | |||
| @@ -65,6 +65,8 @@ export default { | |||
| forgotPassword: { | |||
| title: 'Forgot Password', | |||
| label: 'Send email', | |||
| emailRequired: 'An email is required.', | |||
| emailFormat: 'Invalid email address format.', | |||
| forgotPassword: { | |||
| title: 'Forgot Password', | |||
| subtitle: | |||
| @@ -83,6 +85,7 @@ export default { | |||
| logout: 'Logout', | |||
| }, | |||
| apiErrors:{ | |||
| ClientIpAddressIsNullOrEmpty:"Client Ip address is null or empty" | |||
| ClientIpAddressIsNullOrEmpty:"Client Ip address is null or empty", | |||
| UsernameDoesNotExist: "Username does not exist" | |||
| } | |||
| }; | |||
| @@ -0,0 +1,96 @@ | |||
| import React from 'react'; | |||
| import { useFormik } from 'formik'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| import * as Yup from 'yup'; | |||
| import i18next from 'i18next'; | |||
| import { | |||
| Box, | |||
| Container, | |||
| Typography, | |||
| Button, | |||
| TextField, | |||
| Link, | |||
| Grid, | |||
| } from '@mui/material'; | |||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | |||
| import { LOGIN_PAGE } from '../../constants/pages'; | |||
| import { NavLink } from 'react-router-dom'; | |||
| const forgotPasswordValidationSchema = Yup.object().shape({ | |||
| email: Yup.string() | |||
| .required(i18next.t('forgotPassword.emailRequired')) | |||
| .email(i18next.t('forgotPassword.emailFormat')), | |||
| }); | |||
| const ForgotPasswordPage = () => { | |||
| const { t } = useTranslation(); | |||
| const handleSubmit = (values) => { | |||
| console.log('Values', values); | |||
| }; | |||
| 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> | |||
| ); | |||
| }; | |||
| export default ForgotPasswordPage; | |||
| @@ -1,3 +1,4 @@ | |||
| /* eslint-disable */ | |||
| import React, { useState } from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import { useFormik } from 'formik'; | |||
| @@ -10,7 +11,7 @@ import { | |||
| clearLoginErrors, | |||
| fetchUser, | |||
| } from '../../store/actions/login/loginActions'; | |||
| // import { selectLoginError } from '../../store/selectors/loginSelectors'; | |||
| import { selectLoginError } from '../../store/selectors/loginSelectors'; | |||
| import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from '../../constants/pages'; | |||
| import { | |||
| Box, | |||
| @@ -25,6 +26,7 @@ import { | |||
| } from '@mui/material'; | |||
| import { Visibility, VisibilityOff } from '@mui/icons-material'; | |||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | |||
| import ErrorMessage from '../../components/MUI/CustomErrorMessage'; | |||
| import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | |||
| import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | |||
| @@ -36,7 +38,7 @@ const LoginValidationSchema = Yup.object().shape({ | |||
| const LoginPage = ({ history }) => { | |||
| const dispatch = useDispatch(); | |||
| const { t } = useTranslation(); | |||
| // const error = useSelector(selectLoginError); | |||
| const error = useSelector(selectLoginError); | |||
| const [showPassword, setShowPassword] = useState(false); | |||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | |||
| @@ -58,12 +60,12 @@ const LoginPage = ({ history }) => { | |||
| ); | |||
| const handleApiResponseSuccess = () => { | |||
| history.push({ | |||
| pathname: HOME_PAGE, | |||
| state: { | |||
| from: history.location.pathname, | |||
| }, | |||
| }); | |||
| // history.push({ | |||
| // pathname: HOME_PAGE, | |||
| // state: { | |||
| // from: history.location.pathname, | |||
| // }, | |||
| // }); | |||
| }; | |||
| const handleSubmit = (values) => { | |||
| @@ -102,6 +104,7 @@ const LoginPage = ({ history }) => { | |||
| <Typography component="h1" variant="h5"> | |||
| {t('login.logInTitle')} | |||
| </Typography> | |||
| {error && <ErrorMessage error={error} />} | |||
| <Box | |||
| component="form" | |||
| onSubmit={formik.handleSubmit} | |||
| @@ -151,7 +154,12 @@ const LoginPage = ({ history }) => { | |||
| {t('login.logIn')} | |||
| </Button> | |||
| <Grid container> | |||
| <Grid item xs> | |||
| <Grid | |||
| item | |||
| xs={12} | |||
| md={6} | |||
| sx={{ textAlign: { xs: 'center', md: 'left' } }} | |||
| > | |||
| <Link | |||
| to={FORGOT_PASSWORD_PAGE} | |||
| component={NavLink} | |||
| @@ -161,7 +169,12 @@ const LoginPage = ({ history }) => { | |||
| {t('login.forgotYourPassword')} | |||
| </Link> | |||
| </Grid> | |||
| <Grid item> | |||
| <Grid | |||
| item | |||
| xs={12} | |||
| md={6} | |||
| sx={{ textAlign: { xs: 'center', md: 'right' } }} | |||
| > | |||
| <Link | |||
| to="#" | |||
| component={NavLink} | |||
| @@ -63,8 +63,8 @@ function* fetchUser({ payload }) { | |||
| if (payload.handleApiResponseSuccess) { | |||
| yield call(payload.handleApiResponseSuccess); | |||
| } | |||
| // const errorMessage = yield call(rejectErrorCodeHelper, e); | |||
| // yield put(fetchUserError(errorMessage)); | |||
| const errorMessage = yield call(rejectErrorCodeHelper, e); | |||
| yield put(fetchUserError(errorMessage)); | |||
| } | |||
| } | |||
| } | |||