Ivan - Backend - Fixes to make frontend work with API [skip ci]

This commit is contained in:
ivan 2016-09-09 02:24:12 -03:00
parent c787be375d
commit 06ad75b688
14 changed files with 106 additions and 31 deletions

View File

@ -17,7 +17,7 @@ gulp.task('server', function() {
server.use(express.static(config.buildDir)); server.use(express.static(config.buildDir));
// Proxy php server api // Proxy php server api
server.use('/api', proxy('http://localhost:8080/', { server.use('/api', proxy('http://localhost:8080', {
forwardPath: function(req, res) { forwardPath: function(req, res) {
return require('url').parse(req.url).path; return require('url').parse(req.url).path;
} }

View File

@ -12,7 +12,7 @@ export default {
path: '/user/login', path: '/user/login',
data: loginData data: loginData
}).then((result) => { }).then((result) => {
store.dispatch(this.getUserData(result.data.userId)); store.dispatch(this.getUserData(result.data.userId, result.data.token));
return result; return result;
}) })
@ -32,7 +32,7 @@ export default {
isAutomatic: true isAutomatic: true
} }
}).then((result) => { }).then((result) => {
store.dispatch(this.getUserData(result.data.userId)); store.dispatch(this.getUserData(result.data.userId, result.data.token));
return result; return result;
}) })
@ -49,14 +49,21 @@ export default {
}; };
}, },
getUserData(userId) { getUserData(userId, token) {
let data = {};
if (userId && token) {
data = {
csrf_userid: userId,
csrf_token: token
};
}
return { return {
type: 'USER_DATA', type: 'USER_DATA',
payload: API.call({ payload: API.call({
path: '/user/get', path: '/user/get',
data: { data: data
userId: userId
}
}) })
} }
}, },

View File

