diff --git a/packages/components-faraday/src/components/UserProfile/AccountDetails.js b/packages/components-faraday/src/components/UserProfile/AccountDetails.js index 5932cb212188af6b01e50312c1fa16c452d798d5..768c8a46ecafb78fb2b7ab543e18792365d92b03 100644 --- a/packages/components-faraday/src/components/UserProfile/AccountDetails.js +++ b/packages/components-faraday/src/components/UserProfile/AccountDetails.js @@ -6,7 +6,7 @@ import { compose, withHandlers, withState } from 'recompose' import AccountDetailsCard from './AccountDetailsCard' import AccountDetailsEdit from './AccountDetailsEdit' -const AccountDetails = ({ user, isEdit, setEditMode, journal }) => ( +const AccountDetails = ({ user, isEdit, setEditMode, journal, history }) => ( <Root> {isEdit ? ( <AccountDetailsEdit @@ -16,6 +16,7 @@ const AccountDetails = ({ user, isEdit, setEditMode, journal }) => ( /> ) : ( <AccountDetailsCard + history={history} journal={journal} setEditMode={setEditMode} user={user} diff --git a/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js b/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js index db9172efa60d07a2951ffc92d505042d8f593f7f..22dadc2aa731f7a0406cc81ff7e968b736bc709e 100644 --- a/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js +++ b/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js @@ -13,6 +13,7 @@ import { getUserTitle } from '../utils' const AccountDetailsCard = ({ user: { firstName = '', lastName = '', affiliation = '-', title = '' }, journal, + history, setEditMode, }) => ( <Fragment> @@ -48,7 +49,9 @@ const AccountDetailsCard = ({ <Row noMargin> <RowItem> <LinkText onClick={() => setEditMode(true)}>Edit details</LinkText> - <LinkText>Change Password</LinkText> + <LinkText onClick={() => history.push('/profile/change-password')}> + Change Password + </LinkText> </RowItem> </Row> </Fragment> diff --git a/packages/components-faraday/src/components/UserProfile/ChangePasswordPage.js b/packages/components-faraday/src/components/UserProfile/ChangePasswordPage.js new file mode 100644 index 0000000000000000000000000000000000000000..8405473a825dd6ea6de8b55e85e6794e0fd7be37 --- /dev/null +++ b/packages/components-faraday/src/components/UserProfile/ChangePasswordPage.js @@ -0,0 +1,98 @@ +import React from 'react' +import { compose } from 'recompose' +import { connect } from 'react-redux' +import { reduxForm } from 'redux-form' +import styled from 'styled-components' +import { required } from 'xpub-validators' +import { selectCurrentUser } from 'xpub-selectors' +import { Button, th, TextField, ValidatedField } from '@pubsweet/ui' +import { + onSubmitChangePassword as onSubmit, + changePasswordValidator, +} from '../utils' + +import { Row, RowItem, Label, Title, Err } from '../UIComponents/FormItems' + +const PasswordField = input => <TextField {...input} type="password" /> + +const ChangePassword = ({ history, handleSubmit, error }) => ( + <Root> + <Form onSubmit={handleSubmit}> + <Row> + <RowItem vertical> + <Title>Change Password</Title> + </RowItem> + </Row> + <Row> + <RowItem vertical> + <Label>Current Password *</Label> + <ValidatedField + component={PasswordField} + name="password" + validate={[required]} + /> + </RowItem> + </Row> + <Row> + <RowItem vertical> + <Label>New Password *</Label> + <ValidatedField + component={PasswordField} + name="newPassword" + validate={[required]} + /> + </RowItem> + </Row> + <Row> + <RowItem vertical> + <Label>Re-type password *</Label> + <ValidatedField + component={PasswordField} + name="confirmNewPassword" + validate={[required]} + /> + </RowItem> + </Row> + {error && ( + <Row> + <RowItem> + <Err>{error}</Err> + </RowItem> + </Row> + )} + <Row /> + <Row> + <Button onClick={history.goBack}>Cancel</Button> + <Button primary type="submit"> + Update + </Button> + </Row> + </Form> + </Root> +) + +export default compose( + connect(state => ({ + user: selectCurrentUser(state), + })), + reduxForm({ + form: 'changePassword', + onSubmit, + validate: changePasswordValidator, + }), +)(ChangePassword) + +// #region styles +const Root = styled.div` + display: flex; + flex-direction: column; + max-width: 30em; + margin: 0 auto; +` +const Form = styled.form` + background-color: ${th('colorBackground')}; + padding: ${th('gridUnit')}; + border: ${th('borderDefault')}; +` + +// #endregion diff --git a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js index 75f207cfbe9f5f499f07316e96b1c2ce95052a2d..64dd9d28ea62c185a147e141bf307b7fb3d0d084 100644 --- a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js +++ b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js @@ -19,7 +19,7 @@ const UserProfilePage = ({ history, user }) => ( title="Account Settings" underlined /> - <AccountDetails user={user} /> + <AccountDetails history={history} user={user} /> <EmailNotifications subscribed={get(user, 'subscription')} /> <LinkOrcID orcid={get(user, 'orcid')} /> </Root> diff --git a/packages/components-faraday/src/components/index.js b/packages/components-faraday/src/components/index.js index 54fdcb5734f6e26063cb699cc36f1a125707fdc1..ddc29a62c5815c67a17f33fafa4d8cdc1711077d 100644 --- a/packages/components-faraday/src/components/index.js +++ b/packages/components-faraday/src/components/index.js @@ -9,6 +9,7 @@ export { default as AuthorList } from './AuthorList/AuthorList' export { default as withVersion } from './Dashboard/withVersion.js' export { default as SortableList } from './SortableList/SortableList' export { default as UserProfilePage } from './UserProfile/UserProfilePage' +export { default as ChangePasswordPage } from './UserProfile/ChangePasswordPage' export { Decision } export { Components } diff --git a/packages/components-faraday/src/components/utils.js b/packages/components-faraday/src/components/utils.js index e6dbf37dfb89054bb010ff4761149584eed08515..e791983b430f03dc3936ed552c02c846ad6f6534 100644 --- a/packages/components-faraday/src/components/utils.js +++ b/packages/components-faraday/src/components/utils.js @@ -98,6 +98,20 @@ export const passwordValidator = values => { return errors } +export const changePasswordValidator = values => { + const errors = {} + if (!values.password) { + errors.password = 'Required' + } + if (!values.newPassword) { + errors.newPassword = 'Required' + } else if (values.newPassword !== values.confirmNewPassword) { + errors.confirmNewPassword = 'Password mismatched' + } + + return errors +} + export const parseSearchParams = url => { const params = new URLSearchParams(url) const parsedObject = {} @@ -124,6 +138,7 @@ export const parseUpdateUser = values => { return pick(values, valuesToSave) } +// TODO: move to a dataservice export const onSubmitUser = (values, dispatch, { setEditMode }) => update(`/users/${values.id}`, parseUpdateUser(values)) .then(user => { @@ -131,3 +146,11 @@ export const onSubmitUser = (values, dispatch, { setEditMode }) => dispatch(actions.getCurrentUser()) }) .catch(handleFormError) + +// Temporary till API implementation +export const onSubmitChangePassword = (values, dispatch, { history, user }) => + update(`/users/${values.id}`, parseUpdateUser(values)) + .then(() => { + history.goBack() + }) + .catch(handleFormError) diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js index 77dff3d32b1d050dcbb4dee794d1d9d913416960..826ed981b7f01bdab32619dac5de12f1d87e7124 100644 --- a/packages/xpub-faraday/app/routes.js +++ b/packages/xpub-faraday/app/routes.js @@ -3,7 +3,10 @@ import { Route, Switch } from 'react-router-dom' import { AuthenticatedComponent } from 'pubsweet-client' import { Wizard } from 'pubsweet-component-wizard/src/components' -import { UserProfilePage } from 'pubsweet-components-faraday/src/components' +import { + UserProfilePage, + ChangePasswordPage, +} from 'pubsweet-components-faraday/src/components' import { ManuscriptPage } from 'pubsweet-component-manuscript/src/components' import DashboardPage from 'pubsweet-components-faraday/src/components/Dashboard' import LoginPage from 'pubsweet-components-faraday/src/components/Login/LoginPage' @@ -83,6 +86,11 @@ const Routes = () => ( <Route component={ConfirmAccount} exact path="/confirm-signup" /> <PrivateRoute component={DashboardPage} exact path="/" /> <PrivateRoute component={UserProfilePage} exact path="/profile" /> + <PrivateRoute + component={ChangePasswordPage} + exact + path="/profile/change-password" + /> <PrivateRoute component={ConfirmationPage} exact