Ivan - Frontend - Add captcha and departments from globals [skip ci]

This commit is contained in:
ivan 2016-08-20 17:30:07 -03:00
parent d638465ea6
commit 7dc7e14168
9 changed files with 75 additions and 26 deletions

View File

@ -65,7 +65,7 @@
"react": "^15.0.1", "react": "^15.0.1",
"react-document-title": "^1.0.2", "react-document-title": "^1.0.2",
"react-dom": "^15.0.1", "react-dom": "^15.0.1",
"react-google-recaptcha": "^0.5.2", "react-google-recaptcha": "^0.5.4",
"react-motion": "^0.3.0", "react-motion": "^0.3.0",
"react-redux": "^4.4.5", "react-redux": "^4.4.5",
"react-router": "^2.4.0", "react-router": "^2.4.0",

View File

@ -11,8 +11,8 @@ const ConfigActions = requireUnit('actions/config-actions', {
describe('Config Actions,', function () { describe('Config Actions,', function () {
describe('init action', function () { describe('init action', function () {
it('should return INIT_CONFIGS_FULFILLED with configs if it is already retrieved', function () { it('should return INIT_CONFIGS_FULFILLED with configs if it user is logged in', function () {
sessionStoreMock.areConfigsStored.returns(true); sessionStoreMock.isLoggedIn.returns(true);
sessionStoreMock.getConfigs.returns({ sessionStoreMock.getConfigs.returns({
config1: 'CONFIG_1', config1: 'CONFIG_1',
config2: 'CONFIG_2' config2: 'CONFIG_2'
@ -31,7 +31,7 @@ describe('Config Actions,', function () {
it('should return INIT_CONFIGS with API_RESULT if it is not retrieved', function () { it('should return INIT_CONFIGS with API_RESULT if it is not retrieved', function () {
APICallMock.call.reset(); APICallMock.call.reset();
sessionStoreMock.areConfigsStored.returns(false); sessionStoreMock.isLoggedIn.returns(false);
sessionStoreMock.getConfigs.returns({ sessionStoreMock.getConfigs.returns({
config1: 'CONFIG_1', config1: 'CONFIG_1',
config2: 'CONFIG_2' config2: 'CONFIG_2'

View File

@ -3,7 +3,7 @@ import sessionStore from 'lib-app/session-store';
export default { export default {
init() { init() {
if (sessionStore.areConfigsStored()) { if (sessionStore.isLoggedIn()) {
return { return {
type: 'INIT_CONFIGS_FULFILLED', type: 'INIT_CONFIGS_FULFILLED',
payload: { payload: {

View File

@ -2,6 +2,8 @@ import API from 'lib-app/api-call';
import sessionStore from 'lib-app/session-store'; import sessionStore from 'lib-app/session-store';
import store from 'app/store'; import store from 'app/store';
import ConfigActions from 'actions/config-actions';
export default { export default {
login(loginData) { login(loginData) {
return { return {

View File

@ -0,0 +1,35 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReCAPTCHA from 'react-google-recaptcha';
import {connect} from 'react-redux';
class Captcha extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
}
render() {
return (
<ReCAPTCHA sitekey={this.props.sitekey} ref="reCaptcha" onChange={(value) => {this.setState({value})}} tabIndex="0" />
);
}
getValue() {
return this.state.value;
}
focus() {
ReactDOM.findDOMNode(this).focus();
}
}
export default connect((store) => {
return {
sitekey: store.config.reCaptchaKey
};
}, null, null, { withRef: true })(Captcha);

View File

@ -4,6 +4,7 @@ import { browserHistory } from 'react-router';
import i18n from 'lib-app/i18n'; import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call'; import API from 'lib-app/api-call';
import SessionStore from 'lib-app/session-store';
import store from 'app/store'; import store from 'app/store';
import SessionActions from 'actions/session-actions'; import SessionActions from 'actions/session-actions';
@ -41,11 +42,7 @@ class CreateTicketForm extends React.Component {
<div className="row"> <div className="row">
<FormField className="col-md-7" label="Title" name="title" validation="TITLE" required field="input" fieldProps={{size: 'large'}}/> <FormField className="col-md-7" label="Title" name="title" validation="TITLE" required field="input" fieldProps={{size: 'large'}}/>
<FormField className="col-md-5" label="Department" name="departmentId" field="select" fieldProps={{ <FormField className="col-md-5" label="Department" name="departmentId" field="select" fieldProps={{
items: [ items: SessionStore.getDepartments().map((department) => {return {content: department}}),
{content: 'Sales Support'},
{content: 'Technical Issues'},
{content: 'System and Administration'}
],
size: 'medium' size: 'medium'
}} /> }} />
</div> </div>
@ -70,7 +67,7 @@ class CreateTicketForm extends React.Component {
renderCaptcha() { renderCaptcha() {
return ( return (
<div className="create-ticket-form__captcha"> <div className="create-ticket-form__captcha">
<ReCAPTCHA sitekey="6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS" onChange={function () {}}/> <Captcha />
</div> </div>
); );
} }

View File

@ -1,9 +1,11 @@
import React from 'react'; import React from 'react';
import ReCAPTCHA from 'react-google-recaptcha'; import ReactDOM from 'react-dom';
import _ from 'lodash';
import i18n from 'lib-app/i18n'; import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call'; import API from 'lib-app/api-call';
import Captcha from 'app/main/captcha';
import SubmitButton from 'core-components/submit-button'; import SubmitButton from 'core-components/submit-button';
import Message from 'core-components/message'; import Message from 'core-components/message';
import Form from 'core-components/form'; import Form from 'core-components/form';
@ -34,7 +36,7 @@ class MainSignUpPageWidget extends React.Component {
<FormField {...this.getInputProps(true)} label="Repeat Password" name="repeated-password" validation="REPEAT_PASSWORD" required/> <FormField {...this.getInputProps(true)} label="Repeat Password" name="repeated-password" validation="REPEAT_PASSWORD" required/>
</div> </div>
<div className="signup-widget__captcha"> <div className="signup-widget__captcha">
<ReCAPTCHA sitekey="6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS" onChange={function () {}}/> <Captcha ref="captcha"/>
</div> </div>
<SubmitButton type="primary">SIGN UP</SubmitButton> <SubmitButton type="primary">SIGN UP</SubmitButton>
</Form> </Form>
@ -75,14 +77,20 @@ class MainSignUpPageWidget extends React.Component {
} }
onLoginFormSubmit(formState) { onLoginFormSubmit(formState) {
this.setState({ const captcha = this.refs.captcha.getWrappedInstance();
loading: true
});
API.call({ if (!captcha.getValue()) {
path: '/user/signup', captcha.focus();
data: formState } else {
}).then(this.onSignupSuccess.bind(this)).catch(this.onSignupFail.bind(this)); this.setState({
loading: true
});
API.call({
path: '/user/signup',
data: _.extend({captcha: captcha.getValue()}, formState)
}).then(this.onSignupSuccess.bind(this)).catch(this.onSignupFail.bind(this));
}
} }
onSignupSuccess() { onSignupSuccess() {

View File

@ -7,7 +7,12 @@ module.exports = [
status: 'success', status: 'success',
data: { data: {
'language': 'us', 'language': 'us',
'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS' 'reCaptchaKey': '6LfM5CYTAAAAAGLz6ctpf-hchX2_l0Ge-Bn-n8wS',
'departments': [
'Sales Support',
'Technical Issues',
'System and Administration'
]
} }
}; };
} }

View File

@ -42,6 +42,10 @@ class SessionStore {
return JSON.parse(this.getItem('userData')); return JSON.parse(this.getItem('userData'));
} }
getDepartments() {
return JSON.parse(this.getItem('departments'));
}
storeRememberData({token, userId, expiration}) { storeRememberData({token, userId, expiration}) {
this.setItem('rememberData-token', token); this.setItem('rememberData-token', token);
this.setItem('rememberData-userId', userId); this.setItem('rememberData-userId', userId);
@ -51,19 +55,17 @@ class SessionStore {
storeConfigs(configs) { storeConfigs(configs) {
this.setItem('language', configs.language); this.setItem('language', configs.language);
this.setItem('reCaptchaKey', configs.reCaptchaKey); this.setItem('reCaptchaKey', configs.reCaptchaKey);
this.setItem('departments', JSON.stringify(configs.departments));
} }
getConfigs() { getConfigs() {
return { return {
language: this.getItem('language'), language: this.getItem('language'),
reCaptchaKey: this.getItem('reCaptchaKey') reCaptchaKey: this.getItem('reCaptchaKey'),
departments: this.getDepartments()
}; };
} }
areConfigsStored() {
return !!this.getItem('reCaptchaKey');
}
isRememberDataExpired() { isRememberDataExpired() {
let rememberData = this.getRememberData(); let rememberData = this.getRememberData();