@ -14,13 +14,13 @@ class Captcha extends React.Component {
} }
render() { render() {
return ( return (this.props.sitekey) ? (
<ReCAPTCHA sitekey={this.props.sitekey} ref="reCaptcha" onChange={(value) => {this.setState({value})}} tabIndex="0" /> <ReCAPTCHA sitekey={this.props.sitekey} ref="reCaptcha" onChange={(value) => {this.setState({value})}} tabIndex="0" />
); ) : <div></div>;
} }
getValue() { getValue() {
return this.state.value; return (this.props.sitekey) ? this.state.value : 'valid';
} }
focus() { focus() {

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import _ from 'lodash';
import ReCAPTCHA from 'react-google-recaptcha'; import ReCAPTCHA from 'react-google-recaptcha';
import { browserHistory } from 'react-router'; import { browserHistory } from 'react-router';
@ -90,7 +91,9 @@ class CreateTicketForm extends React.Component {
API.call({ API.call({
path: '/ticket/create', path: '/ticket/create',
data: formState data: _.extend({}, formState, {
departmentId: formState.departmentId + 1
})
}).then(this.onTicketSuccess.bind(this)).catch(this.onTicketFail.bind(this)); }).then(this.onTicketSuccess.bind(this)).catch(this.onTicketFail.bind(this));
} }

View File

@ -50,7 +50,7 @@ class TicketAction extends React.Component {
<span className="ticket-action__comment-author-type">({i18n((config.author.staff) ? 'STAFF' : 'CUSTOMER')})</span> <span className="ticket-action__comment-author-type">({i18n((config.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
</div> </div>
<div className="ticket-action__comment-date">{config.date}</div> <div className="ticket-action__comment-date">{config.date}</div>
<div className="ticket-action__comment-content">{config.content}</div> <div className="ticket-action__comment-content" dangerouslySetInnerHTML={{__html: config.content}}></div>
{this.renderFileRow(config.file)} {this.renderFileRow(config.file)}
</div> </div>
); );

View File

@ -1,6 +1,11 @@
import React from 'react'; import React from 'react';
import _ from 'lodash';
import i18n from 'lib-app/i18n'; import i18n from 'lib-app/i18n';
import API from 'lib-app/api-call';
import store from 'app/store';
import SessionActions from 'actions/session-actions';
import TicketAction from 'app/main/dashboard/dashboard-ticket/ticket-action'; import TicketAction from 'app/main/dashboard/dashboard-ticket/ticket-action';
import Form from 'core-components/form'; import Form from 'core-components/form';
import FormField from 'core-components/form-field'; import FormField from 'core-components/form-field';
@ -19,6 +24,15 @@ class TicketViewer extends React.Component {
} }
}; };
constructor(props) {
super(props);
this.state = {
loading: false
};
}
render() { render() {
return ( return (
<div className="ticket-viewer"> <div className="ticket-viewer">
@ -45,7 +59,7 @@ class TicketViewer extends React.Component {
<div className="ticket-viewer__response"> <div className="ticket-viewer__response">
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div> <div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
<div className="ticket-viewer__response-field row"> <div className="ticket-viewer__response-field row">
<Form> <Form onSubmit={this.onSubmit.bind(this)} loading={this.state.loading}>
<FormField name="content" validation="TEXT_AREA" required field="textarea" /> <FormField name="content" validation="TEXT_AREA" required field="textarea" />
<SubmitButton>{i18n('RESPOND_TICKET')}</SubmitButton> <SubmitButton>{i18n('RESPOND_TICKET')}</SubmitButton>
</Form> </Form>
@ -60,6 +74,33 @@ class TicketViewer extends React.Component {
<TicketAction type="comment" config={comment} key={index} /> <TicketAction type="comment" config={comment} key={index} />
); );
} }
onSubmit(formState) {
this.setState({
loading: true
});
API.call({
path: '/ticket/comment',
data: _.extend({
ticketNumber: this.props.ticket.ticketNumber
}, formState)
}).then(this.onCommentSuccess.bind(this), this.onCommentFail.bind(this));
}
onCommentSuccess() {
this.setState({
loading: false
});
store.dispatch(SessionActions.getUserData());
}
onCommentFail() {
this.setState({
loading: false
});
}
} }
export default TicketViewer; export default TicketViewer;

View File

@ -55,7 +55,7 @@ class MainLayoutHeader extends React.Component {
return { return {
className: 'main-layout-header__languages', className: 'main-layout-header__languages',
items: this.getLanguageList(), items: this.getLanguageList(),
selectedIndex: Object.keys(codeLanguages).map((key) => codeLanguages[key]).indexOf(this.props.config.language), selectedIndex: Object.keys(codeLanguages).map((key) => codeLanguages[key]).indexOf(this.getPropLanguage()),
onChange: this.changeLanguage.bind(this) onChange: this.changeLanguage.bind(this)
}; };
} }
@ -69,10 +69,24 @@ class MainLayoutHeader extends React.Component {
}); });
} }
changeLanguage(event) { getPropLanguage() {
let language = Object.keys(codeLanguages)[event.index]; let language = this.props.config.language;
this.props.dispatch(ConfigActions.changeLanguage(codeLanguages[language])); if (language === 'en') {
language = 'us';
}
return language;
}
changeLanguage(event) {
let language = codeLanguages[Object.keys(codeLanguages)[event.index]];
if (language === 'us') {
language = 'en';
}
this.props.dispatch(ConfigActions.changeLanguage(language));
} }
} }

View File

@ -32,8 +32,8 @@ class MainRecoverPasswordPage extends React.Component {
<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.onRecoverPasswordSubmit.bind(this)} loading={this.state.loading}> <Form className="recover-password__form" onSubmit={this.onRecoverPasswordSubmit.bind(this)} loading={this.state.loading}>
<div className="recover-password__inputs"> <div className="recover-password__inputs">
<FormField placeholder={i18n('NEW_PASSWORD')} name="password" className="recover-password__input" validation="PASSWORD" password required/> <FormField placeholder={i18n('NEW_PASSWORD')} name="password" className="recover-password__input" validation="PASSWORD" fieldProps={{password: true}} required/>
<FormField placeholder={i18n('REPEAT_NEW_PASSWORD')} name="password-repeat" className="recover-password__input" validation="REPEAT_PASSWORD" password required/> <FormField placeholder={i18n('REPEAT_NEW_PASSWORD')} name="password-repeat" className="recover-password__input" validation="REPEAT_PASSWORD" fieldProps={{password: true}} required/>
</div> </div>
<div className="recover-password__submit-button"> <div className="recover-password__submit-button">
<SubmitButton type="primary">{i18n('SUBMIT')}</SubmitButton> <SubmitButton type="primary">{i18n('SUBMIT')}</SubmitButton>

View File

@ -4,6 +4,7 @@ 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 SessionStore from 'lib-app/session-store';
import Captcha from 'app/main/captcha'; import Captcha from 'app/main/captcha';
import SubmitButton from 'core-components/submit-button'; import SubmitButton from 'core-components/submit-button';

View File

@ -7,7 +7,7 @@ import turkishLanguage from 'data/languages/en';
import indianLanguage from 'data/languages/en'; import indianLanguage from 'data/languages/en';
const languages = { const languages = {
'us': englishLanguage, 'en': englishLanguage,
'es': spanishLanguage, 'es': spanishLanguage,
'de': germanLanguage, 'de': germanLanguage,
'fr': frenchLanguage, 'fr': frenchLanguage,

View File

@ -5,7 +5,10 @@ const SessionStore = require('lib-app/session-store');
const root = 'http://localhost:3000/api'; const root = 'http://localhost:3000/api';
function processData (data) { function processData (data) {
return _.extend(SessionStore.getSessionData(), data); return _.extend({
csrf_token: SessionStore.getSessionData().token,
csrf_userid: SessionStore.getSessionData().userId
}, data);
} }
module.exports = { module.exports = {

View File

@ -2,6 +2,7 @@
include 'user/login.php'; include 'user/login.php';
include 'user/signup.php'; include 'user/signup.php';
include 'user/logout.php'; include 'user/logout.php';
include 'user/check-session.php';
include 'user/recover-password.php'; include 'user/recover-password.php';
include 'user/send-recover-password.php'; include 'user/send-recover-password.php';
include 'user/edit-password.php'; include 'user/edit-password.php';
@ -14,6 +15,7 @@ $userControllers->setGroupPath('/user');
$userControllers->addController(new LoginController); $userControllers->addController(new LoginController);
$userControllers->addController(new SignUpController); $userControllers->addController(new SignUpController);
$userControllers->addController(new LogoutController); $userControllers->addController(new LogoutController);
$userControllers->addController(new CheckSessionController);
$userControllers->addController(new SendRecoverPasswordController); $userControllers->addController(new SendRecoverPasswordController);
$userControllers->addController(new RecoverPasswordController); $userControllers->addController(new RecoverPasswordController);
$userControllers->addController(new EditPassword); $userControllers->addController(new EditPassword);

View File

@ -37,7 +37,13 @@ class SignUpController extends Controller {
public function handler() { public function handler() {
$this->storeRequestData(); $this->storeRequestData();
try { $existentUser = User::getUser($this->userEmail, 'email');
if (!$existentUser->isNull()) {
Response::respondError(ERRORS::USER_EXISTS);
return;
}
$userId = $this->createNewUserAndRetrieveId(); $userId = $this->createNewUserAndRetrieveId();
$this->sendRegistrationMail(); $this->sendRegistrationMail();
@ -45,9 +51,6 @@ class SignUpController extends Controller {
'userId' => $userId, 'userId' => $userId,
'userEmail' => $this->userEmail 'userEmail' => $this->userEmail
]); ]);
} catch (Exception $e) {
Response::respondError($e->getMessage());
}
} }

View File

@ -2,6 +2,7 @@
class ERRORS { class ERRORS {
const INVALID_CREDENTIALS = 'User or password is not defined'; const INVALID_CREDENTIALS = 'User or password is not defined';
const SESSION_EXISTS = 'User is already logged in'; const SESSION_EXISTS = 'User is already logged in';
const USER_EXISTS = 'Email already exists';
const NO_PERMISSION = 'You have no permission to access'; const NO_PERMISSION = 'You have no permission to access';
const INVALID_TITLE = 'Invalid title'; const INVALID_TITLE = 'Invalid title';
const INVALID_CONTENT = 'Invalid content'; const INVALID_CONTENT = 'Invalid content';