From f558e64afca96240c2434c292f7783c73b12ed8f Mon Sep 17 00:00:00 2001 From: Maxi Redigonda Date: Mon, 21 Oct 2019 17:44:49 -0300 Subject: [PATCH] First mock for an 'invite user' button in the list-user view --- .../panel/users/admin-panel-list-users.js | 18 ++ .../admin/panel/users/invite-user-widget.js | 165 ++++++++++++++++++ .../admin/panel/users/invite-user-widget.scss | 19 ++ client/src/data/languages/en.js | 3 + 4 files changed, 205 insertions(+) create mode 100644 client/src/app/admin/panel/users/invite-user-widget.js create mode 100644 client/src/app/admin/panel/users/invite-user-widget.scss 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 b2997af2..98fbc06f 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 @@ -13,6 +13,7 @@ import Message from 'core-components/message'; import Icon from 'core-components/icon'; import ModalContainer from 'app-components/modal-container'; import MainSignUpWidget from 'app/main/main-signup/main-signup-widget'; +import InviteUserWidget from 'app/admin/panel/users/invite-user-widget'; class AdminPanelListUsers extends React.Component { @@ -45,6 +46,9 @@ class AdminPanelListUsers extends React.Component { + ); @@ -181,6 +185,20 @@ class AdminPanelListUsers extends React.Component { ModalContainer.closeModal(); } + onInviteUser(user) { + ModalContainer.openModal( +
+ +
+ +
+
+ ); + } + onInviteUserSuccess() { + ModalContainer.closeModal(); + } + onUsersRetrieved(result) { this.setState({ page: result.data.page * 1, diff --git a/client/src/app/admin/panel/users/invite-user-widget.js b/client/src/app/admin/panel/users/invite-user-widget.js new file mode 100644 index 00000000..8336724d --- /dev/null +++ b/client/src/app/admin/panel/users/invite-user-widget.js @@ -0,0 +1,165 @@ +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 InviteUserWidget extends React.Component { + + static propTypes = { + onSuccess: React.PropTypes.func, + className: React.PropTypes.string + }; + + constructor(props) { + super(props); + + this.state = { + loading: false, + email: null, + customFields: [] + }; + } + + componentDidMount() { + API.call({ + path: '/system/get-custom-fields', + data: {} + }) + .then(result => this.setState({customFields: result.data})); + } + + render() { + return ( + +
+
+
+ + + {this.state.customFields.map(this.renderCustomField.bind(this))} +
+
+ +
+ {i18n('INVITE_USER')} +
+ + {this.renderMessage()} + + ); + } + + renderCustomField(customField, key) { + if(customField.type === 'text') { + return ( + + ); + } else { + const items = customField.options.map(option => ({content: option.name, value: option.name})); + + return ( + + ); + } + } + + renderMessage() { + switch (this.state.message) { + case 'success': + return {i18n('INVITE_USER_SUCCESS')}; + case 'fail': + return {i18n('EMAIL_EXISTS')}; + default: + return null; + } + } + + getClass() { + let classes = { + 'invite-user-widget': true, + [this.props.className]: this.props.className + }; + return classNames(classes); + } + + getFormProps() { + return { + loading: this.state.loading, + className: 'invite-user-widget__form', + onSubmit: this.onInviteUserFormSubmit.bind(this) + }; + } + + getInputProps(password) { + return { + className: 'invite-user-widget__input', + fieldProps: { + size: 'medium', + password: password + } + }; + } + + onInviteUserFormSubmit(formState) { + const captcha = this.refs.captcha.getWrappedInstance(); + + if (!captcha.getValue()) { + captcha.focus(); + } else { + this.setState({ + loading: true + }); + + const form = _.clone(formState); + + this.state.customFields.forEach(customField => { + if(customField.type === 'select') { + form[`customfield_${customField.name}`] = customField.options[form[`customfield_${customField.name}`]].name; + } + }) + + API.call({ + path: '/user/invite', + data: _.extend({captcha: captcha.getValue()}, form) + }).then(this.onInviteUserSuccess.bind(this)).catch(this.onInviteUserFail.bind(this)); + } + } + + onInviteUserSuccess() { + this.setState({ + loading: false, + message: 'success' + }); + } + + onInviteUserFail() { + this.setState({ + loading: false, + message: 'fail' + }); + } +} + +export default InviteUserWidget; diff --git a/client/src/app/admin/panel/users/invite-user-widget.scss b/client/src/app/admin/panel/users/invite-user-widget.scss new file mode 100644 index 00000000..9ecbf748 --- /dev/null +++ b/client/src/app/admin/panel/users/invite-user-widget.scss @@ -0,0 +1,19 @@ +.invite-user-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/en.js b/client/src/data/languages/en.js index 6373f738..984d76d8 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -193,6 +193,7 @@ export default { 'NEVER': 'Never', 'HIMSELF': 'himself', 'ADD_USER': 'Add user', + 'INVITE_USER': 'Invite user', 'UPLOAD_FILE': 'Upload file', 'PRIVATE': 'Private', 'ENABLE_USER': 'Enable User', @@ -336,6 +337,7 @@ export default { 'IMAP_POLLING_DESCRIPTION': 'Inbox checking will not be done automatically by OpenSupports. You have to make POST requests periodically to this url to process the emails: {url}', 'NEW_CUSTOM_FIELD_DESCRIPTION': 'Here you can create a custom field for an user, it can be a blank text box or a fixed set of options.', 'CUSTOM_FIELDS_DESCRIPTION': 'Custom fields are defined additional fields the users are able to fill to provide more information about them.', + 'INVITE_USER_VIEW_DESCRIPTION': 'Here you can invite an user to join our support system, he will just need to provide his password to create a new user.', //ERRORS 'EMAIL_OR_PASSWORD': 'Email or password invalid', @@ -372,6 +374,7 @@ export default { //MESSAGES 'SIGNUP_SUCCESS': 'You have registered successfully in our support system.', + 'INVITE_USER_SUCCESS': 'You have invited a new user successfully in our support system', 'TICKET_SENT': 'Ticket has been created successfully.', 'VALID_RECOVER': 'Password recovered successfully', 'EMAIL_EXISTS': 'Email already exists',