mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-30 17:25:11 +02:00
Ivan - Add SubmitButton with loading [skip ci]
This commit is contained in:
parent
db32a2a6ab
commit
dae244bee2
@ -8,6 +8,7 @@ import UserStore from 'stores/user-store';
|
|||||||
import focus from 'lib-core/focus';
|
import focus from 'lib-core/focus';
|
||||||
import i18n from 'lib-app/i18n';
|
import i18n from 'lib-app/i18n';
|
||||||
|
|
||||||
|
import SubmitButton from 'core-components/submit-button';
|
||||||
import Button from 'core-components/button';
|
import Button from 'core-components/button';
|
||||||
import Form from 'core-components/form';
|
import Form from 'core-components/form';
|
||||||
import Input from 'core-components/input';
|
import Input from 'core-components/input';
|
||||||
@ -25,7 +26,8 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
sideToShow: 'front',
|
sideToShow: 'front',
|
||||||
loginFormErrors: {},
|
loginFormErrors: {},
|
||||||
recoverFormErrors: {},
|
recoverFormErrors: {},
|
||||||
recoverSent: false
|
recoverSent: false,
|
||||||
|
loading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -41,14 +43,14 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
renderLogin() {
|
renderLogin() {
|
||||||
return (
|
return (
|
||||||
<Widget className="main-home-page__widget" title="Login" ref="loginWidget">
|
<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">
|
<div className="login-widget__inputs">
|
||||||
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
||||||
<Input placeholder="password" name="password" className="login-widget__input" password required/>
|
<Input placeholder="password" name="password" className="login-widget__input" password required/>
|
||||||
<Checkbox name="remember" label="Remember Me" className="login-widget__input"/>
|
<Checkbox name="remember" label="Remember Me" className="login-widget__input"/>
|
||||||
</div>
|
</div>
|
||||||
<div className="login-widget__submit-button">
|
<div className="login-widget__submit-button">
|
||||||
<Button type="primary">LOG IN</Button>
|
<SubmitButton type="primary">LOG IN</SubmitButton>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
<Button className="login-widget__forgot-password" type="link" onClick={this.handleForgotPasswordClick} onMouseDown={(event) => {event.preventDefault()}}>
|
<Button className="login-widget__forgot-password" type="link" onClick={this.handleForgotPasswordClick} onMouseDown={(event) => {event.preventDefault()}}>
|
||||||
@ -61,12 +63,12 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
renderPasswordRecovery() {
|
renderPasswordRecovery() {
|
||||||
return (
|
return (
|
||||||
<Widget className="main-home-page__widget login-widget_password" title={i18n('RECOVER_PASSWORD')} ref="recoverWidget">
|
<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">
|
<div className="login-widget__inputs">
|
||||||
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
<Input placeholder="email" name="email" className="login-widget__input" validation="EMAIL" required/>
|
||||||
</div>
|
</div>
|
||||||
<div className="login-widget__submit-button">
|
<div className="login-widget__submit-button">
|
||||||
<Button type="primary">{i18n('RECOVER_PASSWORD')}</Button>
|
<SubmitButton type="primary">{i18n('RECOVER_PASSWORD')}</SubmitButton>
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
<Button className="login-widget__forgot-password" type="link" onClick={this.handleBackToLoginClick} onMouseDown={(event) => {event.preventDefault()}}>
|
<Button className="login-widget__forgot-password" type="link" onClick={this.handleBackToLoginClick} onMouseDown={(event) => {event.preventDefault()}}>
|
||||||
@ -91,12 +93,42 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getLoginFormProps() {
|
||||||
|
return {
|
||||||
|
loading: this.state.loading,
|
||||||
|
className: 'login-widget__form',
|
||||||
|
ref: 'loginForm',
|
||||||
|
onSubmit:this.handleLoginFormSubmit,
|
||||||
|
errors: this.state.loginFormErrors,
|
||||||
|
onValidateErrors: this.handleLoginFormErrorsValidation
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getRecoverFormProps() {
|
||||||
|
return {
|
||||||
|
loading: this.state.loading,
|
||||||
|
className: 'login-widget__form',
|
||||||
|
ref: 'recoverForm',
|
||||||
|
onSubmit:this.handleForgotPasswordSubmit,
|
||||||
|
errors: this.state.recoverFormErrors,
|
||||||
|
onValidateErrors: this.handleRecoverFormErrorsValidation
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
handleLoginFormSubmit(formState) {
|
handleLoginFormSubmit(formState) {
|
||||||
UserActions.login(formState);
|
UserActions.login(formState);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleForgotPasswordSubmit(formState) {
|
handleForgotPasswordSubmit(formState) {
|
||||||
UserActions.sendRecover(formState);
|
UserActions.sendRecover(formState);
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleLoginFormErrorsValidation(errors) {
|
handleLoginFormErrorsValidation(errors) {
|
||||||
@ -119,13 +151,15 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
|
|
||||||
handleBackToLoginClick() {
|
handleBackToLoginClick() {
|
||||||
this.setState({
|
this.setState({
|
||||||
sideToShow: 'front'
|
sideToShow: 'front',
|
||||||
|
recoverSent: false
|
||||||
}, this.moveFocusToCurrentSide);
|
}, this.moveFocusToCurrentSide);
|
||||||
},
|
},
|
||||||
|
|
||||||
onUserStoreChanged(event) {
|
onUserStoreChanged(event) {
|
||||||
if (event === 'LOGIN_FAIL') {
|
if (event === 'LOGIN_FAIL') {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
loading: false,
|
||||||
loginFormErrors: {
|
loginFormErrors: {
|
||||||
password: i18n('ERROR_PASSWORD')
|
password: i18n('ERROR_PASSWORD')
|
||||||
}
|
}
|
||||||
@ -136,6 +170,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
|
|
||||||
if (event === 'SEND_RECOVER_FAIL') {
|
if (event === 'SEND_RECOVER_FAIL') {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
loading: false,
|
||||||
recoverFormErrors: {
|
recoverFormErrors: {
|
||||||
email: i18n('EMAIL_NOT_EXIST')
|
email: i18n('EMAIL_NOT_EXIST')
|
||||||
}
|
}
|
||||||
@ -147,6 +182,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||||||
|
|
||||||
if (event === 'SEND_RECOVER_SUCCESS') {
|
if (event === 'SEND_RECOVER_SUCCESS') {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
loading: false,
|
||||||
recoverSent: true
|
recoverSent: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import i18n from 'lib-app/i18n';
|
|||||||
import Widget from 'core-components/widget';
|
import Widget from 'core-components/widget';
|
||||||
import Form from 'core-components/form';
|
import Form from 'core-components/form';
|
||||||
import Input from 'core-components/input';
|
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';
|
import Message from 'core-components/message';
|
||||||
|
|
||||||
const MainRecoverPasswordPage = React.createClass({
|
const MainRecoverPasswordPage = React.createClass({
|
||||||
@ -34,7 +34,8 @@ const MainRecoverPasswordPage = React.createClass({
|
|||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
recoverStatus: 'waiting'
|
recoverStatus: 'waiting',
|
||||||
|
loading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -42,13 +43,13 @@ const MainRecoverPasswordPage = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<div className="main-recover-password-page">
|
<div className="main-recover-password-page">
|
||||||
<Widget title={i18n('RECOVER_PASSWORD')} className="col-md-4 col-md-offset-4">
|
<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">
|
<div className="recover-password__inputs">
|
||||||
<Input placeholder={i18n('NEW_PASSWORD')} name="password" className="recover-password__input" validation="PASSWORD" password required/>
|
<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/>
|
<Input placeholder={i18n('REPEAT_NEW_PASSWORD')} name="password-repeat" className="recover-password__input" validation="REPEAT_PASSWORD" password required/>
|
||||||
</div>
|
</div>
|
||||||
<div className="recover-password__submit-button">
|
<div className="recover-password__submit-button">
|
||||||
<Button type="primary">{i18n('SUBMIT')}</Button>
|
<SubmitButton type="primary">{i18n('SUBMIT')}</SubmitButton>
|
||||||
</div>
|
</div>
|
||||||
{this.renderRecoverStatus()}
|
{this.renderRecoverStatus()}
|
||||||
</Form>
|
</Form>
|
||||||
@ -74,16 +75,22 @@ const MainRecoverPasswordPage = React.createClass({
|
|||||||
recoverData.email = this.props.location.query.email;
|
recoverData.email = this.props.location.query.email;
|
||||||
|
|
||||||
UserActions.recoverPassword(formState);
|
UserActions.recoverPassword(formState);
|
||||||
|
this.setState({
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onUserStoreChanged(event) {
|
onUserStoreChanged(event) {
|
||||||
if (event === 'VALID_RECOVER') {
|
if (event === 'VALID_RECOVER') {
|
||||||
|
setTimeout(CommonActions.loggedOut, 2000);
|
||||||
this.setState({
|
this.setState({
|
||||||
recoverStatus: 'valid'
|
recoverStatus: 'valid',
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
recoverStatus: 'invalid'
|
recoverStatus: 'invalid',
|
||||||
|
loading: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import classNames from 'classnames';
|
|||||||
// CORE LIBS
|
// CORE LIBS
|
||||||
import callback from 'lib-core/callback';
|
import callback from 'lib-core/callback';
|
||||||
|
|
||||||
let Button = React.createClass({
|
const Button = React.createClass({
|
||||||
|
|
||||||
contextTypes: {
|
contextTypes: {
|
||||||
router: React.PropTypes.object
|
router: React.PropTypes.object
|
||||||
@ -54,7 +54,8 @@ let Button = React.createClass({
|
|||||||
|
|
||||||
getClass() {
|
getClass() {
|
||||||
let classes = {
|
let classes = {
|
||||||
'button': true
|
'button': true,
|
||||||
|
'button_disabled': this.props.disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
classes['button-' + this.props.type] = (this.props.type);
|
classes['button-' + this.props.type] = (this.props.type);
|
||||||
|
@ -27,4 +27,8 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_disabled {
|
||||||
|
background-color: #ec9696;
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,11 +10,22 @@ const Checkbox = require('core-components/checkbox');
|
|||||||
const Form = React.createClass({
|
const Form = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
loading: React.PropTypes.bool,
|
||||||
errors: React.PropTypes.object,
|
errors: React.PropTypes.object,
|
||||||
onValidateErrors: React.PropTypes.func,
|
onValidateErrors: React.PropTypes.func,
|
||||||
onSubmit: React.PropTypes.func
|
onSubmit: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
|
childContextTypes: {
|
||||||
|
loading: React.PropTypes.bool
|
||||||
|
},
|
||||||
|
|
||||||
|
getChildContext() {
|
||||||
|
return {
|
||||||
|
loading: this.props.loading
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
@ -41,6 +52,7 @@ const Form = React.createClass({
|
|||||||
props.onSubmit = this.handleSubmit;
|
props.onSubmit = this.handleSubmit;
|
||||||
|
|
||||||
delete props.errors;
|
delete props.errors;
|
||||||
|
delete props.loading;
|
||||||
delete props.onValidateErrors;
|
delete props.onValidateErrors;
|
||||||
|
|
||||||
return props;
|
return props;
|
||||||
|
58
client/src/core-components/submit-button.js
Normal file
58
client/src/core-components/submit-button.js
Normal file
@ -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;
|
46
client/src/core-components/submit-button.scss
Normal file
46
client/src/core-components/submit-button.scss
Normal file
@ -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',
|
path: 'user/send-recover-password',
|
||||||
time: 100,
|
time: 2000,
|
||||||
response: function (data) {
|
response: function (data) {
|
||||||
|
|
||||||
if (data.email.length > 10) {
|
if (data.email.length > 10) {
|
||||||
@ -68,7 +68,7 @@ module.exports = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'user/recover-password',
|
path: 'user/recover-password',
|
||||||
time: 100,
|
time: 1000,
|
||||||
response: function (data) {
|
response: function (data) {
|
||||||
|
|
||||||
if (data.password.length > 6) {
|
if (data.password.length > 6) {
|
||||||
|
@ -72,7 +72,6 @@ const UserStore = Reflux.createStore({
|
|||||||
data: recoverData
|
data: recoverData
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.trigger('VALID_RECOVER');
|
this.trigger('VALID_RECOVER');
|
||||||
setTimeout(CommonActions.loggedOut, 1000);
|
|
||||||
}, () => {
|
}, () => {
|
||||||
this.trigger('INVALID_RECOVER')
|
this.trigger('INVALID_RECOVER')
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user