Skip to content

Commit aa64fde

Browse files
committed
change Forgot Password to Component
1 parent bc5d318 commit aa64fde

File tree

7 files changed

+188
-137
lines changed

7 files changed

+188
-137
lines changed

src/app/apiFetch/Code.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ export const getLastSaveTime = () => {
131131
return textResponseWrapper(response);
132132
})
133133
.then((data) => {
134-
console.log(data);
135134
return data;
136135
})
137136
.catch((error) => {

src/app/apiFetch/User.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export const userForgotPassword = (email: string) => {
158158
method: 'POST',
159159
})
160160
.then((response) => {
161-
return headResponseWrapper(response, HeadReqType.OTHERS);
161+
return response.text();
162162
})
163163
.then((data) => {
164164
return data;
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import * as styles from 'app/styles/Authentication.module.css';
2+
import classnames from 'classnames';
3+
import * as React from 'react';
4+
import { Col, Row } from 'react-bootstrap';
5+
import * as registerStyles from 'app/styles/Register.module.css';
6+
import { Routes } from 'app/routes';
7+
import * as LoginInterfaces from 'app/types/Authentication/Login';
8+
import { AuthType } from 'app/types/Authentication';
9+
10+
// tslint:disable-next-line: variable-name
11+
const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => {
12+
const forgotPasswordRef = React.createRef<HTMLFormElement>();
13+
const [username, setUsername] = React.useState('');
14+
15+
const handleForgotPassword = (event: React.FormEvent<HTMLFormElement>) => {
16+
const form = forgotPasswordRef.current;
17+
18+
event.preventDefault();
19+
if (form) {
20+
if (form.checkValidity()) {
21+
props.forgotPassword(username);
22+
}
23+
form.classList.add('was-validated');
24+
}
25+
};
26+
27+
return (
28+
<div>
29+
<div className={classnames(styles.loginRoot)}>
30+
<div className={classnames(styles.welcomeBack)}>
31+
<h1> Forgot your password? </h1>
32+
</div>
33+
<Row>
34+
<Col className="text-center my-3 ml-auto mr-auto">
35+
<div className="text-dark">
36+
Don't have an account?
37+
<a
38+
href={Routes.REGISTER}
39+
className={classnames(styles['create-one-button'])}
40+
onClick={() => {
41+
props.updateErrorMessage('');
42+
props.handleSelectPanel(AuthType.REGISTER);
43+
}}
44+
>
45+
Create one
46+
</a>
47+
<Row>
48+
<div className={classnames('col-sm-10', styles.form)}>
49+
<form
50+
className={classnames(styles.loginForm)}
51+
noValidate
52+
ref={forgotPasswordRef}
53+
onSubmit={handleForgotPassword}
54+
>
55+
<div className="form-row">
56+
<div className="col mb-4">
57+
<div className={classnames(styles['login-label'])}> Your Email: </div>
58+
<div className="input-group">
59+
<input
60+
type="email"
61+
className={classnames('form-control', styles['login-input'])}
62+
id="validationUsername"
63+
aria-describedby="inputGroupPrepend"
64+
required
65+
value={username}
66+
onChange={(e) => setUsername(e.target.value)}
67+
/>
68+
<div className={classnames('invalid-feedback', styles['login-error'])}>
69+
{' '}
70+
Please enter a valid Email.{' '}
71+
</div>
72+
</div>
73+
</div>
74+
</div>
75+
<div className={classnames('form-row', styles['error-row'])}>
76+
<div
77+
className={
78+
!props.errorMessage
79+
? classnames(
80+
'col text-center mt-0 mb-2 ',
81+
styles['register-error-inactive'],
82+
registerStyles.errorMessage,
83+
)
84+
: classnames(
85+
'col text-center mt-0 mb-2 errorMessage',
86+
styles['register-error-active'],
87+
registerStyles.errorMessageLogin,
88+
styles['login-error-active'],
89+
)
90+
}
91+
>
92+
{props.errorMessage}
93+
</div>
94+
</div>
95+
<div className="form-row">
96+
<div className="col text-center">
97+
<button
98+
className={classnames('btn btn-info', styles.loginButton)}
99+
type="submit"
100+
>
101+
Reset Password&nbsp;
102+
</button>
103+
</div>
104+
</div>
105+
</form>
106+
</div>
107+
</Row>
108+
</div>
109+
</Col>
110+
</Row>
111+
<Row>
112+
<Col className="text-center my-3 ml-auto mr-auto">
113+
<div
114+
className={classnames('text-dark', styles['forgot-your-password'])}
115+
onClick={() => props.closeForgotPassword()}
116+
>
117+
Back{' '}
118+
</div>
119+
</Col>
120+
</Row>
121+
<Row>
122+
<Col className="text-center my-3 ml-auto mr-auto">
123+
<div className="text-dark">
124+
Don't have an account?{' '}
125+
<a
126+
href={Routes.REGISTER}
127+
className={classnames(styles['create-one-button'])}
128+
onClick={() => {
129+
props.updateErrorMessage('');
130+
props.handleSelectPanel(AuthType.REGISTER);
131+
}}
132+
>
133+
Create one
134+
</a>
135+
</div>
136+
</Col>
137+
</Row>
138+
</div>
139+
</div>
140+
);
141+
};
142+
143+
export default ForgotPassword;

src/app/components/Authentication/Login.tsx

Lines changed: 22 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { faSpinner } from '@fortawesome/free-solid-svg-icons';
22
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
33
import { API_BASE_URL } from 'app/../config/config';
4+
import ForgotPassword from 'app/components/Authentication/ForgotPassword';
45
import { Routes } from 'app/routes';
56
import * as styles from 'app/styles/Authentication.module.css';
67
import * as registerStyles from 'app/styles/Register.module.css';
@@ -17,7 +18,6 @@ export enum OAUTH_ROUTES {
1718
}
1819
export class Login extends React.Component<LoginInterfaces.Props, LoginInterfaces.State> {
1920
private loginRef = React.createRef<HTMLFormElement>();
20-
private forgotPasswordRef = React.createRef<HTMLFormElement>();
2121

2222
constructor(props: LoginInterfaces.Props) {
2323
super(props);
@@ -35,6 +35,7 @@ export class Login extends React.Component<LoginInterfaces.Props, LoginInterface
3535
};
3636

3737
public componentDidMount() {
38+
this.props.updateErrorMessage('');
3839
window.addEventListener('beforeunload', this.componentCleanup);
3940
}
4041

@@ -64,6 +65,12 @@ export class Login extends React.Component<LoginInterfaces.Props, LoginInterface
6465
if (isLoggedIn) {
6566
return <Redirect to={Routes.ROOT} />;
6667
}
68+
if (this.props.errorMessage === ' ' && this.state.isForgotPasswordOpen) {
69+
this.setState({
70+
isForgotPasswordOpen: false,
71+
});
72+
updateErrorMessage('');
73+
}
6774
if (!isForgotPasswordOpen) {
6875
return (
6976
<div className={classnames(styles.loginRoot)}>
@@ -182,14 +189,14 @@ export class Login extends React.Component<LoginInterfaces.Props, LoginInterface
182189
<div className={classnames('form-row', styles['error-row'])}>
183190
<div
184191
className={
185-
!errorMessage
192+
errorMessage.trim().length === 0
186193
? classnames(
187-
'col text-center mt -0 mb-2 ',
194+
'col text-center mt-0 mb-2 ',
188195
styles['register-error-inactive'],
189196
registerStyles.errorMessage,
190197
)
191198
: classnames(
192-
'col text-center mt -0 mb-2 errorMessage',
199+
'col text-center mt-0 mb-2 errorMessage',
193200
styles['register-error-active'],
194201
registerStyles.errorMessageLogin,
195202
styles['login-error-active'],
@@ -244,139 +251,20 @@ export class Login extends React.Component<LoginInterfaces.Props, LoginInterface
244251
);
245252
}
246253
return (
247-
<div>
248-
<div className={classnames(styles.loginRoot)}>
249-
<div className={classnames(styles.welcomeBack)}>
250-
<h1> Forgot your password? </h1>
251-
</div>
252-
<Row>
253-
<Col className="text-center my-3 ml-auto mr-auto">
254-
<div className="text-dark">
255-
Don't have an account?
256-
<a
257-
href={Routes.REGISTER}
258-
className={classnames(styles['create-one-button'])}
259-
onClick={() => {
260-
updateErrorMessage('');
261-
this.props.handleSelectPanel(AuthType.REGISTER);
262-
}}
263-
>
264-
Create one
265-
</a>
266-
<Row>
267-
<div className={classnames('col-sm-10', styles.form)}>
268-
<form
269-
className={classnames(styles.loginForm)}
270-
noValidate
271-
ref={this.forgotPasswordRef}
272-
onSubmit={this.handleForgotPassword}
273-
>
274-
<div className="form-row">
275-
<div className="col mb-4">
276-
<div className={classnames(styles['login-label'])}> Your Email: </div>
277-
<div className="input-group">
278-
<input
279-
type="email"
280-
className={classnames('form-control', styles['login-input'])}
281-
id="validationUsername"
282-
aria-describedby="inputGroupPrepend"
283-
required
284-
value={username}
285-
onChange={(e) =>
286-
this.setState({
287-
username: e.target.value,
288-
})
289-
}
290-
/>
291-
<div className={classnames('invalid-feedback', styles['login-error'])}>
292-
{' '}
293-
Please enter a valid Email.{' '}
294-
</div>
295-
</div>
296-
</div>
297-
</div>
298-
<div className={classnames('form-row', styles['error-row'])}>
299-
<div
300-
className={
301-
!errorMessage
302-
? classnames(
303-
'col text-center mt -0 mb-2 ',
304-
styles['register-error-inactive'],
305-
registerStyles.errorMessage,
306-
)
307-
: classnames(
308-
'col text-center mt -0 mb-2 errorMessage',
309-
styles['register-error-active'],
310-
registerStyles.errorMessageLogin,
311-
styles['login-error-active'],
312-
)
313-
}
314-
>
315-
{errorMessage}
316-
</div>
317-
</div>
318-
<div className="form-row">
319-
<div className="col text-center">
320-
<button
321-
className={classnames('btn btn-info', styles.loginButton)}
322-
type="submit"
323-
>
324-
Reset Password&nbsp;
325-
</button>
326-
</div>
327-
</div>
328-
</form>
329-
</div>
330-
</Row>
331-
</div>
332-
</Col>
333-
</Row>
334-
<Row>
335-
<Col className="text-center my-3 ml-auto mr-auto">
336-
<div
337-
className={classnames('text-dark', styles['forgot-your-password'])}
338-
onClick={() => this.setState({ isForgotPasswordOpen: false })}
339-
>
340-
Back{' '}
341-
</div>
342-
</Col>
343-
</Row>
344-
<Row>
345-
<Col className="text-center my-3 ml-auto mr-auto">
346-
<div className="text-dark">
347-
Don't have an account?{' '}
348-
<a
349-
href={Routes.REGISTER}
350-
className={classnames(styles['create-one-button'])}
351-
onClick={() => {
352-
updateErrorMessage('');
353-
this.props.handleSelectPanel(AuthType.REGISTER);
354-
}}
355-
>
356-
Create one
357-
</a>
358-
</div>
359-
</Col>
360-
</Row>
361-
</div>
362-
</div>
254+
<ForgotPassword
255+
updateErrorMessage={updateErrorMessage}
256+
handleSelectPanel={this.props.handleSelectPanel}
257+
errorMessage={this.props.errorMessage}
258+
forgotPassword={this.props.forgotPassword}
259+
closeForgotPassword={() =>
260+
this.setState({
261+
isForgotPasswordOpen: false,
262+
})
263+
}
264+
/>
363265
);
364266
}
365267

366-
private handleForgotPassword = (event: React.FormEvent<HTMLFormElement>) => {
367-
const { username } = this.state;
368-
const { forgotPassword } = this.props;
369-
const form = this.forgotPasswordRef.current;
370-
371-
event.preventDefault();
372-
if (form) {
373-
if (form.checkValidity()) {
374-
forgotPassword(username);
375-
}
376-
form.classList.add('was-validated');
377-
}
378-
};
379-
380268
private handleLogin = (event: React.FormEvent<HTMLFormElement>) => {
381269
const { login } = this.props;
382270
const { username, password } = this.state;

src/app/components/Authentication/Register.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export class Register extends React.Component<RegisterInterfaces.Props, Register
7070
};
7171

7272
public componentDidMount() {
73+
this.props.updateErrorMessage('');
7374
window.addEventListener('beforeunload', this.resetErrorMessage);
7475
}
7576
public componentWillReceiveProps(newProps: RegisterInterfaces.Props) {

src/app/sagas/User.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,20 @@ export function* forgotPassword(action: ActionType<typeof UserActions.forgotPass
248248
try {
249249
const res = yield call(UserFetch.userForgotPassword, action.payload.email);
250250

251+
if (res === 'Password Reset URL sent to the registered email!') {
252+
yield put(
253+
NotificationActions.success(`Password reset URL have been sent to ${action.payload.email}`),
254+
);
255+
}
256+
251257
// Call returns error if username already exists, else empty
252-
yield put(UserActions.updateErrorMessage(res.error));
258+
const message =
259+
res === 'Invalid email'
260+
? 'Email is not registered'
261+
: res === 'Password Reset URL sent to the registered email!'
262+
? ' '
263+
: res;
264+
yield put(UserActions.updateErrorMessage(message));
253265
} catch (err) {
254266
console.error(err);
255267
}

0 commit comments

Comments
 (0)