Client - add password reset - #50

This commit is contained in:
Sam
2020-05-17 18:20:15 +02:00
parent 51d627fa1c
commit 1860cfe320
16 changed files with 348 additions and 83 deletions

View File

@ -312,7 +312,6 @@ label {
.dropdown-item {
cursor: default;
font-size: 0.9em;
}
.dropdown-item-selected {
@ -437,6 +436,12 @@ label {
text-align: center;
}
.password-forget {
margin: 10px;
font-size: .9em;
font-style: italic;
}
.radioLabel {
text-align: center;
}
@ -467,6 +472,14 @@ label {
pointer-events: none;
}
.svg-icon {
fill: #405976;
height: 70px;
margin-left: auto;
margin-right: auto;
width: 70px;
}
.time-frames {
align-items: center;
display: inline-flex;

View File

@ -12,6 +12,7 @@ import Footer from './Footer'
import Logout from './User/Logout'
import NavBar from './NavBar'
import NotFound from './Others/NotFound'
import PasswordReset from './User/PasswordReset'
import ProfileEdit from './User/ProfileEdit'
import Statistics from './Statistics'
import UserForm from './User/UserForm'
@ -43,6 +44,27 @@ class App extends React.Component {
path="/login"
render={() => <UserForm formType={'login'} />}
/>
<Route
exact
path="/password-reset"
render={() => <UserForm formType={'password reset'} />}
/>
<Route
exact
path="/password-reset/request"
render={() => <UserForm formType={'reset your password'} />}
/>
<Route
exact
path="/password-reset/sent"
render={() => <PasswordReset action={'sent'} />}
/>
<Route
exact
path="/updated-password"
render={() => <PasswordReset action={'updated'} />}
/>
<Route exact path="/password-reset/sent" component={PasswordReset} />
<Route exact path="/logout" component={Logout} />
<Route exact path="/profile/edit" component={ProfileEdit} />
<Route exact path="/profile" component={CurrentUserProfile} />

View File

@ -101,7 +101,7 @@ class NavBar extends React.PureComponent {
pathname: '/register',
}}
>
{t('common:Register')}
{t('user:Register')}
</Link>
</li>
)}
@ -113,7 +113,7 @@ class NavBar extends React.PureComponent {
pathname: '/login',
}}
>
{t('common:Login')}
{t('user:Login')}
</Link>
</li>
)}
@ -148,7 +148,7 @@ class NavBar extends React.PureComponent {
pathname: '/logout',
}}
>
{t('common:Logout')}
{t('user:Logout')}
</Link>
</li>
</>

View File

