diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
index caed8aaf..5f4ce9ce 100644
--- a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
+++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js
@@ -32,7 +32,7 @@ class AdminPanelMyTickets extends React.Component {
{(this.props.error) ? {i18n('ERROR_RETRIEVING_TICKETS')} : }
diff --git a/client/src/app/admin/panel/users/admin-panel-list-users.js b/client/src/app/admin/panel/users/admin-panel-list-users.js
index 25607145..29a522a7 100644
--- a/client/src/app/admin/panel/users/admin-panel-list-users.js
+++ b/client/src/app/admin/panel/users/admin-panel-list-users.js
@@ -9,6 +9,10 @@ import Table from 'core-components/table';
import SearchBox from 'core-components/search-box';
import Button from 'core-components/button';
import Message from 'core-components/message';
+import Icon from 'core-components/icon';
+import ModalContainer from 'app-components/modal-container';
+import CreateTicketForm from 'app/main/dashboard/dashboard-create-ticket/create-ticket-form';
+import MainSignUpWidget from 'app/main/main-signup/main-signup-widget';
class AdminPanelListUsers extends React.Component {
@@ -37,6 +41,11 @@ class AdminPanelListUsers extends React.Component {
{(this.state.error) ? {i18n('ERROR_RETRIEVING_USERS')} : }
+
+
+
);
}
@@ -149,6 +158,20 @@ class AdminPanelListUsers extends React.Component {
}).then(this.onUsersRetrieved.bind(this)).catch(this.onUsersRejected.bind(this));
}
+ onCreateUser(user) {
+ ModalContainer.openModal(
+
+ );
+ }
+ onCreateUserSuccess() {
+ ModalContainer.closeModal();
+ }
+
onUsersRetrieved(result) {
this.setState({
page: result.data.page * 1,
diff --git a/client/src/app/admin/panel/users/admin-panel-list-users.scss b/client/src/app/admin/panel/users/admin-panel-list-users.scss
index 7b76f23c..0276301d 100644
--- a/client/src/app/admin/panel/users/admin-panel-list-users.scss
+++ b/client/src/app/admin/panel/users/admin-panel-list-users.scss
@@ -21,4 +21,8 @@
display: inline-block;
text-align: center;
}
-}
\ No newline at end of file
+
+ &__add-user-form {
+ max-width: 500px;
+ }
+}
diff --git a/client/src/app/main/main-signup/main-signup-page.js b/client/src/app/main/main-signup/main-signup-page.js
index 03f8fa7c..2af28912 100644
--- a/client/src/app/main/main-signup/main-signup-page.js
+++ b/client/src/app/main/main-signup/main-signup-page.js
@@ -1,112 +1,18 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import _ from 'lodash';
-import i18n from 'lib-app/i18n';
-import API from 'lib-app/api-call';
-
-import Captcha from 'app/main/captcha';
-import SubmitButton from 'core-components/submit-button';
-import Message from 'core-components/message';
-import Form from 'core-components/form';
-import FormField from 'core-components/form-field';
import Widget from 'core-components/widget';
-import Header from 'core-components/header';
+import MainSignUpWidget from 'app/main/main-signup/main-signup-widget';
-class MainSignUpPageWidget extends React.Component {
-
- constructor(props) {
- super(props);
-
- this.state = {
- loading: false,
- email: null
- };
- }
+class MainSignUpPage extends React.Component {
render() {
return (
-
-
-
-
- {this.renderMessage()}
-
+
);
}
-
- renderMessage() {
- switch (this.state.message) {
- case 'success':
- return {i18n('SIGNUP_SUCCESS')};
- case 'fail':
- return {i18n('EMAIL_EXISTS')};
- default:
- return null;
- }
- }
-
- getFormProps() {
- return {
- loading: this.state.loading,
- className: 'signup-widget__form',
- onSubmit: this.onSignupFormSubmit.bind(this)
- };
- }
-
- getInputProps(password) {
- return {
- className: 'signup-widget__input',
- fieldProps: {
- size: 'medium',
- password: password
- }
- };
- }
-
- onSignupFormSubmit(formState) {
- const captcha = this.refs.captcha.getWrappedInstance();
-
- if (!captcha.getValue()) {
- captcha.focus();
- } else {
- 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() {
- this.setState({
- loading: false,
- message: 'success'
- });
- }
-
- onSignupFail() {
- this.setState({
- loading: false,
- message: 'fail'
- });
- }
}
-export default MainSignUpPageWidget;
\ No newline at end of file
+export default MainSignUpPage;
diff --git a/client/src/app/main/main-signup/main-signup-page.scss b/client/src/app/main/main-signup/main-signup-page.scss
index f3110435..15a08918 100644
--- a/client/src/app/main/main-signup/main-signup-page.scss
+++ b/client/src/app/main/main-signup/main-signup-page.scss
@@ -1,23 +1,3 @@
.main-signup-page {
min-height: 669px;
-
- .signup-widget {
- padding: 30px;
- text-align: center;
-
- &__form {
- margin-bottom: 20px;
- }
-
- &__inputs {
- display: inline-block;
- margin: 0 auto;
- }
-
- &__captcha {
- margin: 10px auto 20px;
- height: 78px;
- width: 304px;
- }
- }
-}
\ No newline at end of file
+}
diff --git a/client/src/app/main/main-signup/main-signup-widget.js b/client/src/app/main/main-signup/main-signup-widget.js
new file mode 100644
index 00000000..0b0ab98f
--- /dev/null
+++ b/client/src/app/main/main-signup/main-signup-widget.js
@@ -0,0 +1,123 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import _ from 'lodash';
+import classNames from 'classnames';
+
+import i18n from 'lib-app/i18n';
+import API from 'lib-app/api-call';
+
+import Captcha from 'app/main/captcha';
+import SubmitButton from 'core-components/submit-button';
+import Message from 'core-components/message';
+import Form from 'core-components/form';
+import FormField from 'core-components/form-field';
+import Widget from 'core-components/widget';
+import Header from 'core-components/header';
+
+class MainSignUpWidget extends React.Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ loading: false,
+ email: null
+ };
+ }
+ static propTypes = {
+ onSuccess: React.PropTypes.func,
+ className: React.PropTypes.string
+ };
+
+ render() {
+ return (
+
+
+
+
+ {this.renderMessage()}
+
+ );
+ }
+
+ renderMessage() {
+ switch (this.state.message) {
+ case 'success':
+ return {i18n('SIGNUP_SUCCESS')};
+ case 'fail':
+ return {i18n('EMAIL_EXISTS')};
+ default:
+ return null;
+ }
+ }
+
+ getClass() {
+ let classes = {
+ 'signup-widget': true,
+ [this.props.className]: this.props.className
+ };
+ return classNames(classes);
+ }
+
+ getFormProps() {
+ return {
+ loading: this.state.loading,
+ className: 'signup-widget__form',
+ onSubmit: this.onSignupFormSubmit.bind(this)
+ };
+ }
+
+ getInputProps(password) {
+ return {
+ className: 'signup-widget__input',
+ fieldProps: {
+ size: 'medium',
+ password: password
+ }
+ };
+ }
+
+ onSignupFormSubmit(formState) {
+ const captcha = this.refs.captcha.getWrappedInstance();
+
+ if (!captcha.getValue()) {
+ captcha.focus();
+ } else {
+ 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() {
+ this.setState({
+ loading: false,
+ message: 'success'
+ });
+ }
+
+ onSignupFail() {
+ this.setState({
+ loading: false,
+ message: 'fail'
+ });
+ }
+}
+
+export default MainSignUpWidget;
diff --git a/client/src/app/main/main-signup/main-signup-widget.scss b/client/src/app/main/main-signup/main-signup-widget.scss
new file mode 100644
index 00000000..388bf1e5
--- /dev/null
+++ b/client/src/app/main/main-signup/main-signup-widget.scss
@@ -0,0 +1,19 @@
+ .signup-widget {
+ padding: 30px;
+ text-align: center;
+
+ &__form {
+ margin-bottom: 20px;
+ }
+
+ &__inputs {
+ display: inline-block;
+ margin: 0 auto;
+ }
+
+ &__captcha {
+ margin: 10px auto 20px;
+ height: 78px;
+ width: 304px;
+ }
+ }
diff --git a/client/src/data/languages/br.js b/client/src/data/languages/br.js
index 12e23c8a..2db0f5b4 100644
--- a/client/src/data/languages/br.js
+++ b/client/src/data/languages/br.js
@@ -181,6 +181,8 @@ export default {
'UPDATE': 'Atualizar',
'NEVER': 'Nunca',
'HIMSELF': 'ele mesmo',
+ 'ADD_USER': 'Adicionar usuário',
+
'CHART_CREATE_TICKET': 'Chamados criados',
'CHART_CLOSE': 'Chamados fechados',
diff --git a/client/src/data/languages/cn.js b/client/src/data/languages/cn.js
index ab259450..8c3c1ada 100644
--- a/client/src/data/languages/cn.js
+++ b/client/src/data/languages/cn.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': '更新',
'NEVER': '从来没有',
'HIMSELF': '他自己',
+ 'ADD_USER': '添加用户',
'CHART_CREATE_TICKET': '已創建門票',
'CHART_CLOSE': '門票已關閉',
diff --git a/client/src/data/languages/de.js b/client/src/data/languages/de.js
index e6b172b6..3aa3cff7 100644
--- a/client/src/data/languages/de.js
+++ b/client/src/data/languages/de.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Aktualisierung',
'NEVER': 'Niemals',
'HIMSELF': 'selbst',
+ 'ADD_USER': 'Benutzer hinzufügen',
'CHART_CREATE_TICKET': 'Tickets erstellt',
'CHART_CLOSE': 'Tickets geschlossen',
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index 8a980634..0ad22724 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Update',
'NEVER': 'Never',
'HIMSELF': 'himself',
+ 'ADD_USER': 'Add user',
'CHART_CREATE_TICKET': 'Tickets created',
'CHART_CLOSE': 'Tickets closed',
diff --git a/client/src/data/languages/es.js b/client/src/data/languages/es.js
index 072bcd83..1780b8de 100644
--- a/client/src/data/languages/es.js
+++ b/client/src/data/languages/es.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Actualizar',
'NEVER': 'Nunca',
'HIMSELF': 'si mismo',
+ 'ADD_USER': 'Añadir un usuario',
'CHART_CREATE_TICKET': 'Tickets creados',
'CHART_CLOSE': 'Tickets cerrados',
diff --git a/client/src/data/languages/fr.js b/client/src/data/languages/fr.js
index ee88f58e..38264122 100644
--- a/client/src/data/languages/fr.js
+++ b/client/src/data/languages/fr.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Mettre à jour',
'NEVER': 'Jamais',
'HIMSELF': 'lui-même',
+ 'ADD_USER': 'Ajouter un utilisateur',
'CHART_CREATE_TICKET': 'Tickets créés',
'CHART_CLOSE': 'Tickets fermés',
diff --git a/client/src/data/languages/gr.js b/client/src/data/languages/gr.js
index 11af28a9..0388334c 100644
--- a/client/src/data/languages/gr.js
+++ b/client/src/data/languages/gr.js
@@ -182,6 +182,7 @@
'UPDATE': 'Ενημέρωση',
'NEVER': 'Ποτέ',
'HIMSELF': 'ο ίδιος',
+ 'ADD_USER': 'Πρόσθεσε χρήστη',
'CHART_CREATE_TICKET': 'Τα εισιτήρια δημιουργήθηκαν',
'CHART_CLOSE': 'Τα εισιτήρια κλείσανε',
diff --git a/client/src/data/languages/in.js b/client/src/data/languages/in.js
index dfb3c2be..9f536524 100644
--- a/client/src/data/languages/in.js
+++ b/client/src/data/languages/in.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'अद्यतन',
'NEVER': 'कभी नहीँ',
'HIMSELF': 'स्वयं',
+ 'ADD_USER': 'उपयोगकर्ता जोड़ें',
'CHART_CREATE_TICKET': 'टिकट बनाया',
'CHART_CLOSE': 'टिकट बंद कर दिया',
diff --git a/client/src/data/languages/it.js b/client/src/data/languages/it.js
index cf94a0eb..ff7834c0 100644
--- a/client/src/data/languages/it.js
+++ b/client/src/data/languages/it.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Aggiornare',
'NEVER': 'Mai',
'HIMSELF': 'lui stesso',
+ 'ADD_USER': 'Aggiungi utente',
'CHART_CREATE_TICKET': 'Tickets creato',
'CHART_CLOSE': 'Tickets chiuso',
diff --git a/client/src/data/languages/jp.js b/client/src/data/languages/jp.js
index 3d1751f2..70940caa 100644
--- a/client/src/data/languages/jp.js
+++ b/client/src/data/languages/jp.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': '更新',
'NEVER': '決して',
'HIMSELF': '彼自身',
+ 'ADD_USER': 'ユーザーを追加する',
'CHART_CREATE_TICKET': '作成されたチケット',
'CHART_CLOSE': 'チケットが閉じられました',
diff --git a/client/src/data/languages/nl.js b/client/src/data/languages/nl.js
index c7e96fa0..199afddc 100644
--- a/client/src/data/languages/nl.js
+++ b/client/src/data/languages/nl.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Update',
'NEVER': 'Nooit',
'HIMSELF': 'zichzelf',
+ 'ADD_USER': 'Voeg gebruiker toe',
'CHART_CREATE_TICKET': 'Aangemaakte incidenten',
'CHART_CLOSE': 'Gesloten incidenten',
diff --git a/client/src/data/languages/pt.js b/client/src/data/languages/pt.js
index d2eb7d54..ac3dbba9 100644
--- a/client/src/data/languages/pt.js
+++ b/client/src/data/languages/pt.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Actualizar',
'NEVER': 'Nunca',
'HIMSELF': 'ele mesmo',
+ 'ADD_USER': 'Adicionar usuário',
'CHART_CREATE_TICKET': 'Ingressos criados',
'CHART_CLOSE': 'Ingressos fechados',
diff --git a/client/src/data/languages/ru.js b/client/src/data/languages/ru.js
index 1d3dce2b..57201e82 100644
--- a/client/src/data/languages/ru.js
+++ b/client/src/data/languages/ru.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Обновить',
'NEVER': 'Никогда',
'HIMSELF': 'сам',
+ 'ADD_USER': 'Добавить пользователя',
'CHART_CREATE_TICKET': 'Билеты создано',
'CHART_CLOSE': ' Билеты закрыты',
diff --git a/client/src/data/languages/tr.js b/client/src/data/languages/tr.js
index 0e5fb187..73f03f3b 100644
--- a/client/src/data/languages/tr.js
+++ b/client/src/data/languages/tr.js
@@ -182,6 +182,7 @@ export default {
'UPDATE': 'Güncelleştirme',
'NEVER': 'Asla',
'HIMSELF': 'kendisi',
+ 'ADD_USER': 'Kullanıcı Ekle',
'CHART_CREATE_TICKET': 'Biletler oluşturuldu',
'CHART_CLOSE': 'Biletler kapandı',
diff --git a/server/controllers/staff/edit.php b/server/controllers/staff/edit.php
index d61cb93f..eb7d8d7e 100755
--- a/server/controllers/staff/edit.php
+++ b/server/controllers/staff/edit.php
@@ -67,7 +67,7 @@ class EditStaffController extends Controller {
return;
}
} else {
- Response::respondError($staffId);
+ Response::respondError(ERRORS::NO_PERMISSION);
return;
}
diff --git a/server/controllers/user/signup.php b/server/controllers/user/signup.php
index 27bc2c8f..5a6c187b 100755
--- a/server/controllers/user/signup.php
+++ b/server/controllers/user/signup.php
@@ -97,7 +97,7 @@ class SignUpController extends Controller {
throw new Exception(ERRORS::ALREADY_BANNED);
}
- if (!Setting::getSetting('registration')->value && $apiKey->isNull() && !$this->csvImported) {
+ if (!Setting::getSetting('registration')->value && $apiKey->isNull() && !Controller::isStaffLogged(2) && !$this->csvImported) {
throw new Exception(ERRORS::NO_PERMISSION);
}