commit
83fcc34701
|
@ -1,5 +1,7 @@
|
|||
export default {
|
||||
checkLoginStatus: stub(),
|
||||
sendRecoverPassword: stub(),
|
||||
recoverPassword: stub(),
|
||||
login: stub(),
|
||||
logout: stub()
|
||||
};
|
|
@ -4,7 +4,7 @@ const UserActions = Reflux.createActions([
|
|||
'checkLoginStatus',
|
||||
'login',
|
||||
'logout',
|
||||
'sendRecover',
|
||||
'sendRecoverPassword',
|
||||
'recoverPassword'
|
||||
]);
|
||||
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
const UserActions = require('actions/__mocks__/user-actions-mock');
|
||||
const UserStore = require('stores/__mocks__/user-store-mock');
|
||||
|
||||
const SubmitButton = ReactMock();
|
||||
const Button = ReactMock();
|
||||
const Input = ReactMock();
|
||||
const Form = ReactMock();
|
||||
const Checkbox = ReactMock();
|
||||
const Message = ReactMock();
|
||||
const Widget = ReactMock();
|
||||
const WidgetTransition = ReactMock();
|
||||
|
||||
const MainHomePageLoginWidget = requireUnit('app/main/main-home/main-home-page-login-widget', {
|
||||
'core-components/submit-button': SubmitButton,
|
||||
'core-components/button': Button,
|
||||
'core-components/input': Input,
|
||||
'core-components/form': Form,
|
||||
'core-components/checkbox': Checkbox,
|
||||
'core-components/message': Message,
|
||||
'core-components/widget': Widget,
|
||||
'core-components/widget-transition': WidgetTransition,
|
||||
'actions/user-actions': UserActions,
|
||||
|
@ -23,7 +27,7 @@ const MainHomePageLoginWidget = requireUnit('app/main/main-home/main-home-page-l
|
|||
describe('Login/Recover Widget', function () {
|
||||
describe('Login Form', function () {
|
||||
let loginWidget, loginForm, widgetTransition, inputs, checkbox, component,
|
||||
forgotPasswordButton;
|
||||
forgotPasswordButton, submitButton;
|
||||
|
||||
beforeEach(function () {
|
||||
component = TestUtils.renderIntoDocument(
|
||||
|
@ -34,7 +38,8 @@ describe('Login/Recover Widget', function () {
|
|||
loginForm = TestUtils.scryRenderedComponentsWithType(component, Form)[0];
|
||||
inputs = TestUtils.scryRenderedComponentsWithType(component, Input);
|
||||
checkbox = TestUtils.scryRenderedComponentsWithType(component, Checkbox)[0];
|
||||
forgotPasswordButton = TestUtils.scryRenderedComponentsWithType(component, Button)[1];
|
||||
submitButton = TestUtils.scryRenderedComponentsWithType(component, SubmitButton)[0];
|
||||
forgotPasswordButton = TestUtils.scryRenderedComponentsWithType(component, Button)[0];
|
||||
|
||||
component.refs.loginForm = {
|
||||
refs: {
|
||||
|
@ -59,10 +64,18 @@ describe('Login/Recover Widget', function () {
|
|||
expect(UserActions.login).to.have.been.calledWith(mockSubmitData);
|
||||
});
|
||||
|
||||
it('should add error if login fails', function () {
|
||||
it('should set loading true in the form when submitted', function () {
|
||||
let mockSubmitData = {email: 'MOCK_VALUE', password: 'MOCK_VALUE'};
|
||||
|
||||
loginForm.props.onSubmit(mockSubmitData);
|
||||
expect(loginForm.props.loading).to.equal(true);
|
||||
});
|
||||
|
||||
it('should add error and stop loading if login fails', function () {
|
||||
component.refs.loginForm.refs.password.focus.reset();
|
||||
component.onUserStoreChanged('LOGIN_FAIL');
|
||||
expect(loginForm.props.errors).to.deep.equal({password: 'Invalid password'});
|
||||
expect(loginForm.props.loading).to.equal(false);
|
||||
expect(component.refs.loginForm.refs.password.focus).to.have.been.called;
|
||||
});
|
||||
|
||||
|
@ -72,4 +85,76 @@ describe('Login/Recover Widget', function () {
|
|||
expect(widgetTransition.props.sideToShow).to.equal('back');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Recover Password form', function () {
|
||||
let recoverWidget, recoverForm, widgetTransition, emailInput, component,
|
||||
backToLoginButton, submitButton;
|
||||
|
||||
beforeEach(function () {
|
||||
component = TestUtils.renderIntoDocument(
|
||||
<MainHomePageLoginWidget />
|
||||
);
|
||||
widgetTransition = TestUtils.scryRenderedComponentsWithType(component, WidgetTransition)[0];
|
||||
recoverWidget = TestUtils.scryRenderedComponentsWithType(component, Widget)[1];
|
||||
recoverForm = TestUtils.scryRenderedComponentsWithType(component, Form)[1];
|
||||
emailInput = TestUtils.scryRenderedComponentsWithType(component, Input)[2];
|
||||
submitButton = TestUtils.scryRenderedComponentsWithType(component, SubmitButton)[1];
|
||||
backToLoginButton = TestUtils.scryRenderedComponentsWithType(component, Button)[1];
|
||||
|
||||
component.refs.recoverForm = {
|
||||
refs: {
|
||||
email: {
|
||||
focus: stub()
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
it('should control form errors by prop', function () {
|
||||
expect(recoverForm.props.errors).to.deep.equal({});
|
||||
recoverForm.props.onValidateErrors({email: 'MOCK_ERROR'});
|
||||
expect(recoverForm.props.errors).to.deep.equal({email: 'MOCK_ERROR'});
|
||||
});
|
||||
|
||||
it('should trigger sendRecoverPassword action when submitted', function () {
|
||||
let mockSubmitData = {email: 'MOCK_VALUE'};
|
||||
|
||||
UserActions.sendRecoverPassword.reset();
|
||||
recoverForm.props.onSubmit(mockSubmitData);
|
||||
expect(UserActions.sendRecoverPassword).to.have.been.calledWith(mockSubmitData);
|
||||
});
|
||||
|
||||
it('should set loading true in the form when submitted', function () {
|
||||
let mockSubmitData = {email: 'MOCK_VALUE'};
|
||||
|
||||
recoverForm.props.onSubmit(mockSubmitData);
|
||||
expect(recoverForm.props.loading).to.equal(true);
|
||||
});
|
||||
|
||||
it('should add error and stop loading when send recover fails', function () {
|
||||
component.refs.recoverForm.refs.email.focus.reset();
|
||||
component.onUserStoreChanged('SEND_RECOVER_FAIL');
|
||||
expect(recoverForm.props.errors).to.deep.equal({email: 'Email does not exist'});
|
||||
expect(recoverForm.props.loading).to.equal(false);
|
||||
expect(component.refs.recoverForm.refs.email.focus).to.have.been.called;
|
||||
});
|
||||
|
||||
it('should show message when send recover success', function () {
|
||||
let message = TestUtils.scryRenderedComponentsWithType(component, Message)[0];
|
||||
expect(message).to.equal(undefined);
|
||||
|
||||
component.onUserStoreChanged('SEND_RECOVER_SUCCESS');
|
||||
message = TestUtils.scryRenderedComponentsWithType(component, Message)[0];
|
||||
|
||||
expect(recoverForm.props.loading).to.equal(false);
|
||||
expect(message).to.not.equal(null);
|
||||
expect(message.props.type).to.equal('info');
|
||||
expect(message.props.children).to.equal('An email with recover instructions has been sent.');
|
||||
});
|
||||
|
||||
it('should show front side if \'Back to login form\' link is clicked', function () {
|
||||
backToLoginButton.props.onClick();
|
||||
expect(widgetTransition.props.sideToShow).to.equal('front');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -8,6 +8,7 @@ import UserStore from 'stores/user-store';
|
|||
import focus from 'lib-core/focus';
|
||||
import i18n from 'lib-app/i18n';
|
||||
|
||||
import SubmitButton from 'core-components/submit-button';
|
||||
import Button from 'core-components/button';
|
||||
import Form from 'core-components/form';
|
||||
import Input from 'core-components/input';
|
||||
|
@ -25,7 +26,9 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
sideToShow: 'front',
|
||||
loginFormErrors: {},
|
||||
recoverFormErrors: {},
|
||||
recoverSent: false
|
||||
recoverSent: false,
|
||||
loadingLogin: false,
|
||||
loadingRecover: false
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -41,14 +44,14 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
renderLogin() {
|
||||
return (
|
||||
<Widget className="main-home-page__widget" title="Login" ref="loginWidget">
|
||||
<Form className="login-widget__form" ref="loginForm" onSubmit={this.handleLoginFormSubmit} errors={this.state.loginFormErrors} onValidateErrors={this.handleLoginFormErrorsValidation}>
|
||||
<Form {...this.getLoginFormProps()}>
|
||||
<div className="login-widget__inputs">
|
||||
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
||||
<Input placeholder="password" name="password" className="login-widget__input" password required/>
|
||||
<Checkbox name="remember" label="Remember Me" className="login-widget__input"/>
|
||||
</div>
|
||||
<div className="login-widget__submit-button">
|
||||
<Button type="primary">LOG IN</Button>
|
||||
<SubmitButton type="primary">LOG IN</SubmitButton>
|
||||
</div>
|
||||
</Form>
|
||||
<Button className="login-widget__forgot-password" type="link" onClick={this.handleForgotPasswordClick} onMouseDown={(event) => {event.preventDefault()}}>
|
||||
|
@ -61,12 +64,12 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
renderPasswordRecovery() {
|
||||
return (
|
||||
<Widget className="main-home-page__widget login-widget_password" title={i18n('RECOVER_PASSWORD')} ref="recoverWidget">
|
||||
<Form className="login-widget__form" ref="recoverForm" onSubmit={this.handleForgotPasswordSubmit} errors={this.state.recoverFormErrors} onValidateErrors={this.handleRecoverFormErrorsValidation}>
|
||||
<Form {...this.getRecoverFormProps()}>
|
||||
<div className="login-widget__inputs">
|
||||
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
||||
</div>
|
||||
<div className="login-widget__submit-button">
|
||||
<Button type="primary">{i18n('RECOVER_PASSWORD')}</Button>
|
||||
<SubmitButton type="primary">{i18n('RECOVER_PASSWORD')}</SubmitButton>
|
||||
</div>
|
||||
</Form>
|
||||
<Button className="login-widget__forgot-password" type="link" onClick={this.handleBackToLoginClick} onMouseDown={(event) => {event.preventDefault()}}>
|
||||
|
@ -91,12 +94,42 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
return status;
|
||||
},
|
||||
|
||||
getLoginFormProps() {
|
||||
return {
|
||||
loading: this.state.loadingLogin,
|
||||
className: 'login-widget__form',
|
||||
ref: 'loginForm',
|
||||
onSubmit:this.handleLoginFormSubmit,
|
||||
errors: this.state.loginFormErrors,
|
||||
onValidateErrors: this.handleLoginFormErrorsValidation
|
||||
};
|
||||
},
|
||||
|
||||
getRecoverFormProps() {
|
||||
return {
|
||||
loading: this.state.loadingRecover,
|
||||
className: 'login-widget__form',
|
||||
ref: 'recoverForm',
|
||||
onSubmit:this.handleForgotPasswordSubmit,
|
||||
errors: this.state.recoverFormErrors,
|
||||
onValidateErrors: this.handleRecoverFormErrorsValidation
|
||||
};
|
||||
},
|
||||
|
||||
handleLoginFormSubmit(formState) {
|
||||
UserActions.login(formState);
|
||||
|
||||
this.setState({
|
||||
loadingLogin: true
|
||||
});
|
||||
},
|
||||
|
||||
handleForgotPasswordSubmit(formState) {
|
||||
UserActions.sendRecover(formState);
|
||||
UserActions.sendRecoverPassword(formState);
|
||||
|
||||
this.setState({
|
||||
loadingRecover: true
|
||||
});
|
||||
},
|
||||
|
||||
handleLoginFormErrorsValidation(errors) {
|
||||
|
@ -119,13 +152,15 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
|
||||
handleBackToLoginClick() {
|
||||
this.setState({
|
||||
sideToShow: 'front'
|
||||
sideToShow: 'front',
|
||||
recoverSent: false
|
||||
}, this.moveFocusToCurrentSide);
|
||||
},
|
||||
|
||||
onUserStoreChanged(event) {
|
||||
if (event === 'LOGIN_FAIL') {
|
||||
this.setState({
|
||||
loadingLogin: false,
|
||||
loginFormErrors: {
|
||||
password: i18n('ERROR_PASSWORD')
|
||||
}
|
||||
|
@ -136,6 +171,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
|
||||
if (event === 'SEND_RECOVER_FAIL') {
|
||||
this.setState({
|
||||
loadingRecover: false,
|
||||
recoverFormErrors: {
|
||||
email: i18n('EMAIL_NOT_EXIST')
|
||||
}
|
||||
|
@ -147,6 +183,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
|
||||
if (event === 'SEND_RECOVER_SUCCESS') {
|
||||
this.setState({
|
||||
loadingRecover: false,
|
||||
recoverSent: true
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
const CommonActions = require('actions/__mocks__/common-actions-mock');
|
||||
const UserActions = require('actions/__mocks__/user-actions-mock');
|
||||
const UserStore = require('stores/__mocks__/user-store-mock');
|
||||
|
||||
const SubmitButton = ReactMock();
|
||||
const Button = ReactMock();
|
||||
const Input = ReactMock();
|
||||
const Form = ReactMock();
|
||||
const Message = ReactMock();
|
||||
const Widget = ReactMock();
|
||||
|
||||
const MainRecoverPasswordPage = requireUnit('app/main/main-recover-password/main-recover-password-page', {
|
||||
'core-components/submit-button': SubmitButton,
|
||||
'core-components/button': Button,
|
||||
'core-components/input': Input,
|
||||
'core-components/form': Form,
|
||||
'core-components/message': Message,
|
||||
'core-components/widget': Widget,
|
||||
'actions/common-actions': CommonActions,
|
||||
'actions/user-actions': UserActions,
|
||||
'stores/user-store': UserStore
|
||||
});
|
||||
|
||||
describe('Recover Password form', function () {
|
||||
let recoverForm, inputs, component, submitButton;
|
||||
let query = {
|
||||
token: 'SOME_TOKEN',
|
||||
email: 'SOME_EMAIL'
|
||||
};
|
||||
|
||||
beforeEach(function () {
|
||||
component = TestUtils.renderIntoDocument(
|
||||
<MainRecoverPasswordPage location={{query}}/>
|
||||
);
|
||||
recoverForm = TestUtils.scryRenderedComponentsWithType(component, Form)[0];
|
||||
inputs = TestUtils.scryRenderedComponentsWithType(component, Input);
|
||||
submitButton = TestUtils.scryRenderedComponentsWithType(component, SubmitButton)[0];
|
||||
});
|
||||
|
||||
it('should trigger recoverPassword action when submitted', function () {
|
||||
UserActions.sendRecoverPassword.reset();
|
||||
recoverForm.props.onSubmit({password: 'MOCK_VALUE'});
|
||||
expect(UserActions.recoverPassword).to.have.been.calledWith({
|
||||
password: 'MOCK_VALUE',
|
||||
token: 'SOME_TOKEN',
|
||||
email: 'SOME_EMAIL'
|
||||
});
|
||||
});
|
||||
|
||||
it('should set loading true in the form when submitted', function () {
|
||||
recoverForm.props.onSubmit({password: 'MOCK_VALUE'});
|
||||
expect(recoverForm.props.loading).to.equal(true);
|
||||
});
|
||||
|
||||
it('should show message when recover fails', function () {
|
||||
component.onUserStoreChanged('INVALID_RECOVER');
|
||||
expect(recoverForm.props.loading).to.equal(false);
|
||||
|
||||
let message = TestUtils.scryRenderedComponentsWithType(component, Message)[0];
|
||||
expect(message).to.not.equal(null);
|
||||
expect(message.props.type).to.equal('error');
|
||||
expect(message.props.children).to.equal('Invalid recover data');
|
||||
});
|
||||
|
||||
it('should show message when recover success', function () {
|
||||
component.onUserStoreChanged('VALID_RECOVER');
|
||||
expect(recoverForm.props.loading).to.equal(false);
|
||||
|
||||
let message = TestUtils.scryRenderedComponentsWithType(component, Message)[0];
|
||||
expect(message).to.not.equal(null);
|
||||
expect(message.props.type).to.equal('success');
|
||||
expect(message.props.children).to.equal('Password recovered successfully');
|
||||
});
|
||||
});
|
|
@ -10,7 +10,7 @@ import i18n from 'lib-app/i18n';
|
|||
import Widget from 'core-components/widget';
|
||||
import Form from 'core-components/form';
|
||||
import Input from 'core-components/input';
|
||||
import Button from 'core-components/button';
|
||||
import SubmitButton from 'core-components/submit-button';
|
||||
import Message from 'core-components/message';
|
||||
|
||||
const MainRecoverPasswordPage = React.createClass({
|
||||
|
@ -34,7 +34,8 @@ const MainRecoverPasswordPage = React.createClass({
|
|||
|
||||
getInitialState() {
|
||||
return {
|
||||
recoverStatus: 'waiting'
|
||||
recoverStatus: 'waiting',
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -42,13 +43,13 @@ const MainRecoverPasswordPage = React.createClass({
|
|||
return (
|
||||
<div className="main-recover-password-page">
|
||||
<Widget title={i18n('RECOVER_PASSWORD')} className="col-md-4 col-md-offset-4">
|
||||
<Form className="recover-password__form" onSubmit={this.handleRecoverPasswordSubmit}>
|
||||
<Form className="recover-password__form" onSubmit={this.handleRecoverPasswordSubmit} loading={this.state.loading}>
|
||||
<div className="recover-password__inputs">
|
||||
<Input placeholder={i18n('NEW_PASSWORD')} name="password" className="recover-password__input" validation="PASSWORD" password required/>
|
||||
<Input placeholder={i18n('REPEAT_NEW_PASSWORD')} name="password-repeat" className="recover-password__input" validation="REPEAT_PASSWORD" password required/>
|
||||
</div>
|
||||
<div className="recover-password__submit-button">
|
||||
<Button type="primary">{i18n('SUBMIT')}</Button>
|
||||
<SubmitButton type="primary">{i18n('SUBMIT')}</SubmitButton>
|
||||
</div>
|
||||
{this.renderRecoverStatus()}
|
||||
</Form>
|
||||
|
@ -73,17 +74,23 @@ const MainRecoverPasswordPage = React.createClass({
|
|||
recoverData.token = this.props.location.query.token;
|
||||
recoverData.email = this.props.location.query.email;
|
||||
|
||||
UserActions.recoverPassword(formState);
|
||||
UserActions.recoverPassword(recoverData);
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
},
|
||||
|
||||
onUserStoreChanged(event) {
|
||||
if (event === 'VALID_RECOVER') {
|
||||
setTimeout(CommonActions.loggedOut, 2000);
|
||||
this.setState({
|
||||
recoverStatus: 'valid'
|
||||
recoverStatus: 'valid',
|
||||
loading: false
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
recoverStatus: 'invalid'
|
||||
recoverStatus: 'invalid',
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,4 +203,22 @@ describe('Form component', function () {
|
|||
expect(fields[1].focus).to.have.been.called;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using loading prop', function () {
|
||||
it('should pass loading context in true if enabled', function () {
|
||||
renderForm({ loading: true });
|
||||
|
||||
expect(fields[0].context.loading).to.equal(true);
|
||||
expect(fields[1].context.loading).to.equal(true);
|
||||
expect(fields[2].context.loading).to.equal(true);
|
||||
});
|
||||
|
||||
it('should pass loading context in true if disabled', function () {
|
||||
renderForm({ loading: false });
|
||||
|
||||
expect(fields[0].context.loading).to.equal(false);
|
||||
expect(fields[1].context.loading).to.equal(false);
|
||||
expect(fields[2].context.loading).to.equal(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import classNames from 'classnames';
|
|||
// CORE LIBS
|
||||
import callback from 'lib-core/callback';
|
||||
|
||||
let Button = React.createClass({
|
||||
const Button = React.createClass({
|
||||
|
||||
contextTypes: {
|
||||
router: React.PropTypes.object
|
||||
|
@ -54,7 +54,8 @@ let Button = React.createClass({
|
|||
|
||||
getClass() {
|
||||
let classes = {
|
||||
'button': true
|
||||
'button': true,
|
||||
'button_disabled': this.props.disabled
|
||||
};
|
||||
|
||||
classes['button-' + this.props.type] = (this.props.type);
|
||||
|
|
|
@ -27,4 +27,8 @@
|
|||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&_disabled {
|
||||
background-color: #ec9696;
|
||||
}
|
||||
}
|
|
@ -10,11 +10,22 @@ const Checkbox = require('core-components/checkbox');
|
|||
const Form = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
loading: React.PropTypes.bool,
|
||||
errors: React.PropTypes.object,
|
||||
onValidateErrors: React.PropTypes.func,
|
||||
onSubmit: React.PropTypes.func
|
||||
},
|
||||
|
||||
childContextTypes: {
|
||||
loading: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
loading: this.props.loading
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
form: {},
|
||||
|
@ -41,6 +52,7 @@ const Form = React.createClass({
|
|||
props.onSubmit = this.handleSubmit;
|
||||
|
||||
delete props.errors;
|
||||
delete props.loading;
|
||||
delete props.onValidateErrors;
|
||||
|
||||
return props;
|
||||
|
|
|
@ -6,6 +6,10 @@ const Icon = require('core-components/icon');
|
|||
|
||||
const Input = React.createClass({
|
||||
|
||||
contextTypes: {
|
||||
loading: React.PropTypes.bool
|
||||
},
|
||||
|
||||
propTypes: {
|
||||
value: React.PropTypes.string,
|
||||
validation: React.PropTypes.string,
|
||||
|
@ -60,6 +64,7 @@ const Input = React.createClass({
|
|||
props['aria-required'] = this.props.required;
|
||||
props.type = (this.props.password) ? 'password' : 'text';
|
||||
props.ref = 'nativeInput';
|
||||
props.disabled = this.context.loading;
|
||||
|
||||
delete props.required;
|
||||
delete props.validation;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
// VENDOR LIBS
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
|
||||
// CORE LIBS
|
||||
import Button from 'core-components/button';
|
||||
|
||||
const SubmitButton = React.createClass({
|
||||
|
||||
contextTypes: {
|
||||
loading: React.PropTypes.bool
|
||||
},
|
||||
|
||||
propTypes: {
|
||||
children: React.PropTypes.node
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
return {
|
||||
type: 'primary'
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Button {...this.getProps()}>
|
||||
{(this.context.loading) ? this.renderLoading() : this.props.children}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
|
||||
renderLoading() {
|
||||
return (
|
||||
<div className="submit-button__loader"></div>
|
||||
);
|
||||
},
|
||||
|
||||
getProps() {
|
||||
return _.extend({}, this.props, {
|
||||
disabled: this.context.loading,
|
||||
className: this.getClass()
|
||||
});
|
||||
},
|
||||
|
||||
getClass() {
|
||||
let classes = {
|
||||
'submit-button': true,
|
||||
'submit-button_loading': this.context.loading
|
||||
};
|
||||
|
||||
classes[this.props.className] = (this.props.className);
|
||||
|
||||
return classNames(classes);
|
||||
}
|
||||
});
|
||||
|
||||
export default SubmitButton;
|
|
@ -0,0 +1,46 @@
|
|||
.submit-button {
|
||||
position: relative;
|
||||
|
||||
&__loader {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: 103px;
|
||||
|
||||
font-size: 4px;
|
||||
border-top: 1.1em solid rgba(255, 255, 255, 0.2);
|
||||
border-right: 1.1em solid rgba(255, 255, 255, 0.2);
|
||||
border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);
|
||||
border-left: 1.1em solid #ffffff;
|
||||
-webkit-transform: translateZ(0);
|
||||
-ms-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
-webkit-animation: turnAnimation 1.1s infinite linear;
|
||||
animation: turnAnimation 1.1s infinite linear;
|
||||
}
|
||||
&__loader,
|
||||
&__loader:after {
|
||||
border-radius: 50%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
@-webkit-keyframes turnAnimation {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes turnAnimation {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ module.exports = [
|
|||
},
|
||||
{
|
||||
path: 'user/send-recover-password',
|
||||
time: 100,
|
||||
time: 2000,
|
||||
response: function (data) {
|
||||
|
||||
if (data.email.length > 10) {
|
||||
|
@ -68,7 +68,7 @@ module.exports = [
|
|||
},
|
||||
{
|
||||
path: 'user/recover-password',
|
||||
time: 100,
|
||||
time: 1000,
|
||||
response: function (data) {
|
||||
|
||||
if (data.password.length > 6) {
|
||||
|
|
|
@ -14,7 +14,7 @@ const UserStore = Reflux.createStore({
|
|||
this.listenTo(UserActions.login, this.loginUser);
|
||||
this.listenTo(UserActions.logout, this.logoutUser);
|
||||
this.listenTo(UserActions.recoverPassword, this.recoverPassword);
|
||||
this.listenTo(UserActions.sendRecover, this.sendRecoverPassword);
|
||||
this.listenTo(UserActions.sendRecoverPassword, this.sendRecoverPassword);
|
||||
},
|
||||
|
||||
initSession() {
|
||||
|
@ -72,7 +72,6 @@ const UserStore = Reflux.createStore({
|
|||
data: recoverData
|
||||
}).then(() => {
|
||||
this.trigger('VALID_RECOVER');
|
||||
setTimeout(CommonActions.loggedOut, 1000);
|
||||
}, () => {
|
||||
this.trigger('INVALID_RECOVER')
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue