mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-01-16 08:33:15 +05:30
#147: add validation errors for first stem of ChangeEmail
This commit is contained in:
parent
d6df492073
commit
6160e4a0bc
@ -5,7 +5,7 @@ import classNames from 'classnames';
|
|||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import { Motion, spring } from 'react-motion';
|
import { Motion, spring } from 'react-motion';
|
||||||
|
|
||||||
import { Input, Button, Form, FormModel } from 'components/ui/form';
|
import { Input, Button, Form, FormModel, FormError } from 'components/ui/form';
|
||||||
import { BackButton } from 'components/profile/ProfileForm';
|
import { BackButton } from 'components/profile/ProfileForm';
|
||||||
import styles from 'components/profile/profileForm.scss';
|
import styles from 'components/profile/profileForm.scss';
|
||||||
import helpLinks from 'components/auth/helpLinks.scss';
|
import helpLinks from 'components/auth/helpLinks.scss';
|
||||||
@ -181,7 +181,7 @@ export default class ChangeEmail extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStep0({email}) {
|
renderStep0({email, form}) {
|
||||||
return (
|
return (
|
||||||
<div className={styles.formBody}>
|
<div className={styles.formBody}>
|
||||||
<div className={styles.formRow}>
|
<div className={styles.formRow}>
|
||||||
@ -194,6 +194,8 @@ export default class ChangeEmail extends Component {
|
|||||||
<h2 className={changeEmail.currentAccountEmail}>
|
<h2 className={changeEmail.currentAccountEmail}>
|
||||||
{email}
|
{email}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
<FormError error={form.getError('email')} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.formRow}>
|
<div className={styles.formRow}>
|
||||||
|
17
src/components/ui/form/FormError.jsx
Normal file
17
src/components/ui/form/FormError.jsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React, { PropTypes } from 'react';
|
||||||
|
|
||||||
|
import errorsDict from 'services/errorsDict';
|
||||||
|
|
||||||
|
import styles from './form.scss';
|
||||||
|
|
||||||
|
export default function FormError({error}) {
|
||||||
|
return error ? (
|
||||||
|
<div className={styles.fieldError}>
|
||||||
|
{errorsDict.resolve(error)}
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormError.propTypes = {
|
||||||
|
error: PropTypes.string
|
||||||
|
};
|
@ -1,9 +1,7 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
|
|
||||||
import errorsDict from 'services/errorsDict';
|
|
||||||
|
|
||||||
import styles from './form.scss';
|
|
||||||
import FormComponent from './FormComponent';
|
import FormComponent from './FormComponent';
|
||||||
|
import FormError from './FormError';
|
||||||
|
|
||||||
export default class FormInputComponent extends FormComponent {
|
export default class FormInputComponent extends FormComponent {
|
||||||
static displayName = 'FormInputComponent';
|
static displayName = 'FormInputComponent';
|
||||||
@ -27,15 +25,7 @@ export default class FormInputComponent extends FormComponent {
|
|||||||
renderError() {
|
renderError() {
|
||||||
const error = this.state && this.state.error || this.props.error;
|
const error = this.state && this.state.error || this.props.error;
|
||||||
|
|
||||||
if (error) {
|
return <FormError error={error} />;
|
||||||
return (
|
|
||||||
<div className={styles.fieldError}>
|
|
||||||
{errorsDict.resolve(error)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setError(error) {
|
setError(error) {
|
||||||
|
@ -13,7 +13,7 @@ export default class FormModel {
|
|||||||
*
|
*
|
||||||
* @param {string} name - the name of field
|
* @param {string} name - the name of field
|
||||||
*
|
*
|
||||||
* @return {Object} ref and name props for component
|
* @return {object} - ref and name props for component
|
||||||
*/
|
*/
|
||||||
bindField(name) {
|
bindField(name) {
|
||||||
this.fields[name] = {};
|
this.fields[name] = {};
|
||||||
@ -36,6 +36,11 @@ export default class FormModel {
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focuses field
|
||||||
|
*
|
||||||
|
* @param {string} fieldId - an id of field to focus
|
||||||
|
*/
|
||||||
focus(fieldId) {
|
focus(fieldId) {
|
||||||
if (!this.fields[fieldId]) {
|
if (!this.fields[fieldId]) {
|
||||||
throw new Error(`Can not focus. The field with an id ${fieldId} does not exists`);
|
throw new Error(`Can not focus. The field with an id ${fieldId} does not exists`);
|
||||||
@ -44,6 +49,13 @@ export default class FormModel {
|
|||||||
this.fields[fieldId].focus();
|
this.fields[fieldId].focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value of field
|
||||||
|
*
|
||||||
|
* @param {string} fieldId - an id of field to get value of
|
||||||
|
*
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
value(fieldId) {
|
value(fieldId) {
|
||||||
const field = this.fields[fieldId];
|
const field = this.fields[fieldId];
|
||||||
|
|
||||||
@ -58,6 +70,11 @@ export default class FormModel {
|
|||||||
return field.getValue();
|
return field.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add errors to form fields
|
||||||
|
*
|
||||||
|
* @param {object} errors - object maping {fieldId: errorMessage}
|
||||||
|
*/
|
||||||
setErrors(errors) {
|
setErrors(errors) {
|
||||||
const oldErrors = this.errors;
|
const oldErrors = this.errors;
|
||||||
this.errors = errors;
|
this.errors = errors;
|
||||||
@ -69,14 +86,29 @@ export default class FormModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get error by id
|
||||||
|
*
|
||||||
|
* @param {string} fieldId - an id of field to get error for
|
||||||
|
*
|
||||||
|
* @return {string|null}
|
||||||
|
*/
|
||||||
getError(fieldId) {
|
getError(fieldId) {
|
||||||
return this.errors[fieldId] || null;
|
return this.errors[fieldId] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
hasErrors() {
|
hasErrors() {
|
||||||
return Object.keys(this.errors).length > 0;
|
return Object.keys(this.errors).length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert form into key-value object representation
|
||||||
|
*
|
||||||
|
* @return {object}
|
||||||
|
*/
|
||||||
serialize() {
|
serialize() {
|
||||||
return Object.keys(this.fields).reduce((acc, fieldId) => {
|
return Object.keys(this.fields).reduce((acc, fieldId) => {
|
||||||
acc[fieldId] = this.fields[fieldId].getValue();
|
acc[fieldId] = this.fields[fieldId].getValue();
|
||||||
@ -88,7 +120,7 @@ export default class FormModel {
|
|||||||
/**
|
/**
|
||||||
* Bind handler to listen for form loading state change
|
* Bind handler to listen for form loading state change
|
||||||
*
|
*
|
||||||
* @param {Function} fn
|
* @param {function} fn
|
||||||
*/
|
*/
|
||||||
addLoadingListener(fn) {
|
addLoadingListener(fn) {
|
||||||
this.removeLoadingListener(fn);
|
this.removeLoadingListener(fn);
|
||||||
@ -98,22 +130,31 @@ export default class FormModel {
|
|||||||
/**
|
/**
|
||||||
* Remove form loading state handler
|
* Remove form loading state handler
|
||||||
*
|
*
|
||||||
* @param {Function} fn
|
* @param {function} fn
|
||||||
*/
|
*/
|
||||||
removeLoadingListener(fn) {
|
removeLoadingListener(fn) {
|
||||||
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
this.handlers = this.handlers.filter((handler) => handler !== fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Switch form in loading state
|
||||||
|
*/
|
||||||
beginLoading() {
|
beginLoading() {
|
||||||
this._isLoading = true;
|
this._isLoading = true;
|
||||||
this.notifyHandlers();
|
this.notifyHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable loading state
|
||||||
|
*/
|
||||||
endLoading() {
|
endLoading() {
|
||||||
this._isLoading = false;
|
this._isLoading = false;
|
||||||
this.notifyHandlers();
|
this.notifyHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
notifyHandlers() {
|
notifyHandlers() {
|
||||||
this.handlers.forEach((fn) => fn(this._isLoading));
|
this.handlers.forEach((fn) => fn(this._isLoading));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import Button from './Button';
|
|||||||
import Form from './Form';
|
import Form from './Form';
|
||||||
import FormModel from './FormModel';
|
import FormModel from './FormModel';
|
||||||
import Dropdown from './Dropdown';
|
import Dropdown from './Dropdown';
|
||||||
|
import FormError from './FormError';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Input,
|
Input,
|
||||||
@ -13,5 +14,6 @@ export {
|
|||||||
Checkbox,
|
Checkbox,
|
||||||
Form,
|
Form,
|
||||||
FormModel,
|
FormModel,
|
||||||
Dropdown
|
Dropdown,
|
||||||
|
FormError
|
||||||
};
|
};
|
||||||
|
@ -61,6 +61,15 @@ export default connect(null, {
|
|||||||
if (resp.errors) {
|
if (resp.errors) {
|
||||||
Reflect.deleteProperty(resp.errors, 'password');
|
Reflect.deleteProperty(resp.errors, 'password');
|
||||||
|
|
||||||
|
if (resp.errors.email && resp.data && resp.data.canRepeatIn) {
|
||||||
|
resp.errors.email = {
|
||||||
|
type: resp.errors.email,
|
||||||
|
payload: {
|
||||||
|
msLeft: resp.data.canRepeatIn * 1000
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(resp.errors).length) {
|
if (Object.keys(resp.errors).length) {
|
||||||
form.setErrors(resp.errors);
|
form.setErrors(resp.errors);
|
||||||
return Promise.reject(resp);
|
return Promise.reject(resp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user