@ -1,12 +1,13 @@
import React from 'react'
import { useTranslation } from 'react-i18next'
import { Helmet } from 'react-helmet'
import { Link } from 'react-router-dom'
import { history } from '../../index'
export default function Form(props) {
const { t } = useTranslation()
const pageTitle = `common:${props.formType
const pageTitle = `user:${props.formType
.charAt(0)
.toUpperCase()}${props.formType.slice(1)}`
return (
@ -34,65 +35,86 @@ export default function Form(props) {
</div>
</div>
) : (
<form
onSubmit={event =>
props.handleUserFormSubmit(event, props.formType)
}
>
{props.formType === 'register' && (
<div className="form-group">
<input
className="form-control input-lg"
name="username"
placeholder={t('user:Enter a username')}
required
type="text"
value={props.userForm.username}
onChange={props.onHandleFormChange}
/>
</div>
)}
<div className="form-group">
<>
<form
onSubmit={event =>
props.handleUserFormSubmit(event, props.formType)
}
>
{props.formType === 'register' && (
<div className="form-group">
<input
className="form-control input-lg"
name="username"
placeholder={t('user:Enter a username')}
required
type="text"
value={props.userForm.username}
onChange={props.onHandleFormChange}
/>
</div>
)}
{props.formType !== 'password reset' && (
<div className="form-group">
<input
className="form-control input-lg"
name="email"
placeholder={t('user:Enter an email address')}
required
type="email"
value={props.userForm.email}
onChange={props.onHandleFormChange}
/>
</div>
)}
{props.formType !== 'reset your password' && (
<>
<div className="form-group">
<input
className="form-control input-lg"
name="password"
placeholder={t('user:Enter a password')}
required
type="password"
value={props.userForm.password}
onChange={props.onHandleFormChange}
/>
</div>
{props.formType !== 'login' && (
<div className="form-group">
<input
className="form-control input-lg"
name="password_conf"
placeholder={t(
'user:Enter the password confirmation'
)}
required
type="password"
value={props.userForm.password_conf}
onChange={props.onHandleFormChange}
/>
</div>
)}
</>
)}
<input
className="form-control input-lg"
name="email"
placeholder={t('user:Enter an email address')}
required
type="email"
value={props.userForm.email}
onChange={props.onHandleFormChange}
type="submit"
className="btn btn-primary btn-lg btn-block"
value={t('Submit')}
/>
</div>
<div className="form-group">
<input
className="form-control input-lg"
name="password"
placeholder={t('user:Enter a password')}
required
type="password"
value={props.userForm.password}
onChange={props.onHandleFormChange}
/>
</div>
{props.formType === 'register' && (
<div className="form-group">
<input
className="form-control input-lg"
name="password_conf"
placeholder={t('user:Enter the password confirmation')}
required
type="password"
value={props.userForm.password_conf}
onChange={props.onHandleFormChange}
/>
</div>
)}
<input
type="submit"
className="btn btn-primary btn-lg btn-block"
value={t('Submit')}
/>
</form>
</form>
<p className="password-forget">
{props.formType === 'login' && (
<Link
to={{
pathname: '/password-reset/request',
}}
>
{t('user:Forgot password?')}
</Link>
)}
</p>
</>
)}
</div>
<div className="col-md-3" />

View File

@ -0,0 +1,48 @@
import React from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { ReactComponent as Password } from '../../images/password.svg'
import { ReactComponent as MailSend } from '../../images/mail-send.svg'
export default function PasswordReset(props) {
const { t } = useTranslation()
const { action } = props
return (
<div className="container dashboard">
<div className="row">
<div className="col-2" />
<div className="card col-8">
<div className="card-body">
<div className="text-center ">
{action === 'sent' && (
<>
<div className="svg-icon">
<MailSend />
</div>
{t(
// eslint-disable-next-line max-len
"user:Check your email. If your address is in our database, you'll received an email with a link to reset your password."
)}
</>
)}
{action === 'updated' && (
<>
<div className="svg-icon">
<Password />
</div>
<Trans i18nKey="user:updatedPasswordText">
{/* prettier-ignore */}
Your password have been updated. Click
<Link to="/login">here</Link> to log in.
</Trans>
</>
)}
</div>
</div>
</div>
<div className="col-2" />
</div>
</div>
)
}

View File

@ -49,9 +49,10 @@ class UserForm extends React.Component {
t,
} = this.props
const { formData } = this.state
const { token } = this.props.location.query
return (
<div>
{isLoggedIn() ? (
{isLoggedIn() || (formType === 'password reset' && !token) ? (
<Redirect to="/" />
) : (
<div>
@ -63,6 +64,9 @@ class UserForm extends React.Component {
onHandleFormChange={event => this.onHandleFormChange(event)}
handleUserFormSubmit={event => {
event.preventDefault()
if (formType === 'password reset') {
formData.token = token
}
onHandleUserFormSubmit(formData, formType)
}}
/>
@ -82,6 +86,12 @@ export default withTranslation()(
}),
dispatch => ({
onHandleUserFormSubmit: (formData, formType) => {
formType =
formType === 'password reset'
? 'password/update'
: formType === 'reset your password'
? 'password/reset-request'
: formType
dispatch(handleUserFormSubmit(formData, formType))
},
})