mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-28 20:53:24 +10:00
Merge pull request #434 from sharetribe/change-password
Change password
This commit is contained in:
commit
2d6f52fc99
14 changed files with 419 additions and 10 deletions
|
|
@ -34,7 +34,7 @@
|
|||
"redux-thunk": "^2.2.0",
|
||||
"sanitize.css": "^5.0.0",
|
||||
"sharetribe-scripts": "0.9.2",
|
||||
"sharetribe-sdk": "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#2c7f3d323c5e7a7c4c93ef38962c236859b83bab",
|
||||
"sharetribe-sdk": "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#e2fe4c3be061bfbefdb2db1fa5ed2a8a5d4d4ffe",
|
||||
"source-map-support": "^0.4.15",
|
||||
"url": "^0.11.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,6 +56,6 @@
|
|||
|
||||
@media (--viewportMedium) {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 31px;
|
||||
margin-bottom: 47px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
60
src/containers/PasswordChangeForm/PasswordChangeForm.css
Normal file
60
src/containers/PasswordChangeForm/PasswordChangeForm.css
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
.root {}
|
||||
|
||||
.newPasswordSection {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 46px;
|
||||
padding-top: 6px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-bottom: 56px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirmChangesSection {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 60px;
|
||||
padding: 0;
|
||||
|
||||
@media (--viewportLarge) {
|
||||
padding: 4px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.confirmChangesTitle {
|
||||
/* Font */
|
||||
color: var(--matterColorAnti);
|
||||
|
||||
margin-top: 0;
|
||||
margin-bottom: 13px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-top: 0;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-top: 0;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.confirmChangesInfo {
|
||||
margin-top: 0;
|
||||
margin-bottom: 37px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-bottom: 46px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottomWrapper {
|
||||
margin-top: 46px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-top: 96px;
|
||||
}
|
||||
}
|
||||
182
src/containers/PasswordChangeForm/PasswordChangeForm.js
Normal file
182
src/containers/PasswordChangeForm/PasswordChangeForm.js
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import { compose } from 'redux';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
|
||||
import classNames from 'classnames';
|
||||
import * as validators from '../../util/validators';
|
||||
import { ensureCurrentUser } from '../../util/data';
|
||||
import { isForbiddenChangePasswordError } from '../../util/errors';
|
||||
import { PrimaryButton, TextInputField } from '../../components';
|
||||
|
||||
import css from './PasswordChangeForm.css';
|
||||
|
||||
const RESET_TIMEOUT = 800;
|
||||
|
||||
class PasswordChangeFormComponent extends Component {
|
||||
componentWillUnmount() {
|
||||
window.clearTimeout(this.resetTimeoutId);
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
rootClassName,
|
||||
className,
|
||||
changePasswordError,
|
||||
currentUser,
|
||||
form,
|
||||
handleSubmit,
|
||||
submitting,
|
||||
inProgress,
|
||||
intl,
|
||||
invalid,
|
||||
ready,
|
||||
reset,
|
||||
} = this.props;
|
||||
|
||||
const user = ensureCurrentUser(currentUser);
|
||||
|
||||
if (!user.id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// New password
|
||||
const newPasswordLabel = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.newPasswordLabel',
|
||||
});
|
||||
const newPasswordPlaceholder = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.newPasswordPlaceholder',
|
||||
});
|
||||
const newPasswordRequiredMessage = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.newPasswordRequired',
|
||||
});
|
||||
const newPasswordRequired = validators.required(newPasswordRequiredMessage);
|
||||
|
||||
const passwordMinLengthMessage = intl.formatMessage(
|
||||
{
|
||||
id: 'PasswordChangeForm.passwordTooShort',
|
||||
},
|
||||
{
|
||||
minLength: validators.PASSWORD_MIN_LENGTH,
|
||||
}
|
||||
);
|
||||
const passwordMaxLengthMessage = intl.formatMessage(
|
||||
{
|
||||
id: 'PasswordChangeForm.passwordTooLong',
|
||||
},
|
||||
{
|
||||
maxLength: validators.PASSWORD_MAX_LENGTH,
|
||||
}
|
||||
);
|
||||
|
||||
const passwordMinLength = validators.minLength(
|
||||
passwordMinLengthMessage,
|
||||
validators.PASSWORD_MIN_LENGTH
|
||||
);
|
||||
const passwordMaxLength = validators.maxLength(
|
||||
passwordMaxLengthMessage,
|
||||
validators.PASSWORD_MAX_LENGTH
|
||||
);
|
||||
|
||||
// password
|
||||
const passwordLabel = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.passwordLabel',
|
||||
});
|
||||
const passwordPlaceholder = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.passwordPlaceholder',
|
||||
});
|
||||
const passwordRequiredMessage = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.passwordRequired',
|
||||
});
|
||||
|
||||
const passwordRequired = validators.required(passwordRequiredMessage);
|
||||
|
||||
const passwordFailedMessage = intl.formatMessage({
|
||||
id: 'PasswordChangeForm.passwordFailed',
|
||||
});
|
||||
const passwordErrorText = isForbiddenChangePasswordError(changePasswordError)
|
||||
? passwordFailedMessage
|
||||
: null;
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const submitDisabled = invalid || submitting || inProgress;
|
||||
|
||||
return (
|
||||
<form
|
||||
className={classes}
|
||||
onSubmit={values => {
|
||||
handleSubmit(values).then(() => {
|
||||
this.resetTimeoutId = window.setTimeout(reset, RESET_TIMEOUT);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div className={css.newPasswordSection}>
|
||||
<TextInputField
|
||||
type="password"
|
||||
name="newPassword"
|
||||
id={`${form}.newPassword`}
|
||||
label={newPasswordLabel}
|
||||
placeholder={newPasswordPlaceholder}
|
||||
validate={[newPasswordRequired, passwordMinLength, passwordMaxLength]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={css.confirmChangesSection}>
|
||||
<h3 className={css.confirmChangesTitle}>
|
||||
<FormattedMessage id="PasswordChangeForm.confirmChangesTitle" />
|
||||
</h3>
|
||||
<p className={css.confirmChangesInfo}>
|
||||
<FormattedMessage id="PasswordChangeForm.confirmChangesInfo" />
|
||||
</p>
|
||||
|
||||
<TextInputField
|
||||
className={css.password}
|
||||
type="password"
|
||||
name="currentPassword"
|
||||
id={`${form}.currentPassword`}
|
||||
label={passwordLabel}
|
||||
placeholder={passwordPlaceholder}
|
||||
validate={[passwordRequired, passwordMinLength, passwordMaxLength]}
|
||||
customErrorText={passwordErrorText}
|
||||
/>
|
||||
</div>
|
||||
<div className={css.bottomWrapper}>
|
||||
<PrimaryButton
|
||||
className={css.submitButton}
|
||||
type="submit"
|
||||
inProgress={inProgress}
|
||||
ready={ready}
|
||||
disabled={submitDisabled}
|
||||
>
|
||||
<FormattedMessage id="PasswordChangeForm.saveChanges" />
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PasswordChangeFormComponent.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
changePasswordError: null,
|
||||
inProgress: false,
|
||||
};
|
||||
|
||||
const { bool, instanceOf, string } = PropTypes;
|
||||
|
||||
PasswordChangeFormComponent.propTypes = {
|
||||
...formPropTypes,
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
changePasswordError: instanceOf(Error),
|
||||
inProgress: bool,
|
||||
intl: intlShape.isRequired,
|
||||
ready: bool.isRequired,
|
||||
};
|
||||
|
||||
const defaultFormName = 'PasswordChangeForm';
|
||||
|
||||
const PasswordChangeForm = compose(reduxForm({ form: defaultFormName }), injectIntl)(
|
||||
PasswordChangeFormComponent
|
||||
);
|
||||
|
||||
export default PasswordChangeForm;
|
||||
|
|
@ -1,5 +1,23 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
.content {
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin: 32px auto 0 auto;
|
||||
max-width: 564px;
|
||||
}
|
||||
|
||||
@media (--viewportLarge) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.desktopTopbar,
|
||||
.mobileTopbar {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
|
@ -13,7 +31,7 @@
|
|||
@media (--viewportLarge) {
|
||||
min-height: auto;
|
||||
flex-direction: column;
|
||||
margin-top: 4px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,3 +49,13 @@
|
|||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 19px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 47px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
66
src/containers/PasswordChangePage/PasswordChangePage.duck.js
Normal file
66
src/containers/PasswordChangePage/PasswordChangePage.duck.js
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
// ================ Action types ================ //
|
||||
|
||||
export const CHANGE_PASSWORD_REQUEST = 'app/PasswordChangePage/CHANGE_PASSWORD_REQUEST';
|
||||
export const CHANGE_PASSWORD_SUCCESS = 'app/PasswordChangePage/CHANGE_PASSWORD_SUCCESS';
|
||||
export const CHANGE_PASSWORD_ERROR = 'app/PasswordChangePage/CHANGE_PASSWORD_ERROR';
|
||||
|
||||
export const CHANGE_PASSWORD_CLEAR = 'app/PasswordChangePage/CHANGE_PASSWORD_CLEAR';
|
||||
|
||||
// ================ Reducer ================ //
|
||||
|
||||
const initialState = {
|
||||
changePasswordError: null,
|
||||
changePasswordInProgress: false,
|
||||
passwordChanged: false,
|
||||
};
|
||||
|
||||
export default function reducer(state = initialState, action = {}) {
|
||||
const { type, payload } = action;
|
||||
switch (type) {
|
||||
case CHANGE_PASSWORD_REQUEST:
|
||||
return {
|
||||
...state,
|
||||
changePasswordInProgress: true,
|
||||
changePasswordError: null,
|
||||
passwordChanged: false,
|
||||
};
|
||||
case CHANGE_PASSWORD_SUCCESS:
|
||||
return { ...state, changePasswordInProgress: false, passwordChanged: true };
|
||||
case CHANGE_PASSWORD_ERROR:
|
||||
return { ...state, changePasswordInProgress: false, changePasswordError: payload };
|
||||
|
||||
case CHANGE_PASSWORD_CLEAR:
|
||||
return { ...initialState };
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
// ================ Action creators ================ //
|
||||
|
||||
export const changePasswordRequest = () => ({ type: CHANGE_PASSWORD_REQUEST });
|
||||
export const changePasswordSuccess = () => ({ type: CHANGE_PASSWORD_SUCCESS });
|
||||
export const changePasswordError = error => ({
|
||||
type: CHANGE_PASSWORD_ERROR,
|
||||
payload: error,
|
||||
error: true,
|
||||
});
|
||||
|
||||
export const changePasswordClear = () => ({ type: CHANGE_PASSWORD_CLEAR });
|
||||
|
||||
// ================ Thunks ================ //
|
||||
|
||||
export const changePassword = params =>
|
||||
(dispatch, getState, sdk) => {
|
||||
dispatch(changePasswordRequest());
|
||||
const { newPassword, currentPassword } = params;
|
||||
|
||||
return sdk.currentUser
|
||||
.changePassword({ newPassword, currentPassword })
|
||||
.then(() => dispatch(changePasswordSuccess()))
|
||||
.catch(e => {
|
||||
dispatch(changePasswordError(e));
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
|
|
@ -17,13 +17,17 @@ import {
|
|||
TopbarWrapper,
|
||||
UserNav,
|
||||
} from '../../components';
|
||||
import { PasswordChangeForm } from '../../containers';
|
||||
|
||||
import { changePassword, changePasswordClear } from './PasswordChangePage.duck';
|
||||
import css from './PasswordChangePage.css';
|
||||
|
||||
export const PasswordChangePageComponent = props => {
|
||||
const {
|
||||
authInfoError,
|
||||
authInProgress,
|
||||
changePasswordError,
|
||||
changePasswordInProgress,
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
currentUserHasOrders,
|
||||
|
|
@ -32,8 +36,11 @@ export const PasswordChangePageComponent = props => {
|
|||
location,
|
||||
logoutError,
|
||||
notificationCount,
|
||||
onChange,
|
||||
onLogout,
|
||||
onManageDisableScrolling,
|
||||
onSubmitChangePassword,
|
||||
passwordChanged,
|
||||
sendVerificationEmailInProgress,
|
||||
sendVerificationEmailError,
|
||||
onResendVerificationEmail,
|
||||
|
|
@ -56,6 +63,18 @@ export const PasswordChangePageComponent = props => {
|
|||
},
|
||||
];
|
||||
|
||||
const changePasswordForm = currentUser && currentUser.id
|
||||
? <PasswordChangeForm
|
||||
className={css.form}
|
||||
changePasswordError={changePasswordError}
|
||||
currentUser={currentUser}
|
||||
onSubmit={onSubmitChangePassword}
|
||||
onChange={onChange}
|
||||
inProgress={changePasswordInProgress}
|
||||
ready={passwordChanged}
|
||||
/>
|
||||
: null;
|
||||
|
||||
return (
|
||||
<PageLayout authInfoError={authInfoError} logoutError={logoutError} title="Contact details">
|
||||
<LayoutSideNavigation>
|
||||
|
|
@ -82,7 +101,12 @@ export const PasswordChangePageComponent = props => {
|
|||
<TabNav rootClassName={css.tabs} tabRootClassName={css.tab} tabs={tabs} />
|
||||
</SideNavWrapper>
|
||||
<ContentWrapper>
|
||||
Main content
|
||||
<div className={css.content}>
|
||||
<h1 className={css.title}>
|
||||
<FormattedMessage id="PasswordChangePage.title" />
|
||||
</h1>
|
||||
{changePasswordForm}
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
</LayoutSideNavigation>
|
||||
</PageLayout>
|
||||
|
|
@ -91,6 +115,7 @@ export const PasswordChangePageComponent = props => {
|
|||
|
||||
PasswordChangePageComponent.defaultProps = {
|
||||
authInfoError: null,
|
||||
changePasswordError: null,
|
||||
currentUser: null,
|
||||
currentUserHasOrders: null,
|
||||
logoutError: null,
|
||||
|
|
@ -103,14 +128,19 @@ const { bool, func, instanceOf, number, object, shape } = PropTypes;
|
|||
PasswordChangePageComponent.propTypes = {
|
||||
authInfoError: instanceOf(Error),
|
||||
authInProgress: bool.isRequired,
|
||||
changePasswordError: instanceOf(Error),
|
||||
changePasswordInProgress: bool.isRequired,
|
||||
currentUser: propTypes.currentUser,
|
||||
currentUserHasListings: bool.isRequired,
|
||||
currentUserHasOrders: bool,
|
||||
isAuthenticated: bool.isRequired,
|
||||
logoutError: instanceOf(Error),
|
||||
notificationCount: number,
|
||||
onChange: func.isRequired,
|
||||
onLogout: func.isRequired,
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
onSubmitChangePassword: func.isRequired,
|
||||
passwordChanged: bool.isRequired,
|
||||
sendVerificationEmailInProgress: bool.isRequired,
|
||||
sendVerificationEmailError: instanceOf(Error),
|
||||
onResendVerificationEmail: func.isRequired,
|
||||
|
|
@ -126,6 +156,11 @@ const mapStateToProps = state => {
|
|||
// PageLayout needs authInfoError and logoutError, Topbar needs isAuthenticated
|
||||
const { authInfoError, isAuthenticated, logoutError } = state.Auth;
|
||||
// Topbar needs user info.
|
||||
const {
|
||||
changePasswordError,
|
||||
changePasswordInProgress,
|
||||
passwordChanged,
|
||||
} = state.PasswordChangePage;
|
||||
const {
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
|
|
@ -137,12 +172,15 @@ const mapStateToProps = state => {
|
|||
return {
|
||||
authInfoError,
|
||||
authInProgress: authenticationInProgress(state),
|
||||
changePasswordError,
|
||||
changePasswordInProgress,
|
||||
currentUser,
|
||||
currentUserHasListings,
|
||||
currentUserHasOrders,
|
||||
notificationCount,
|
||||
isAuthenticated,
|
||||
logoutError,
|
||||
passwordChanged,
|
||||
scrollingDisabled: isScrollingDisabled(state),
|
||||
sendVerificationEmailInProgress,
|
||||
sendVerificationEmailError,
|
||||
|
|
@ -150,10 +188,12 @@ const mapStateToProps = state => {
|
|||
};
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onChange: () => dispatch(changePasswordClear()),
|
||||
onLogout: historyPush => dispatch(logout(historyPush)),
|
||||
onManageDisableScrolling: (componentId, disableScrolling) =>
|
||||
dispatch(manageDisableScrolling(componentId, disableScrolling)),
|
||||
onResendVerificationEmail: () => dispatch(sendVerificationEmail()),
|
||||
onSubmitChangePassword: values => dispatch(changePassword(values)),
|
||||
});
|
||||
|
||||
const PasswordChangePage = compose(connect(mapStateToProps, mapDispatchToProps), withRouter)(
|
||||
|
|
|
|||
|
|
@ -15,10 +15,14 @@ describe('PasswordChangePage', () => {
|
|||
authInProgress={false}
|
||||
currentUserHasListings={false}
|
||||
isAuthenticated={false}
|
||||
onChange={noop}
|
||||
onLogout={noop}
|
||||
onManageDisableScrolling={noop}
|
||||
sendVerificationEmailInProgress={false}
|
||||
onResendVerificationEmail={noop}
|
||||
onSubmitChangePassword={noop}
|
||||
changePasswordInProgress={false}
|
||||
passwordChanged={false}
|
||||
/>
|
||||
);
|
||||
expect(tree).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -72,7 +72,13 @@ exports[`PasswordChangePage matches snapshot 1`] = `
|
|||
<ContentWrapper
|
||||
className={null}
|
||||
rootClassName={null}>
|
||||
Main content
|
||||
<div>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id="PasswordChangePage.title"
|
||||
values={Object {}} />
|
||||
</h1>
|
||||
</div>
|
||||
</ContentWrapper>
|
||||
</LayoutSideNavigation>
|
||||
</withRouter(PageLayout)>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import LoginForm from './LoginForm/LoginForm';
|
|||
import ManageListingsPage from './ManageListingsPage/ManageListingsPage';
|
||||
import NotFoundPage from './NotFoundPage/NotFoundPage';
|
||||
import OrderPage from './OrderPage/OrderPage';
|
||||
import PasswordChangeForm from './PasswordChangeForm/PasswordChangeForm';
|
||||
import PasswordChangePage from './PasswordChangePage/PasswordChangePage';
|
||||
import PasswordRecoveryForm from './PasswordRecoveryForm/PasswordRecoveryForm';
|
||||
import PasswordRecoveryPage from './PasswordRecoveryPage/PasswordRecoveryPage';
|
||||
|
|
@ -59,6 +60,7 @@ export {
|
|||
ManageListingsPage,
|
||||
NotFoundPage,
|
||||
OrderPage,
|
||||
PasswordChangeForm,
|
||||
PasswordChangePage,
|
||||
PasswordRecoveryForm,
|
||||
PasswordRecoveryPage,
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@ import InboxPage from './InboxPage/InboxPage.duck';
|
|||
import ListingPage from './ListingPage/ListingPage.duck';
|
||||
import ManageListingsPage from './ManageListingsPage/ManageListingsPage.duck';
|
||||
import OrderPage from './OrderPage/OrderPage.duck';
|
||||
import PasswordChangePage from './PasswordChangePage/PasswordChangePage.duck';
|
||||
import PasswordRecoveryPage from './PasswordRecoveryPage/PasswordRecoveryPage.duck';
|
||||
import PasswordResetPage from './PasswordResetPage/PasswordResetPage.duck';
|
||||
import ProfileSettingsPage from './ProfileSettingsPage/ProfileSettingsPage.duck';
|
||||
import SalePage from './SalePage/SalePage.duck';
|
||||
import SearchPage from './SearchPage/SearchPage.duck';
|
||||
import PasswordRecoveryPage from './PasswordRecoveryPage/PasswordRecoveryPage.duck';
|
||||
|
||||
export {
|
||||
CheckoutPage,
|
||||
|
|
@ -24,9 +25,10 @@ export {
|
|||
ListingPage,
|
||||
ManageListingsPage,
|
||||
OrderPage,
|
||||
PasswordChangePage,
|
||||
PasswordRecoveryPage,
|
||||
PasswordResetPage,
|
||||
ProfileSettingsPage,
|
||||
SalePage,
|
||||
SearchPage,
|
||||
PasswordRecoveryPage,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
"ContactDetailsForm.emailRequired": "Email is required",
|
||||
"ContactDetailsForm.emailUnverified": "You haven't verified your email yet. {resendEmailLink}",
|
||||
"ContactDetailsForm.emailVerified": "Your email is verified.",
|
||||
"ContactDetailsForm.passwordFailed": "You entered wrong password",
|
||||
"ContactDetailsForm.passwordFailed": "Please double-check your password",
|
||||
"ContactDetailsForm.passwordLabel": "Current password",
|
||||
"ContactDetailsForm.passwordPlaceholder": "Enter your current password…",
|
||||
"ContactDetailsForm.passwordRequired": "Password is required",
|
||||
|
|
@ -240,8 +240,21 @@
|
|||
"PaginationLinks.next": "Next page",
|
||||
"PaginationLinks.previous": "Previous page",
|
||||
"PaginationLinks.toPage": "Go to page {page}",
|
||||
"PasswordChangeForm.confirmChangesInfo": "To change your password, you need to enter your current password.",
|
||||
"PasswordChangeForm.confirmChangesTitle": "Confirm your changes",
|
||||
"PasswordChangeForm.newPasswordLabel": "New password",
|
||||
"PasswordChangeForm.newPasswordPlaceholder": "Enter your new password",
|
||||
"PasswordChangeForm.newPasswordRequired": "New password is required",
|
||||
"PasswordChangeForm.passwordFailed": "Please double-check your current password",
|
||||
"PasswordChangeForm.passwordLabel": "Current password",
|
||||
"PasswordChangeForm.passwordPlaceholder": "Enter your current password…",
|
||||
"PasswordChangeForm.passwordRequired": "Current password is required",
|
||||
"PasswordChangeForm.passwordTooLong": "Password should be at most {maxLength} characters",
|
||||
"PasswordChangeForm.passwordTooShort": "Password should be at least {minLength} characters",
|
||||
"PasswordChangeForm.saveChanges": "Save changes",
|
||||
"PasswordChangePage.emailTabTitle": "Email",
|
||||
"PasswordChangePage.passwordTabTitle": "Password",
|
||||
"PasswordChangePage.title": "Password settings",
|
||||
"PasswordRecoveryForm.emailLabel": "Email",
|
||||
"PasswordRecoveryForm.emailNotFound": "Hmm. We didn't find an account with that email. Please double-check your email and try again.",
|
||||
"PasswordRecoveryForm.emailPlaceholder": "john.doe@example.com",
|
||||
|
|
|
|||
|
|
@ -94,3 +94,9 @@ export const isTransactionInitiateListingNotFoundError = apiError => {
|
|||
* is due to giving wrong password.
|
||||
*/
|
||||
export const isForbiddenChangeEmailError = apiError => apiError && apiError.status === 403;
|
||||
|
||||
/**
|
||||
* Check if the given API error (from `sdk.currentUser.changePassword(params)`)
|
||||
* is due to giving wrong password.
|
||||
*/
|
||||
export const isForbiddenChangePasswordError = apiError => apiError && apiError.status === 403;
|
||||
|
|
|
|||
|
|
@ -6128,9 +6128,9 @@ sharetribe-scripts@0.9.2:
|
|||
optionalDependencies:
|
||||
fsevents "1.0.17"
|
||||
|
||||
"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#2c7f3d323c5e7a7c4c93ef38962c236859b83bab":
|
||||
"sharetribe-sdk@git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#e2fe4c3be061bfbefdb2db1fa5ed2a8a5d4d4ffe":
|
||||
version "0.0.1"
|
||||
resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#2c7f3d323c5e7a7c4c93ef38962c236859b83bab"
|
||||
resolved "git+ssh://git@github.com/sharetribe/sharetribe-sdk-js#e2fe4c3be061bfbefdb2db1fa5ed2a8a5d4d4ffe"
|
||||
dependencies:
|
||||
axios "^0.15.3"
|
||||
js-cookie "^2.1.3"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue