Ivan - Update i18n, add recover-password path logic [skip ci]
This commit is contained in:
parent
783f13cf59
commit
3dd27fbb3e
|
@ -1,9 +1,10 @@
|
|||
import Reflux from 'reflux';
|
||||
|
||||
let UserActions = Reflux.createActions([
|
||||
const UserActions = Reflux.createActions([
|
||||
'checkLoginStatus',
|
||||
'login',
|
||||
'logout'
|
||||
'logout',
|
||||
'recoverPassword'
|
||||
]);
|
||||
|
||||
export default UserActions;
|
|
@ -3,10 +3,11 @@ import Reflux from 'reflux';
|
|||
|
||||
import CommonStore from 'stores/common-store';
|
||||
|
||||
let App = React.createClass({
|
||||
const App = React.createClass({
|
||||
|
||||
contextTypes: {
|
||||
router: React.PropTypes.object
|
||||
router: React.PropTypes.object,
|
||||
location: React.PropTypes.object
|
||||
},
|
||||
|
||||
mixins: [Reflux.listenTo(CommonStore, 'onCommonStoreChanged')],
|
||||
|
@ -21,7 +22,7 @@ let App = React.createClass({
|
|||
|
||||
onCommonStoreChanged(change) {
|
||||
let handle = {
|
||||
'i18n': () => {this.forceUpdate()},
|
||||
'i18n': () => {this.context.router.push(this.context.location.pathname)},
|
||||
'logged': () => {this.context.router.push('/app/dashboard')},
|
||||
'loggedOut': () => {this.context.router.push('/app')}
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ const DemoPage = require('app/demo/components-demo-page');
|
|||
const MainLayout = require('app/main/main-layout');
|
||||
const MainHomePage = require('app/main/main-home/main-home-page');
|
||||
const MainSignUpPage = require('app/main/main-signup/main-signup-page');
|
||||
const MainRecoverPasswordPage = require('app/main/main-recover-password/main-recover-password-page');
|
||||
|
||||
const DashboardLayout = require('app/main/dashboard/dashboard-layout');
|
||||
|
||||
|
@ -25,6 +26,7 @@ export default (
|
|||
<Route path='/app' component={MainLayout}>
|
||||
<IndexRoute component={MainHomePage} />
|
||||
<Route path='signup' component={MainSignUpPage}/>
|
||||
<Route path='recover-password' component={MainRecoverPasswordPage}/>
|
||||
<Route path='dashboard' component={DashboardLayout}>
|
||||
<IndexRoute component={DashboardListTicketsPage} />
|
||||
<Route path='articles' component={DashboardListArticlesPage}/>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
const React = require('react');
|
||||
const ReactDOM = require('react-dom');
|
||||
const Reflux = require('reflux');
|
||||
const _ = require('lodash');
|
||||
const classNames = require('classnames');
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Reflux from 'reflux';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const UserActions = require('actions/user-actions');
|
||||
const UserStore = require('stores/user-store');
|
||||
const focus = require('lib-core/focus');
|
||||
import UserActions from 'actions/user-actions';
|
||||
import UserStore from 'stores/user-store';
|
||||
import focus from 'lib-core/focus';
|
||||
import i18n from 'lib-app/i18n';
|
||||
|
||||
const Button = require('core-components/button');
|
||||
const Form = require('core-components/form');
|
||||
const Input = require('core-components/input');
|
||||
const Checkbox = require('core-components/checkbox');
|
||||
const Widget = require('core-components/widget');
|
||||
const WidgetTransition = require('core-components/widget-transition');
|
||||
import Button from 'core-components/button';
|
||||
import Form from 'core-components/form';
|
||||
import Input from 'core-components/input';
|
||||
import Checkbox from 'core-components/checkbox';
|
||||
import Widget from 'core-components/widget';
|
||||
import WidgetTransition from 'core-components/widget-transition';
|
||||
|
||||
let MainHomePageLoginWidget = React.createClass({
|
||||
|
||||
|
@ -49,7 +49,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
</div>
|
||||
</Form>
|
||||
<Button className="login-widget--forgot-password" type="link" onClick={this.handleForgotPasswordClick} onMouseDown={(event) => {event.preventDefault()}}>
|
||||
{'Forgot your password?'}
|
||||
{i18n('FORGOT_PASSWORD')}
|
||||
</Button>
|
||||
</Widget>
|
||||
);
|
||||
|
@ -57,7 +57,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
|
||||
renderPasswordRecovery() {
|
||||
return (
|
||||
<Widget className="main-home-page--widget main-home-page--password-widget" title="Password Recovery" ref="recoverWidget">
|
||||
<Widget className="main-home-page--widget main-home-page--password-widget" title={i18n('RECOVER_PASSWORD')} ref="recoverWidget">
|
||||
<Form className="login-widget--form" onSubmit={this.handleForgotPasswordSubmit}>
|
||||
<div className="login-widget--inputs">
|
||||
<Input placeholder="email" name="email" className="login-widget--input" validation="EMAIL"/>
|
||||
|
@ -103,7 +103,7 @@ let MainHomePageLoginWidget = React.createClass({
|
|||
if (event === 'LOGIN_FAIL') {
|
||||
this.setState({
|
||||
loginFormErrors: {
|
||||
password: 'Password does not match'
|
||||
password: i18n('ERROR_PASSWORD')
|
||||
}
|
||||
}, function () {
|
||||
this.refs.loginForm.refs.password.focus()
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const React = require( 'react');
|
||||
import React from 'react';
|
||||
|
||||
const MainHomePageLoginWidget = require('app/main/main-home/main-home-page-login-widget');
|
||||
const MainHomePagePortal = require('app/main/main-home/main-home-page-portal');
|
||||
import MainHomePageLoginWidget from 'app/main/main-home/main-home-page-login-widget';
|
||||
import MainHomePagePortal from 'app/main/main-home/main-home-page-portal';
|
||||
|
||||
const CommonActions = require('actions/common-actions');
|
||||
const UserStore = require('stores/user-store');
|
||||
import CommonActions from 'actions/common-actions';
|
||||
import UserStore from 'stores/user-store';
|
||||
|
||||
const MainHomePage = React.createClass({
|
||||
|
||||
|
|
|
@ -7,14 +7,13 @@ import UserStore from 'stores/user-store';
|
|||
|
||||
import Button from 'core-components/button';
|
||||
import DropDown from 'core-components/drop-down';
|
||||
import Icon from 'core-components/icon';
|
||||
|
||||
let languageList = ['English', 'Spanish', 'Portuguese', 'German', 'Turkish', 'Indian'];
|
||||
let codeLanguages = {
|
||||
'English': 'us',
|
||||
'Spanish': 'es',
|
||||
'Portuguese': 'pt',
|
||||
'German': 'de',
|
||||
'French': 'fr',
|
||||
'Chinese': 'cn',
|
||||
'Turkish': 'tr',
|
||||
'Indian': 'in'
|
||||
};
|
||||
|
@ -52,7 +51,7 @@ let MainLayoutHeader = React.createClass({
|
|||
},
|
||||
|
||||
getLanguageList() {
|
||||
return languageList.map((language) => {
|
||||
return Object.keys(codeLanguages).map((language) => {
|
||||
return {
|
||||
content: language,
|
||||
icon: codeLanguages[language]
|
||||
|
@ -61,7 +60,7 @@ let MainLayoutHeader = React.createClass({
|
|||
},
|
||||
|
||||
changeLanguage(event) {
|
||||
let language = languageList[event.index];
|
||||
let language = Object.keys(codeLanguages)[event.index];
|
||||
|
||||
CommonActions.changeLanguage(codeLanguages[language]);
|
||||
},
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
import React from 'react';
|
||||
import Reflux from 'reflux';
|
||||
import _ from 'lodash';
|
||||
|
||||
import CommonActions from 'actions/common-actions';
|
||||
import UserActions from 'actions/user-actions';
|
||||
import UserStore from 'stores/user-store';
|
||||
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';
|
||||
|
||||
const MainRecoverPasswordPage = React.createClass({
|
||||
|
||||
mixins: [Reflux.listenTo(UserStore, 'onUserStoreChanged')],
|
||||
|
||||
propTypes: {
|
||||
location: React.PropTypes.object,
|
||||
router: React.PropTypes.object
|
||||
},
|
||||
|
||||
componentWillMount() {
|
||||
if (UserStore.isLoggedIn()) {
|
||||
CommonActions.logged();
|
||||
}
|
||||
|
||||
if (!this.props.location.query.token || !this.props.location.query.email) {
|
||||
CommonActions.loggedOut();
|
||||
}
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
recoverStatus: 'waiting'
|
||||
};
|
||||
},
|
||||
|
||||
render() {
|
||||
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}>
|
||||
<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>
|
||||
</div>
|
||||
{this.renderRecoverStatus()}
|
||||
</Form>
|
||||
</Widget>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
renderRecoverStatus() {
|
||||
switch (this.state.recoverStatus) {
|
||||
case 'valid':
|
||||
return <div className="recover-password__text_valid">{i18n('VALID_RECOVER')}</div>;
|
||||
case 'invalid':
|
||||
return <div className="recover-password__text_invalid">{i18n('INVALID_RECOVER')}</div>;
|
||||
case 'waiting':
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
handleRecoverPasswordSubmit(formState) {
|
||||
let recoverData = _.clone(formState);
|
||||
recoverData.token = this.props.location.query.token;
|
||||
recoverData.email = this.props.location.query.email;
|
||||
|
||||
UserActions.recoverPassword(formState);
|
||||
},
|
||||
|
||||
onUserStoreChanged(event) {
|
||||
if (event === 'VALID_RECOVER') {
|
||||
this.setState({
|
||||
recoverStatus: 'valid'
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
recoverStatus: 'invalid'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default MainRecoverPasswordPage;
|
|
@ -0,0 +1,19 @@
|
|||
.recover-password {
|
||||
&__inputs {
|
||||
display: inline-block;
|
||||
margin: 0 auto 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&__input {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
&__text_valid {
|
||||
color: green;
|
||||
}
|
||||
|
||||
&__text_invalid {
|
||||
color: red;
|
||||
}
|
||||
}
|
|
@ -63,7 +63,8 @@ const DropDown = React.createClass({
|
|||
let menuProps = {
|
||||
items: this.props.items,
|
||||
onItemClick: this.handleItemClick,
|
||||
onMouseDown: this.handleListMouseDown
|
||||
onMouseDown: this.handleListMouseDown,
|
||||
selectedIndex: this.state.selectedIndex
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -46,5 +46,24 @@ module.exports = [
|
|||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'user/recover-password',
|
||||
time: 100,
|
||||
response: function (data) {
|
||||
|
||||
if (data.password.length > 6) {
|
||||
return {
|
||||
status: 'success',
|
||||
data: {}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: 'fail',
|
||||
message: 'Invalid token',
|
||||
data: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
const englishLanguage = require('data/languages/en');
|
||||
const spanishLanguage = require('data/languages/es');
|
||||
import englishLanguage from 'data/languages/en';
|
||||
import spanishLanguage from 'data/languages/en';
|
||||
import germanLanguage from 'data/languages/en';
|
||||
import frenchLanguage from 'data/languages/en';
|
||||
import chineseLanguage from 'data/languages/en';
|
||||
import turkishLanguage from 'data/languages/en';
|
||||
import indianLanguage from 'data/languages/en';
|
||||
|
||||
const languages = {
|
||||
'us': englishLanguage,
|
||||
'es': spanishLanguage
|
||||
'es': spanishLanguage,
|
||||
'de': germanLanguage,
|
||||
'fr': frenchLanguage,
|
||||
'cn': chineseLanguage,
|
||||
'tr': turkishLanguage,
|
||||
'in': indianLanguage
|
||||
};
|
||||
|
||||
const i18nData = function (key, lang) {
|
||||
|
|
|
@ -2,6 +2,16 @@ export default {
|
|||
'SUBMIT': 'Submit',
|
||||
'LOG_IN': 'Log in',
|
||||
'SIGN_UP': 'Sign up',
|
||||
'FORGOT_PASSWORD': 'Forgot your password?',
|
||||
'RECOVER_PASSWORD': 'Recover Password',
|
||||
'NEW_PASSWORD': 'New password',
|
||||
'REPEAT_NEW_PASSWORD': 'Repeat new password',
|
||||
'VALID_RECOVER': 'Password recovered successfully',
|
||||
'INVALID_RECOVER': 'Invalid recover data',
|
||||
|
||||
//ERRORS
|
||||
'ERROR_EMPTY': 'Invalid value',
|
||||
'ERROR_EMAIL': 'Invalid email'
|
||||
'ERROR_PASSWORD': 'Invalid password',
|
||||
'ERROR_EMAIL': 'Invalid email',
|
||||
'PASSWORD_NOT_MATCH': 'Password does not match'
|
||||
};
|
|
@ -1,7 +0,0 @@
|
|||
export default {
|
||||
'SUBMIT': 'Enviar',
|
||||
'LOG_IN': 'Ingresar',
|
||||
'SIGN_UP': 'Registrarse',
|
||||
'ERROR_EMPTY': 'Valor invalido',
|
||||
'ERROR_EMAIL': 'Email invalido'
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
const Validator = require('lib-app/validations/validator');
|
||||
import Validator from 'lib-app/validations/validator';
|
||||
|
||||
class EmailValidator extends Validator {
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import Validator from 'lib-app/validations/validator';
|
||||
|
||||
class LengthValidator extends Validator {
|
||||
constructor(length, errorKey = 'INVALID_VALUE') {
|
||||
super();
|
||||
|
||||
this.minlength = length;
|
||||
this.errorKey = errorKey;
|
||||
}
|
||||
|
||||
validate(value, form) {
|
||||
if (value.length < this.minlength) return this.getError(this.errorKey);
|
||||
}
|
||||
}
|
||||
|
||||
export default LengthValidator;
|
|
@ -0,0 +1,10 @@
|
|||
import Validator from 'lib-app/validations/validator';
|
||||
|
||||
class RepeatPasswordValidator extends Validator {
|
||||
|
||||
validate(value, form) {
|
||||
if (value !== form.password) return this.getError('PASSWORD_NOT_MATCH');
|
||||
}
|
||||
}
|
||||
|
||||
export default RepeatPasswordValidator;
|
|
@ -1,9 +1,13 @@
|
|||
const Validator = require('lib-app/validations/validator');
|
||||
const EmailValidator = require('lib-app/validations/email-validator');
|
||||
import Validator from 'lib-app/validations/validator';
|
||||
import EmailValidator from 'lib-app/validations/email-validator';
|
||||
import RepeatPasswordValidator from 'lib-app/validations/repeat-password-validator';
|
||||
import LengthValidator from 'lib-app/validations/length-validator';
|
||||
|
||||
let validators = {
|
||||
'DEFAULT': new Validator(),
|
||||
'EMAIL': new EmailValidator()
|
||||
'EMAIL': new EmailValidator(),
|
||||
'PASSWORD': new LengthValidator(6, 'ERROR_PASSWORD'),
|
||||
'REPEAT_PASSWORD': new RepeatPasswordValidator()
|
||||
};
|
||||
|
||||
class ValidatorFactory {
|
||||
|
|
|
@ -11,11 +11,14 @@ let reactDFS = function (children, visitFunction) {
|
|||
let element = stack.pop();
|
||||
let tempChilds = [];
|
||||
|
||||
if(element.props && element.props.children) {
|
||||
React.Children.forEach(element.props.children, child => tempChilds.push(child));
|
||||
if (element) {
|
||||
if (element.props && element.props.children) {
|
||||
React.Children.forEach(element.props.children, child => tempChilds.push(child));
|
||||
}
|
||||
|
||||
visitFunction(element);
|
||||
}
|
||||
|
||||
visitFunction(element);
|
||||
stack = stack.concat(tempChilds.reverse());
|
||||
}
|
||||
};
|
||||
|
@ -26,12 +29,12 @@ let renderChildrenWithProps = function(children, mapFunction) {
|
|||
}
|
||||
|
||||
return React.Children.map(children, function (child) {
|
||||
let props = mapFunction(child);
|
||||
|
||||
if (typeof child !== 'object' || child === null) {
|
||||
return child;
|
||||
}
|
||||
|
||||
let props = mapFunction(child);
|
||||
|
||||
if (!_.isEmpty(props)) {
|
||||
return React.cloneElement(child, props, child.props && child.props.children);
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,7 @@ const UserStore = Reflux.createStore({
|
|||
this.listenTo(UserActions.checkLoginStatus, this.checkLoginStatus);
|
||||
this.listenTo(UserActions.login, this.loginUser);
|
||||
this.listenTo(UserActions.logout, this.logoutUser);
|
||||
this.listenTo(UserActions.recoverPassword, this.recoverPassword);
|
||||
},
|
||||
|
||||
initSession() {
|
||||
|
@ -53,6 +54,18 @@ const UserStore = Reflux.createStore({
|
|||
});
|
||||
},
|
||||
|
||||
recoverPassword(recoverData) {
|
||||
return API.call({
|
||||
path: 'user/recover-password',
|
||||
data: recoverData
|
||||
}).then(() => {
|
||||
this.trigger('VALID_RECOVER');
|
||||
setTimeout(CommonActions.loggedOut, 2000);
|
||||
}, () => {
|
||||
this.trigger('INVALID_RECOVER')
|
||||
});
|
||||
},
|
||||
|
||||
isLoggedIn() {
|
||||
return sessionStore.isLoggedIn();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue