From b429a783151bced3dde1c0aae869f6d5089b2a4b Mon Sep 17 00:00:00 2001 From: Bestin Date: Sat, 29 Feb 2020 02:38:53 +0530 Subject: [PATCH 1/9] Add ChangePassword component --- package.json | 2 +- src/app/actions/User.ts | 4 + src/app/apiFetch/User.ts | 23 ++++ .../Authentication/ChangePassword.tsx | 114 ++++++++++++++++++ .../Authentication/ChangePassword.ts | 17 +++ src/app/index.tsx | 5 + src/app/routes.ts | 1 + src/app/sagas/User.ts | 14 +++ .../types/Authentication/ChangePassword.ts | 11 ++ src/app/types/User.ts | 5 + 10 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/app/components/Authentication/ChangePassword.tsx create mode 100644 src/app/containers/Authentication/ChangePassword.ts create mode 100644 src/app/types/Authentication/ChangePassword.ts diff --git a/package.json b/package.json index 2ef15be9..b4fff3a5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "predeploy": "npm run build", "test": "jest -i", - "start": "webpack-dev-server --mode development --hot --progress --color --port 3000", + "start": "webpack-dev-server --mode development --hot --progress --color --port 3000 --host 0.0.0.0", "build": "webpack -p --progress --colors", "lint": "prettier --write \"src/**/*.{ts,tsx,css}\" \"__tests__/**/*.{ts,tsx,css}\" && tslint --project .", "lint:fix": "tslint --project . --fix" diff --git a/src/app/actions/User.ts b/src/app/actions/User.ts index 7b57822d..db95a12a 100644 --- a/src/app/actions/User.ts +++ b/src/app/actions/User.ts @@ -10,6 +10,7 @@ export namespace UserActions { GET_USER_DETAILS = 'GET_USER_DETAILS', EDIT_USER_PROFILE = 'EDIT_USER_PROFILE', EDIT_USER_PASSWORD = 'EDIT_USER_PASSWORD', + CHANGE_USER_PASSWORD = 'CHANGE_USER_PASSWORD', UPDATE_ERROR_MESSAGE = 'UPDATE_ERROR_MESSAGE', UPDATE_USER_DETAILS = 'UPDATE_USER_DETAILS', CHECK_EMAIL_EXISTS = 'CHECK_EMAIL_EXISTS', @@ -70,6 +71,9 @@ export namespace UserActions { export const checkUsernameExists = (username: string) => action(Type.CHECK_USERNAME_EXISTS, { username }); + export const changeUserPassword = (changePasswordDetails: UserInterfaces.ChangeUserPassword) => + action(Type.CHANGE_USER_PASSWORD, changePasswordDetails); + export const toggleUserProfileModal = (isUserProfileModalOpen: boolean) => action(Type.TOGGLE_USER_PROFILE_MODAL, { isUserProfileModalOpen }); diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index 8b5dcc8a..27e9a0ba 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -131,6 +131,29 @@ export const userEditPassword = (body: UserInterfaces.EditUserPassword) => { }); }; +export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { + return fetch(`${API_BASE_URL}user/password`, { + body: JSON.stringify(body), + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + }) + .then((response) => { + console.log('api fetch response'); + console.log(response); + return response.json(); + }) + .then((data) => { + console.log('api fetch data'); + console.log(data); + return data; + }) + .catch((error) => { + console.error(error); + }); +}; + export const userGetDetails = () => { return fetch(`${API_BASE_URL}user`, { credentials: 'include', diff --git a/src/app/components/Authentication/ChangePassword.tsx b/src/app/components/Authentication/ChangePassword.tsx new file mode 100644 index 00000000..37bcce40 --- /dev/null +++ b/src/app/components/Authentication/ChangePassword.tsx @@ -0,0 +1,114 @@ +import * as authStyles from 'app/styles/Authentication.module.css'; +import * as registerStyles from 'app/styles/Register.module.css'; +import { changePasswordProps } from 'app/types/Authentication/ChangePassword'; +import classnames from 'classnames'; +import * as React from 'react'; + +// tslint:disable-next-line: variable-name +export const ChangePassword: React.FunctionComponent = ( + props: changePasswordProps, +) => { + let passwordResetToken: string; + const [password, setPassword] = React.useState(''); + const [repeatPassword, setRepeatPassword] = React.useState(''); + const [passwordError, setpasswordError] = React.useState(''); + const submitPassword = (e: React.MouseEvent) => { + e.preventDefault(); + if (password !== '') { + if (password.length >= 5) { + if (password === repeatPassword) { + setpasswordError(''); + props.changePassword({ + passwordResetToken, + newPassword: password, + }); + } else { + setpasswordError('Password and confirm passwords have different values'); + } + } else { + setpasswordError('Password should have minimum 5 letters'); + } + } else { + setpasswordError('Password cannot be empty'); + } + }; + React.useEffect(() => { + // get string from url + passwordResetToken = 'token from url'; + }); + return ( +
+
+

Reset Password

+

Enter your new password

+
+
+
+
+
New Password
+
+ setPassword(e.target.value)} + required + /> +
+ Password should have minimum 5 characters. +
+
+
Confirm Password
+
+ setRepeatPassword(e.target.value)} + required + /> +
+ +
+
+ {passwordError} + {'\n'} + {props.errorMessage} +
+
+
+ +
+
+
+
+
+ ); +}; diff --git a/src/app/containers/Authentication/ChangePassword.ts b/src/app/containers/Authentication/ChangePassword.ts new file mode 100644 index 00000000..da36565a --- /dev/null +++ b/src/app/containers/Authentication/ChangePassword.ts @@ -0,0 +1,17 @@ +import { UserActions } from 'app/actions'; +import { ChangePassword } from 'app/components/Authentication/ChangePassword'; +import { RootState } from 'app/reducers'; +import { DispatchProps, StateProps } from 'app/types/Authentication/ChangePassword'; +import { connect } from 'react-redux'; + +const mapStateToProps = (rootState: RootState) => { + return { + errorMessage: rootState.user.errorMessage, + }; +}; + +const changePasswordContainer = connect(mapStateToProps, { + changePassword: UserActions.changeUserPassword, +})(ChangePassword); + +export default changePasswordContainer; diff --git a/src/app/index.tsx b/src/app/index.tsx index d70d20c7..fb8d1b95 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -1,4 +1,8 @@ +<<<<<<< HEAD import ActivateUser from 'app/containers/Authentication/ActivateUser'; +======= +import ChangePassword from 'app/containers/Authentication/ChangePassword'; +>>>>>>> Add ChangePassword component import Login from 'app/containers/Authentication/Login'; import Register from 'app/containers/Authentication/Register'; import Dashboard from 'app/containers/Dashboard'; @@ -25,6 +29,7 @@ export const App = hot(module)(() => ( + diff --git a/src/app/routes.ts b/src/app/routes.ts index 7b0c8cb8..9fcb5030 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -7,4 +7,5 @@ export enum Routes { GITHUB_OAUTH = '/login/github', GOOGLE_OAUTH = '/login/google', USER_ACTIVATION = '/user-activate', + CHANGE_PASSWORD = '/forgot-password', } diff --git a/src/app/sagas/User.ts b/src/app/sagas/User.ts index c3435890..3b396e0d 100644 --- a/src/app/sagas/User.ts +++ b/src/app/sagas/User.ts @@ -14,6 +14,7 @@ import * as UserFetch from 'app/apiFetch/User'; import { checkAuthentication } from 'app/sagas/utils'; import { avatarName } from 'app/types/Authentication/Register'; import { resType } from 'app/types/sagas'; +import { push } from 'react-router-redux'; import { all, call, put, takeEvery } from 'redux-saga/effects'; import { ActionType } from 'typesafe-actions'; @@ -209,6 +210,18 @@ export function* editUserPassword(action: ActionType) { + try { + const res = yield call(UserFetch.changeUserPassword, action.payload); + + if (res.status === 200 || res.status === 201) { + yield put(push('/login')); + } else yield put(UserActions.updateErrorMessage(res.message)); + } catch (err) { + console.error(err); + } +} + export function* checkEmailExists(action: ActionType) { try { const res = yield call(UserFetch.checkEmailExists, action.payload.email); @@ -253,6 +266,7 @@ export function* userSagas() { takeEvery(UserActions.Type.REGISTER, register), takeEvery(UserActions.Type.EDIT_USER_PROFILE, editUserProfile), takeEvery(UserActions.Type.EDIT_USER_PASSWORD, editUserPassword), + takeEvery(UserActions.Type.CHANGE_USER_PASSWORD, changeUserPassword), takeEvery(UserActions.Type.LOGIN, login), takeEvery(UserActions.Type.LOGOUT, logout), takeEvery(UserActions.Type.CHECK_EMAIL_EXISTS, checkEmailExists), diff --git a/src/app/types/Authentication/ChangePassword.ts b/src/app/types/Authentication/ChangePassword.ts new file mode 100644 index 00000000..46996a54 --- /dev/null +++ b/src/app/types/Authentication/ChangePassword.ts @@ -0,0 +1,11 @@ +import { ChangeUserPassword } from 'app/types/User'; + +export interface StateProps { + errorMessage: string; +} + +export interface DispatchProps { + changePassword: (changePasswordDetails: ChangeUserPassword) => void; +} + +export type changePasswordProps = StateProps & DispatchProps; diff --git a/src/app/types/User.ts b/src/app/types/User.ts index 99e8ab1a..079a8aca 100644 --- a/src/app/types/User.ts +++ b/src/app/types/User.ts @@ -30,6 +30,11 @@ export interface EditUserPassword { oldPassword?: string; } +export interface ChangeUserPassword { + newPassword: string; + passwordResetToken: string; +} + export interface Login { email: string; password: string; From 5fede1a15137f03a5cd9fe350135edc1c5ce5297 Mon Sep 17 00:00:00 2001 From: Bestin Date: Sat, 29 Feb 2020 16:07:05 +0530 Subject: [PATCH 2/9] get token from url --- package.json | 2 +- src/app/actions/User.ts | 7 +- src/app/apiFetch/User.ts | 1 + .../Authentication/ChangePassword.tsx | 233 ++++++++++-------- .../Authentication/ChangePassword.ts | 5 +- src/app/index.tsx | 3 - .../types/Authentication/ChangePassword.ts | 11 +- 7 files changed, 150 insertions(+), 112 deletions(-) diff --git a/package.json b/package.json index b4fff3a5..2ef15be9 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "predeploy": "npm run build", "test": "jest -i", - "start": "webpack-dev-server --mode development --hot --progress --color --port 3000 --host 0.0.0.0", + "start": "webpack-dev-server --mode development --hot --progress --color --port 3000", "build": "webpack -p --progress --colors", "lint": "prettier --write \"src/**/*.{ts,tsx,css}\" \"__tests__/**/*.{ts,tsx,css}\" && tslint --project .", "lint:fix": "tslint --project . --fix" diff --git a/src/app/actions/User.ts b/src/app/actions/User.ts index db95a12a..a3480910 100644 --- a/src/app/actions/User.ts +++ b/src/app/actions/User.ts @@ -71,8 +71,11 @@ export namespace UserActions { export const checkUsernameExists = (username: string) => action(Type.CHECK_USERNAME_EXISTS, { username }); - export const changeUserPassword = (changePasswordDetails: UserInterfaces.ChangeUserPassword) => - action(Type.CHANGE_USER_PASSWORD, changePasswordDetails); + export const changeUserPassword = (newPassword: string, passwordResetToken: string) => + action(Type.CHANGE_USER_PASSWORD, { + newPassword, + passwordResetToken, + }); export const toggleUserProfileModal = (isUserProfileModalOpen: boolean) => action(Type.TOGGLE_USER_PROFILE_MODAL, { isUserProfileModalOpen }); diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index 27e9a0ba..fb5347c8 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -138,6 +138,7 @@ export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { Accept: 'application/json', 'Content-Type': 'application/json', }, + method: 'POST', }) .then((response) => { console.log('api fetch response'); diff --git a/src/app/components/Authentication/ChangePassword.tsx b/src/app/components/Authentication/ChangePassword.tsx index 37bcce40..311f345a 100644 --- a/src/app/components/Authentication/ChangePassword.tsx +++ b/src/app/components/Authentication/ChangePassword.tsx @@ -1,114 +1,143 @@ import * as authStyles from 'app/styles/Authentication.module.css'; import * as registerStyles from 'app/styles/Register.module.css'; -import { changePasswordProps } from 'app/types/Authentication/ChangePassword'; +import { changePasswordProps, ChangePasswordState } from 'app/types/Authentication/ChangePassword'; import classnames from 'classnames'; import * as React from 'react'; -// tslint:disable-next-line: variable-name -export const ChangePassword: React.FunctionComponent = ( - props: changePasswordProps, -) => { - let passwordResetToken: string; - const [password, setPassword] = React.useState(''); - const [repeatPassword, setRepeatPassword] = React.useState(''); - const [passwordError, setpasswordError] = React.useState(''); - const submitPassword = (e: React.MouseEvent) => { +export class ChangePassword extends React.Component { + private credentialsFormRef = React.createRef(); + private passwordResetToken = ''; + constructor(props: changePasswordProps) { + super(props); + this.state = { + password: '', + passwordError: '', + repeatPassword: '', + }; + } + + public componentDidMount() { + // get string from url + const search = this.props.location.search; + this.passwordResetToken = search.split('=')[1]; + } + + public render() { + return ( +
+
+

Reset Password

+

Enter your new password

+
+
+
+
+ +
New Password
+
+ + this.setState({ + password: e.target.value, + }) + } + required + /> +
+ Password should have minimum 5 characters. +
+
+
Confirm Password
+
+ + this.setState({ + repeatPassword: e.target.value, + }) + } + required + /> +
+ +
+
+ {this.state.passwordError} + {'\n'} + {this.props.errorMessage} +
+
+
+ +
+ +
+ +
+
+ ); + } + + private submitPassword = (e: React.MouseEvent) => { e.preventDefault(); - if (password !== '') { - if (password.length >= 5) { - if (password === repeatPassword) { - setpasswordError(''); - props.changePassword({ - passwordResetToken, - newPassword: password, + if (this.state.password === this.state.repeatPassword) { + if (this.credentialsFormRef.current) { + this.credentialsFormRef.current.classList.add('was-validated'); + if (this.credentialsFormRef.current.checkValidity()) { + this.setState({ + ...this.state, + passwordError: '', }); - } else { - setpasswordError('Password and confirm passwords have different values'); + this.props.changePassword(this.state.password, this.passwordResetToken); } - } else { - setpasswordError('Password should have minimum 5 letters'); } } else { - setpasswordError('Password cannot be empty'); + this.setState({ + ...this.state, + passwordError: 'Password and confirm passwords have different values', + }); } }; - React.useEffect(() => { - // get string from url - passwordResetToken = 'token from url'; - }); - return ( -
-
-

Reset Password

-

Enter your new password

-
-
-
-
-
New Password
-
- setPassword(e.target.value)} - required - /> -
- Password should have minimum 5 characters. -
-
-
Confirm Password
-
- setRepeatPassword(e.target.value)} - required - /> -
- -
-
- {passwordError} - {'\n'} - {props.errorMessage} -
-
-
- -
-
-
-
-
- ); -}; +} diff --git a/src/app/containers/Authentication/ChangePassword.ts b/src/app/containers/Authentication/ChangePassword.ts index da36565a..93c64536 100644 --- a/src/app/containers/Authentication/ChangePassword.ts +++ b/src/app/containers/Authentication/ChangePassword.ts @@ -3,6 +3,7 @@ import { ChangePassword } from 'app/components/Authentication/ChangePassword'; import { RootState } from 'app/reducers'; import { DispatchProps, StateProps } from 'app/types/Authentication/ChangePassword'; import { connect } from 'react-redux'; +import { withRouter } from 'react-router'; const mapStateToProps = (rootState: RootState) => { return { @@ -10,8 +11,10 @@ const mapStateToProps = (rootState: RootState) => { }; }; +const componentWithRouter = withRouter(ChangePassword); + const changePasswordContainer = connect(mapStateToProps, { changePassword: UserActions.changeUserPassword, -})(ChangePassword); +})(componentWithRouter); export default changePasswordContainer; diff --git a/src/app/index.tsx b/src/app/index.tsx index fb8d1b95..49d531db 100644 --- a/src/app/index.tsx +++ b/src/app/index.tsx @@ -1,8 +1,5 @@ -<<<<<<< HEAD import ActivateUser from 'app/containers/Authentication/ActivateUser'; -======= import ChangePassword from 'app/containers/Authentication/ChangePassword'; ->>>>>>> Add ChangePassword component import Login from 'app/containers/Authentication/Login'; import Register from 'app/containers/Authentication/Register'; import Dashboard from 'app/containers/Dashboard'; diff --git a/src/app/types/Authentication/ChangePassword.ts b/src/app/types/Authentication/ChangePassword.ts index 46996a54..0d0a9374 100644 --- a/src/app/types/Authentication/ChangePassword.ts +++ b/src/app/types/Authentication/ChangePassword.ts @@ -1,11 +1,16 @@ -import { ChangeUserPassword } from 'app/types/User'; +import { RouteComponentProps } from 'react-router-dom'; +export interface ChangePasswordState { + password: string; + repeatPassword: string; + passwordError: string; +} export interface StateProps { errorMessage: string; } export interface DispatchProps { - changePassword: (changePasswordDetails: ChangeUserPassword) => void; + changePassword: (password: string, passwordResetToken: string) => void; } -export type changePasswordProps = StateProps & DispatchProps; +export type changePasswordProps = StateProps & DispatchProps & RouteComponentProps; From c5dd4c30ae6c897b56cf76b07b75add3dcbb6fc1 Mon Sep 17 00:00:00 2001 From: Bestin Date: Sun, 1 Mar 2020 20:26:51 +0530 Subject: [PATCH 3/9] add forgot password in login --- .../__snapshots__/Login.test.tsx.snap | 1 + src/app/actions/User.ts | 10 +- src/app/apiFetch/User.ts | 25 +- .../Authentication/ChangePassword.tsx | 9 +- src/app/components/Authentication/Login.tsx | 319 ++++++++++++++---- .../Authentication/ChangePassword.ts | 5 +- src/app/containers/Authentication/Login.ts | 1 + src/app/routes.ts | 2 +- src/app/sagas/User.ts | 18 +- src/app/styles/Authentication.module.css | 10 + .../types/Authentication/ChangePassword.ts | 2 +- src/app/types/Authentication/Login.ts | 3 + src/app/types/User.ts | 5 + 13 files changed, 325 insertions(+), 85 deletions(-) diff --git a/__tests__/app/containers/Authentication/__snapshots__/Login.test.tsx.snap b/__tests__/app/containers/Authentication/__snapshots__/Login.test.tsx.snap index efd2a5a7..c4db6d25 100644 --- a/__tests__/app/containers/Authentication/__snapshots__/Login.test.tsx.snap +++ b/__tests__/app/containers/Authentication/__snapshots__/Login.test.tsx.snap @@ -3,6 +3,7 @@ exports[`Login Container Should render 1`] = ` action(Type.CHECK_USERNAME_EXISTS, { username }); - export const changeUserPassword = (newPassword: string, passwordResetToken: string) => + export const changeUserPassword = ( + newPassword: string, + passwordResetToken: string, + userId: number, + ) => action(Type.CHANGE_USER_PASSWORD, { newPassword, passwordResetToken, + userId, }); export const toggleUserProfileModal = (isUserProfileModalOpen: boolean) => @@ -89,4 +95,6 @@ export namespace UserActions { export const setIsLoginLoading = (isLoginLoading: boolean) => action(Type.SET_IS_LOGIN_LOADING, { isLoginLoading }); + + export const forgotPassword = (email: string) => action(Type.FORGOT_PASSWORD, { email }); } diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index fb5347c8..706537e0 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -135,19 +135,32 @@ export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { return fetch(`${API_BASE_URL}user/password`, { body: JSON.stringify(body), headers: { - Accept: 'application/json', 'Content-Type': 'application/json', }, method: 'POST', }) .then((response) => { - console.log('api fetch response'); - console.log(response); - return response.json(); + return headResponseWrapper(response, HeadReqType.USERNAME); + }) + .then((data) => { + return data; + }) + .catch((error) => { + console.error(error); + }); +}; +export const userForgotPassword = (email: string) => { + return fetch(`${API_BASE_URL}user/forgot-password`, { + body: email, + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + }) + .then((response) => { + return response.text(); }) .then((data) => { - console.log('api fetch data'); - console.log(data); return data; }) .catch((error) => { diff --git a/src/app/components/Authentication/ChangePassword.tsx b/src/app/components/Authentication/ChangePassword.tsx index 311f345a..6ad682ca 100644 --- a/src/app/components/Authentication/ChangePassword.tsx +++ b/src/app/components/Authentication/ChangePassword.tsx @@ -7,6 +7,7 @@ import * as React from 'react'; export class ChangePassword extends React.Component { private credentialsFormRef = React.createRef(); private passwordResetToken = ''; + private userId = 0; constructor(props: changePasswordProps) { super(props); this.state = { @@ -19,7 +20,9 @@ export class ChangePassword extends React.Component { private loginRef = React.createRef(); + private forgotPasswordRef = React.createRef(); constructor(props: LoginInterfaces.Props) { super(props); this.state = { + isForgotPassword: false, password: '', username: '', }; @@ -59,28 +61,30 @@ export class Login extends React.Component; } - - return ( -
-
-

Welcome!

-

Log in to access your dashboard and profile

-
- You can use your{' '} - - Pragyan - {' '} - account credentials to login. + if (!isForgotPassword) { + return ( +
+
+

Welcome!

+

Log in to access your dashboard and profile

+
+ You can use your{' '} + + Pragyan + {' '} + account credentials to login. +
+<<<<<<< HEAD
{' '} Please enter a valid Email.{' '} +======= + + +
+
+
+
+
Email
+
+ + this.setState({ + username: e.target.value, + }) + } + /> +
+ {' '} + Please enter a valid Email.{' '} +
+>>>>>>> add forgot password in login
-
-
-
-
Password
-
- - this.setState({ - password: e.target.value, - }) - } - required - /> -
- Please enter the correct password. +
+
+
Password
+
+ + this.setState({ + password: e.target.value, + }) + } + required + /> +
+ Please enter the correct password. +
-
-
-
- {errorMessage} +
+
+ {errorMessage} +
-
-
-
- +
+
+ +
+ +
+ + + +
this.setState({ isForgotPassword: true })} + > + Forgot Your Password?{' '}
- + +
+ + + + + +
+ ); + } + return ( +
+
+
+

Forgot your password?

+<<<<<<< HEAD @@ -221,17 +297,126 @@ export class Login extends React.Component +
+
>>>>>> add forgot password in login > - Create one - +
+
+
Your Email:
+
+ + this.setState({ + username: e.target.value, + }) + } + /> +
+ {' '} + Please enter a valid Email.{' '} +
+
+
+
+ +
+
+ {errorMessage} +
+
+
+
+ +
+
+
+<<<<<<< HEAD
+======= + + + +
this.setState({ isForgotPassword: false })} + > + Back{' '} +
+ +
+ + + + + +
+>>>>>>> add forgot password in login
); } + private handleForgotPassword = (event: React.FormEvent) => { + const { username } = this.state; + const { forgotPassword } = this.props; + const form = this.forgotPasswordRef.current; + + event.preventDefault(); + if (form) { + if (form.checkValidity()) { + forgotPassword(username); + } + form.classList.add('was-validated'); + } + }; + private handleLogin = (event: React.FormEvent) => { const { login } = this.props; const { username, password } = this.state; diff --git a/src/app/containers/Authentication/ChangePassword.ts b/src/app/containers/Authentication/ChangePassword.ts index 93c64536..da36565a 100644 --- a/src/app/containers/Authentication/ChangePassword.ts +++ b/src/app/containers/Authentication/ChangePassword.ts @@ -3,7 +3,6 @@ import { ChangePassword } from 'app/components/Authentication/ChangePassword'; import { RootState } from 'app/reducers'; import { DispatchProps, StateProps } from 'app/types/Authentication/ChangePassword'; import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; const mapStateToProps = (rootState: RootState) => { return { @@ -11,10 +10,8 @@ const mapStateToProps = (rootState: RootState) => { }; }; -const componentWithRouter = withRouter(ChangePassword); - const changePasswordContainer = connect(mapStateToProps, { changePassword: UserActions.changeUserPassword, -})(componentWithRouter); +})(ChangePassword); export default changePasswordContainer; diff --git a/src/app/containers/Authentication/Login.ts b/src/app/containers/Authentication/Login.ts index 7f3eee77..7d900daf 100644 --- a/src/app/containers/Authentication/Login.ts +++ b/src/app/containers/Authentication/Login.ts @@ -15,6 +15,7 @@ const mapStateToProps = (rootState: RootState) => { const loginContainer = connect( mapStateToProps, { + forgotPassword: UserActions.forgotPassword, login: UserActions.login, updateErrorMessage: UserActions.updateErrorMessage, }, diff --git a/src/app/routes.ts b/src/app/routes.ts index 9fcb5030..174ec139 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -7,5 +7,5 @@ export enum Routes { GITHUB_OAUTH = '/login/github', GOOGLE_OAUTH = '/login/google', USER_ACTIVATION = '/user-activate', - CHANGE_PASSWORD = '/forgot-password', + CHANGE_PASSWORD = '/reset-password', } diff --git a/src/app/sagas/User.ts b/src/app/sagas/User.ts index 3b396e0d..6fa2c14b 100644 --- a/src/app/sagas/User.ts +++ b/src/app/sagas/User.ts @@ -15,6 +15,7 @@ import { checkAuthentication } from 'app/sagas/utils'; import { avatarName } from 'app/types/Authentication/Register'; import { resType } from 'app/types/sagas'; import { push } from 'react-router-redux'; +// import { push } from 'react-router-redux'; import { all, call, put, takeEvery } from 'redux-saga/effects'; import { ActionType } from 'typesafe-actions'; @@ -213,10 +214,11 @@ export function* editUserPassword(action: ActionType) { try { const res = yield call(UserFetch.changeUserPassword, action.payload); + yield put(UserActions.updateErrorMessage(res.error ? res.body.message : '')); - if (res.status === 200 || res.status === 201) { + if (res.type !== resType.ERROR) { yield put(push('/login')); - } else yield put(UserActions.updateErrorMessage(res.message)); + } } catch (err) { console.error(err); } @@ -244,6 +246,17 @@ export function* checkUsernameExists(action: ActionType) { + try { + const res = yield call(UserFetch.userForgotPassword, action.payload.email); + + // Call returns error if username already exists, else empty + yield put(UserActions.updateErrorMessage(res)); + } catch (err) { + console.error(err); + } +} + export function* resetAppState(action: ActionType) { try { yield put(CodeActions.resetCodeState()); @@ -273,5 +286,6 @@ export function* userSagas() { takeEvery(UserActions.Type.CHECK_USERNAME_EXISTS, checkUsernameExists), takeEvery(UserActions.Type.GET_USER_DETAILS, getUserDetails), takeEvery(UserActions.Type.RESET_APP_STATE, resetAppState), + takeEvery(UserActions.Type.FORGOT_PASSWORD, forgotPassword), ]); } diff --git a/src/app/styles/Authentication.module.css b/src/app/styles/Authentication.module.css index 37c00f98..9bf8836d 100755 --- a/src/app/styles/Authentication.module.css +++ b/src/app/styles/Authentication.module.css @@ -491,6 +491,7 @@ position: relative; left: 1%; } +<<<<<<< HEAD .google-btn { font-size: 18px; background-color: white; @@ -567,4 +568,13 @@ font-size: 1rem; background: #fff; padding: 0 10px; +======= + +.forgot-your-password { + cursor: pointer; +} + +.forgot-your-password:hover { + color: #4630eb !important; +>>>>>>> add forgot password in login } diff --git a/src/app/types/Authentication/ChangePassword.ts b/src/app/types/Authentication/ChangePassword.ts index 0d0a9374..15888467 100644 --- a/src/app/types/Authentication/ChangePassword.ts +++ b/src/app/types/Authentication/ChangePassword.ts @@ -10,7 +10,7 @@ export interface StateProps { } export interface DispatchProps { - changePassword: (password: string, passwordResetToken: string) => void; + changePassword: (password: string, passwordResetToken: string, userId: number) => void; } export type changePasswordProps = StateProps & DispatchProps & RouteComponentProps; diff --git a/src/app/types/Authentication/Login.ts b/src/app/types/Authentication/Login.ts index 2cbf9e8e..c2345b71 100644 --- a/src/app/types/Authentication/Login.ts +++ b/src/app/types/Authentication/Login.ts @@ -1,6 +1,7 @@ import { AuthType } from 'app/types/Authentication'; export interface State { + isForgotPassword: boolean; username: string; password: string; } @@ -15,7 +16,9 @@ export interface StateProps { } export interface DispatchProps { + forgotPassword: (email: string) => void; login: (username: string, password: string) => void; + updateErrorMessage: (errorMessage: string) => void; } diff --git a/src/app/types/User.ts b/src/app/types/User.ts index 079a8aca..ebb2c782 100644 --- a/src/app/types/User.ts +++ b/src/app/types/User.ts @@ -33,6 +33,7 @@ export interface EditUserPassword { export interface ChangeUserPassword { newPassword: string; passwordResetToken: string; + userId: number; } export interface Login { @@ -44,11 +45,15 @@ export interface ActivateUser { authToken: string; userId: number; } +export interface ForgotPassword { + email: string; +} const actions = { ActivateUser: UserActions.activateUser, editUserPassword: UserActions.editUserPassword, editUserProfile: UserActions.editUserProfile, + forgotPassword: UserActions.forgotPassword, getUserDetails: UserActions.getUserDetails, login: UserActions.login, logout: UserActions.logout, From 366721040970cb8f2ad32d554c103978ead56422 Mon Sep 17 00:00:00 2001 From: Bestin Date: Mon, 2 Mar 2020 00:27:39 +0530 Subject: [PATCH 4/9] fixup! add forgot password in login --- src/app/apiFetch/User.ts | 2 +- src/app/components/Authentication/Login.tsx | 288 +++++++++----------- src/app/sagas/User.ts | 10 +- src/app/styles/Authentication.module.css | 4 +- 4 files changed, 130 insertions(+), 174 deletions(-) diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index 706537e0..220372dc 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -140,7 +140,7 @@ export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { method: 'POST', }) .then((response) => { - return headResponseWrapper(response, HeadReqType.USERNAME); + return response; }) .then((data) => { return data; diff --git a/src/app/components/Authentication/Login.tsx b/src/app/components/Authentication/Login.tsx index bebbd661..fc891dca 100644 --- a/src/app/components/Authentication/Login.tsx +++ b/src/app/components/Authentication/Login.tsx @@ -1,7 +1,5 @@ import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { API_BASE_URL } from 'app/../config/config'; -import PopUpMenu from 'app/components/PopUpMenu'; import { Routes } from 'app/routes'; import * as styles from 'app/styles/Authentication.module.css'; import * as registerStyles from 'app/styles/Register.module.css'; @@ -11,11 +9,7 @@ import classnames from 'classnames'; import * as React from 'react'; import { Col, Row } from 'react-bootstrap'; import { Redirect } from 'react-router-dom'; - -export enum OAUTH_ROUTES { - GOOGLE = 'login/google', - GITHUB = 'login/github', -} +import { API_BASE_URL } from '../../../config/config'; export class Login extends React.Component { private loginRef = React.createRef(); @@ -61,7 +55,7 @@ export class Login extends React.Component; @@ -84,80 +78,48 @@ export class Login extends React.Component
-<<<<<<< HEAD -
-
- { - window.location.href = `${API_BASE_URL}${OAUTH_ROUTES.GOOGLE}`; - }} - className={classnames( - styles['google-btn'], - 'border justify-content-center my-3', - styles.oauth_btn, - styles.no_margin, - )} - > -
- -
-

Log in with Google

-
- { - window.location.href = `${API_BASE_URL}${OAUTH_ROUTES.GITHUB}`; - }} - className={classnames( - 'justify-content-center', - styles['github-btn'], - styles.oauth_btn, - styles.no_margin, - )} - > -
- -
-

Log in with Github

-
- -
-
- or +
+ { + window.location.href = `${API_BASE_URL}${Routes.GOOGLE_OAUTH}`; + }} + className={classnames( + styles['google-btn'], + 'border justify-content-center my-3', + styles.oauth_btn, + styles.no_margin, + )} + > +
+
-
- -
- -
-
Log in with Google

+ + { + window.location.href = `${API_BASE_URL}${Routes.GITHUB_OAUTH}`; + }} + className={classnames( + 'justify-content-center', + styles['github-btn'], + styles.oauth_btn, + styles.no_margin, + )} > -
-
-
Email
-
- - this.setState({ - username: e.target.value, - }) - } - /> -
- {' '} - Please enter a valid Email.{' '} -======= - - +
+ +
+

Log in with Github

+
+ +
+
+ or +
+
+
+
+
->>>>>>> add forgot password in login
@@ -261,7 +222,7 @@ export class Login extends React.Component
- Don't have an account?{' '} + Don't have an account?

Forgot your password?

-<<<<<<< HEAD - - - - + @@ -383,7 +340,7 @@ export class Login extends React.Component
- Don't have an account?{' '} + Don't have an account?
->>>>>>> add forgot password in login
); } diff --git a/src/app/sagas/User.ts b/src/app/sagas/User.ts index 6fa2c14b..e9d806dc 100644 --- a/src/app/sagas/User.ts +++ b/src/app/sagas/User.ts @@ -14,8 +14,6 @@ import * as UserFetch from 'app/apiFetch/User'; import { checkAuthentication } from 'app/sagas/utils'; import { avatarName } from 'app/types/Authentication/Register'; import { resType } from 'app/types/sagas'; -import { push } from 'react-router-redux'; -// import { push } from 'react-router-redux'; import { all, call, put, takeEvery } from 'redux-saga/effects'; import { ActionType } from 'typesafe-actions'; @@ -216,9 +214,13 @@ export function* changeUserPassword(action: ActionType>>>>>> add forgot password in login } From 43a49f34c1d93785fb01ac6ff543225795c63dcb Mon Sep 17 00:00:00 2001 From: Bestin Date: Mon, 2 Mar 2020 00:46:49 +0530 Subject: [PATCH 5/9] fixup! fixup! add forgot password in login --- src/app/components/Authentication/Login.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/components/Authentication/Login.tsx b/src/app/components/Authentication/Login.tsx index fc891dca..ae2ba8ac 100644 --- a/src/app/components/Authentication/Login.tsx +++ b/src/app/components/Authentication/Login.tsx @@ -11,6 +11,10 @@ import { Col, Row } from 'react-bootstrap'; import { Redirect } from 'react-router-dom'; import { API_BASE_URL } from '../../../config/config'; +export enum OAUTH_ROUTES { + GOOGLE = 'login/google', + GITHUB = 'login/github', +} export class Login extends React.Component { private loginRef = React.createRef(); private forgotPasswordRef = React.createRef(); @@ -81,7 +85,7 @@ export class Login extends React.Component { - window.location.href = `${API_BASE_URL}${Routes.GOOGLE_OAUTH}`; + window.location.href = `${API_BASE_URL}${OAUTH_ROUTES.GOOGLE}`; }} className={classnames( styles['google-btn'], @@ -97,7 +101,7 @@ export class Login extends React.Component { - window.location.href = `${API_BASE_URL}${Routes.GITHUB_OAUTH}`; + window.location.href = `${API_BASE_URL}${OAUTH_ROUTES.GITHUB}`; }} className={classnames( 'justify-content-center', From bc5d318462f224b5bc1b4c1cb86eb190fd595b52 Mon Sep 17 00:00:00 2001 From: kumaran-14 Date: Mon, 2 Mar 2020 19:58:13 +0530 Subject: [PATCH 6/9] Add fixes --- src/app/apiFetch/User.ts | 4 ++-- src/app/components/Authentication/Login.tsx | 16 ++++++++-------- src/app/sagas/User.ts | 8 ++------ src/app/types/Authentication/Login.ts | 3 +-- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index 220372dc..f21a6cb8 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -140,7 +140,7 @@ export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { method: 'POST', }) .then((response) => { - return response; + return jsonResponseWrapper(response); }) .then((data) => { return data; @@ -158,7 +158,7 @@ export const userForgotPassword = (email: string) => { method: 'POST', }) .then((response) => { - return response.text(); + return headResponseWrapper(response, HeadReqType.OTHERS); }) .then((data) => { return data; diff --git a/src/app/components/Authentication/Login.tsx b/src/app/components/Authentication/Login.tsx index ae2ba8ac..435a379f 100644 --- a/src/app/components/Authentication/Login.tsx +++ b/src/app/components/Authentication/Login.tsx @@ -1,5 +1,6 @@ import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { API_BASE_URL } from 'app/../config/config'; import { Routes } from 'app/routes'; import * as styles from 'app/styles/Authentication.module.css'; import * as registerStyles from 'app/styles/Register.module.css'; @@ -9,7 +10,6 @@ import classnames from 'classnames'; import * as React from 'react'; import { Col, Row } from 'react-bootstrap'; import { Redirect } from 'react-router-dom'; -import { API_BASE_URL } from '../../../config/config'; export enum OAUTH_ROUTES { GOOGLE = 'login/google', @@ -23,7 +23,7 @@ export class Login extends React.Component; } - if (!isForgotPassword) { + if (!isForgotPasswordOpen) { return (
@@ -217,7 +217,7 @@ export class Login extends React.Component
this.setState({ isForgotPassword: true })} + onClick={() => this.setState({ isForgotPasswordOpen: true })} > Forgot Your Password?{' '}
@@ -226,7 +226,7 @@ export class Login extends React.Component
- Don't have an account? + Don't have an account?{' '}
this.setState({ isForgotPassword: false })} + onClick={() => this.setState({ isForgotPasswordOpen: false })} > Back{' '}
@@ -344,7 +344,7 @@ export class Login extends React.Component
- Don't have an account? + Don't have an account?{' '} void; login: (username: string, password: string) => void; - updateErrorMessage: (errorMessage: string) => void; } From aa64fded2dbe084ab4674163d46ad684b30ea0d4 Mon Sep 17 00:00:00 2001 From: Bestin Date: Mon, 2 Mar 2020 23:44:18 +0530 Subject: [PATCH 7/9] change Forgot Password to Component --- src/app/apiFetch/Code.ts | 1 - src/app/apiFetch/User.ts | 2 +- .../Authentication/ForgotPassword.tsx | 143 ++++++++++++++++ src/app/components/Authentication/Login.tsx | 156 +++--------------- .../components/Authentication/Register.tsx | 1 + src/app/sagas/User.ts | 14 +- src/app/types/Authentication/Login.ts | 8 + 7 files changed, 188 insertions(+), 137 deletions(-) create mode 100644 src/app/components/Authentication/ForgotPassword.tsx diff --git a/src/app/apiFetch/Code.ts b/src/app/apiFetch/Code.ts index 07ba5f06..58d0961c 100644 --- a/src/app/apiFetch/Code.ts +++ b/src/app/apiFetch/Code.ts @@ -131,7 +131,6 @@ export const getLastSaveTime = () => { return textResponseWrapper(response); }) .then((data) => { - console.log(data); return data; }) .catch((error) => { diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index f21a6cb8..12cfed29 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -158,7 +158,7 @@ export const userForgotPassword = (email: string) => { method: 'POST', }) .then((response) => { - return headResponseWrapper(response, HeadReqType.OTHERS); + return response.text(); }) .then((data) => { return data; diff --git a/src/app/components/Authentication/ForgotPassword.tsx b/src/app/components/Authentication/ForgotPassword.tsx new file mode 100644 index 00000000..432c2bf0 --- /dev/null +++ b/src/app/components/Authentication/ForgotPassword.tsx @@ -0,0 +1,143 @@ +import * as styles from 'app/styles/Authentication.module.css'; +import classnames from 'classnames'; +import * as React from 'react'; +import { Col, Row } from 'react-bootstrap'; +import * as registerStyles from 'app/styles/Register.module.css'; +import { Routes } from 'app/routes'; +import * as LoginInterfaces from 'app/types/Authentication/Login'; +import { AuthType } from 'app/types/Authentication'; + +// tslint:disable-next-line: variable-name +const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => { + const forgotPasswordRef = React.createRef(); + const [username, setUsername] = React.useState(''); + + const handleForgotPassword = (event: React.FormEvent) => { + const form = forgotPasswordRef.current; + + event.preventDefault(); + if (form) { + if (form.checkValidity()) { + props.forgotPassword(username); + } + form.classList.add('was-validated'); + } + }; + + return ( +
+
+
+

Forgot your password?

+
+ + +
+ Don't have an account? + { + props.updateErrorMessage(''); + props.handleSelectPanel(AuthType.REGISTER); + }} + > + Create one + + +
+
+
+
+
Your Email:
+
+ setUsername(e.target.value)} + /> +
+ {' '} + Please enter a valid Email.{' '} +
+
+
+
+
+
+ {props.errorMessage} +
+
+
+
+ +
+
+
+
+
+
+ + + + +
props.closeForgotPassword()} + > + Back{' '} +
+ +
+ + + + + +
+
+ ); +}; + +export default ForgotPassword; diff --git a/src/app/components/Authentication/Login.tsx b/src/app/components/Authentication/Login.tsx index 435a379f..fcb2665c 100644 --- a/src/app/components/Authentication/Login.tsx +++ b/src/app/components/Authentication/Login.tsx @@ -1,6 +1,7 @@ import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { API_BASE_URL } from 'app/../config/config'; +import ForgotPassword from 'app/components/Authentication/ForgotPassword'; import { Routes } from 'app/routes'; import * as styles from 'app/styles/Authentication.module.css'; import * as registerStyles from 'app/styles/Register.module.css'; @@ -17,7 +18,6 @@ export enum OAUTH_ROUTES { } export class Login extends React.Component { private loginRef = React.createRef(); - private forgotPasswordRef = React.createRef(); constructor(props: LoginInterfaces.Props) { super(props); @@ -35,6 +35,7 @@ export class Login extends React.Component; } + if (this.props.errorMessage === ' ' && this.state.isForgotPasswordOpen) { + this.setState({ + isForgotPasswordOpen: false, + }); + updateErrorMessage(''); + } if (!isForgotPasswordOpen) { return (
@@ -182,14 +189,14 @@ export class Login extends React.Component
-
-
-

Forgot your password?

-
- - -
- Don't have an account? - { - updateErrorMessage(''); - this.props.handleSelectPanel(AuthType.REGISTER); - }} - > - Create one - - -
-
-
-
-
Your Email:
-
- - this.setState({ - username: e.target.value, - }) - } - /> -
- {' '} - Please enter a valid Email.{' '} -
-
-
-
-
-
- {errorMessage} -
-
-
-
- -
-
-
-
-
-
- -
- - -
this.setState({ isForgotPasswordOpen: false })} - > - Back{' '} -
- -
- - - - - -
-
+ + this.setState({ + isForgotPasswordOpen: false, + }) + } + /> ); } - private handleForgotPassword = (event: React.FormEvent) => { - const { username } = this.state; - const { forgotPassword } = this.props; - const form = this.forgotPasswordRef.current; - - event.preventDefault(); - if (form) { - if (form.checkValidity()) { - forgotPassword(username); - } - form.classList.add('was-validated'); - } - }; - private handleLogin = (event: React.FormEvent) => { const { login } = this.props; const { username, password } = this.state; diff --git a/src/app/components/Authentication/Register.tsx b/src/app/components/Authentication/Register.tsx index 2a1f3186..6dd0ad0e 100644 --- a/src/app/components/Authentication/Register.tsx +++ b/src/app/components/Authentication/Register.tsx @@ -70,6 +70,7 @@ export class Register extends React.Component void; } +export interface ForgotPasswordProps { + updateErrorMessage: (errorMessage: string) => void; + handleSelectPanel: (authType: AuthType) => void; + closeForgotPassword: () => void; + errorMessage: string; + forgotPassword: (email: string) => void; +} + export type Props = ElementOwnProps & StateProps & DispatchProps; From c523e5e558133dfb90c6bfb252e0b29e9bd575dd Mon Sep 17 00:00:00 2001 From: Bestin Date: Tue, 3 Mar 2020 08:48:38 +0530 Subject: [PATCH 8/9] fixup! change Forgot Password to Component --- src/app/apiFetch/User.ts | 9 +++-- src/app/apiFetch/utils/index.ts | 3 ++ .../Authentication/ForgotPassword.tsx | 15 ++++---- src/app/components/Authentication/Login.tsx | 35 ++++++++++++------- src/app/types/Authentication/Login.ts | 2 ++ 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/app/apiFetch/User.ts b/src/app/apiFetch/User.ts index 12cfed29..c503eb21 100644 --- a/src/app/apiFetch/User.ts +++ b/src/app/apiFetch/User.ts @@ -1,5 +1,10 @@ /* tslint:disable:no-console*/ -import { HeadReqType, headResponseWrapper, jsonResponseWrapper } from 'app/apiFetch/utils'; +import { + HeadReqType, + headResponseWrapper, + jsonResponseWrapper, + textResponseWrapper, +} from 'app/apiFetch/utils'; import * as UserInterfaces from 'app/types/User'; import { API_BASE_URL } from '../../config/config'; @@ -140,7 +145,7 @@ export const changeUserPassword = (body: UserInterfaces.ChangeUserPassword) => { method: 'POST', }) .then((response) => { - return jsonResponseWrapper(response); + return textResponseWrapper(response); }) .then((data) => { return data; diff --git a/src/app/apiFetch/utils/index.ts b/src/app/apiFetch/utils/index.ts index cd609447..fb8ec5a7 100644 --- a/src/app/apiFetch/utils/index.ts +++ b/src/app/apiFetch/utils/index.ts @@ -90,8 +90,11 @@ export function textResponseWrapper(response: any) { case 302: case 409: case 401: + case 404: + case 403: case 500: case 403: + case 501: error = 'Oops! Something went wrong.'; type = resType.ERROR; } diff --git a/src/app/components/Authentication/ForgotPassword.tsx b/src/app/components/Authentication/ForgotPassword.tsx index 432c2bf0..a1d47999 100644 --- a/src/app/components/Authentication/ForgotPassword.tsx +++ b/src/app/components/Authentication/ForgotPassword.tsx @@ -1,16 +1,15 @@ +import { Routes } from 'app/routes'; import * as styles from 'app/styles/Authentication.module.css'; +import * as registerStyles from 'app/styles/Register.module.css'; +import { AuthType } from 'app/types/Authentication'; +import * as LoginInterfaces from 'app/types/Authentication/Login'; import classnames from 'classnames'; import * as React from 'react'; import { Col, Row } from 'react-bootstrap'; -import * as registerStyles from 'app/styles/Register.module.css'; -import { Routes } from 'app/routes'; -import * as LoginInterfaces from 'app/types/Authentication/Login'; -import { AuthType } from 'app/types/Authentication'; // tslint:disable-next-line: variable-name const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => { const forgotPasswordRef = React.createRef(); - const [username, setUsername] = React.useState(''); const handleForgotPassword = (event: React.FormEvent) => { const form = forgotPasswordRef.current; @@ -18,7 +17,7 @@ const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => { event.preventDefault(); if (form) { if (form.checkValidity()) { - props.forgotPassword(username); + props.forgotPassword(props.username); } form.classList.add('was-validated'); } @@ -62,8 +61,8 @@ const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => { id="validationUsername" aria-describedby="inputGroupPrepend" required - value={username} - onChange={(e) => setUsername(e.target.value)} + value={props.username} + onChange={(e) => props.setUsername(e.target.value)} />
{' '} diff --git a/src/app/components/Authentication/Login.tsx b/src/app/components/Authentication/Login.tsx index fcb2665c..e93bd664 100644 --- a/src/app/components/Authentication/Login.tsx +++ b/src/app/components/Authentication/Login.tsx @@ -2,6 +2,7 @@ import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { API_BASE_URL } from 'app/../config/config'; import ForgotPassword from 'app/components/Authentication/ForgotPassword'; +import PopUpMenu from 'app/components/PopUpMenu'; import { Routes } from 'app/routes'; import * as styles from 'app/styles/Authentication.module.css'; import * as registerStyles from 'app/styles/Register.module.css'; @@ -65,7 +66,7 @@ export class Login extends React.Component; } - if (this.props.errorMessage === ' ' && this.state.isForgotPasswordOpen) { + if (errorMessage === ' ' && isForgotPasswordOpen) { this.setState({ isForgotPasswordOpen: false, }); @@ -247,21 +248,31 @@ export class Login extends React.Component +
); } return ( - - this.setState({ - isForgotPasswordOpen: false, - }) - } - /> +
+ + this.setState({ + username: newUsername, + }) + } + closeForgotPassword={() => + this.setState({ + isForgotPasswordOpen: false, + }) + } + /> + +
); } diff --git a/src/app/types/Authentication/Login.ts b/src/app/types/Authentication/Login.ts index 77efb6a1..9c020162 100644 --- a/src/app/types/Authentication/Login.ts +++ b/src/app/types/Authentication/Login.ts @@ -26,6 +26,8 @@ export interface ForgotPasswordProps { handleSelectPanel: (authType: AuthType) => void; closeForgotPassword: () => void; errorMessage: string; + username: string; + setUsername: (username: string) => void; forgotPassword: (email: string) => void; } From b132c3a0b293fac5bd2133e51cdb833586ca19f2 Mon Sep 17 00:00:00 2001 From: Bestin Date: Tue, 3 Mar 2020 20:06:43 +0530 Subject: [PATCH 9/9] fixup! fixup! change Forgot Password to Component --- src/app/components/Authentication/ForgotPassword.tsx | 11 ----------- src/app/components/Authentication/Login.tsx | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/app/components/Authentication/ForgotPassword.tsx b/src/app/components/Authentication/ForgotPassword.tsx index a1d47999..246ef40e 100644 --- a/src/app/components/Authentication/ForgotPassword.tsx +++ b/src/app/components/Authentication/ForgotPassword.tsx @@ -32,17 +32,6 @@ const ForgotPassword = (props: LoginInterfaces.ForgotPasswordProps) => {