diff --git a/client/package.json b/client/package.json index 09757c3a..25f14d6c 100644 --- a/client/package.json +++ b/client/package.json @@ -55,6 +55,7 @@ "dependencies": { "app-module-path": "^1.0.3", "classnames": "^2.1.3", + "draft-js": "^0.8.1", "jquery": "^2.1.4", "keycode": "^2.1.4", "localStorage": "^1.0.3", diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js new file mode 100644 index 00000000..44f62ffa --- /dev/null +++ b/client/src/app/main/dashboard/dashboard-create-ticket/create-ticket-form.js @@ -0,0 +1,33 @@ +import React from 'react'; +import ReCAPTCHA from 'react-google-recaptcha'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import SubmitButton from 'core-components/submit-button'; +import Message from 'core-components/message'; +import Form from 'core-components/form'; +import Input from 'core-components/input'; +import TextEditor from 'core-components/text-editor'; +import DropDown from 'core-components/drop-down'; +import Widget from 'core-components/widget'; + +class CreateTicketForm extends React.Component { + render() { + return ( +
+
+ + + + +
+ ); + } +} + +export default CreateTicketForm; \ No newline at end of file diff --git a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js index 9914bc12..596cc4a9 100644 --- a/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js +++ b/client/src/app/main/dashboard/dashboard-create-ticket/dashboard-create-ticket-page.js @@ -1,11 +1,13 @@ import React from 'react'; +import CreateTicketForm from 'app/main/dashboard/dashboard-create-ticket/create-ticket-form'; + class DashboardCreateTicketPage extends React.Component { render() { return (
- DASHBOARD CREATE TICKET +
); } diff --git a/client/src/app/main/main-layout.js b/client/src/app/main/main-layout.js index 74be940d..5a259324 100644 --- a/client/src/app/main/main-layout.js +++ b/client/src/app/main/main-layout.js @@ -9,7 +9,7 @@ class MainLayout extends React.Component { return (
-
+
{this.props.children}
diff --git a/client/src/core-components/button.js b/client/src/core-components/button.js index 755004f9..9f96a095 100644 --- a/client/src/core-components/button.js +++ b/client/src/core-components/button.js @@ -6,6 +6,9 @@ import classNames from 'classnames'; // CORE LIBS import callback from 'lib-core/callback'; +// CORE COMPONENTS +import Icon from 'core-components/icon'; + class Button extends React.Component { static contextTypes = { @@ -16,6 +19,7 @@ class Button extends React.Component { children: React.PropTypes.node, type: React.PropTypes.oneOf([ 'primary', + 'primary-icon', 'clean', 'link' ]), @@ -23,7 +27,8 @@ class Button extends React.Component { to: React.PropTypes. string.isRequired, params: React.PropTypes.object, query: React.PropTypes.query - }) + }), + iconName: React.PropTypes.string }; static defaultProps = { @@ -33,7 +38,7 @@ class Button extends React.Component { render() { return ( ); } diff --git a/client/src/core-components/button.scss b/client/src/core-components/button.scss index 974cf04e..34c58bea 100644 --- a/client/src/core-components/button.scss +++ b/client/src/core-components/button.scss @@ -2,7 +2,8 @@ .button { - &-primary { + &-primary, + &-primary-icon { background-color: $primary-red; border: solid transparent; border-radius: 4px; @@ -12,6 +13,11 @@ width: 239px; } + &-primary-icon { + width: initial; + height: initial; + } + &-clean { background: none; border: none; diff --git a/client/src/core-components/text-area.js b/client/src/core-components/text-area.js new file mode 100644 index 00000000..8f2f6e94 --- /dev/null +++ b/client/src/core-components/text-area.js @@ -0,0 +1,84 @@ +import React from 'react'; +import classNames from 'classnames'; +import _ from 'lodash'; + +import TextEditor from 'core-components/text-editor'; + +class TextArea extends React.Component { + + static contextTypes = { + loading: React.PropTypes.bool + }; + + static propTypes = { + value: React.PropTypes.string, + validation: React.PropTypes.string, + onChange: React.PropTypes.func, + required: React.PropTypes.bool, + error: React.PropTypes.string + }; + + constructor(props) { + super(props); + + this.state = { + editorState: EditorState.createEmpty() + }; + this.onChange = (editorState) => this.setState({editorState}); + } + + render() { + return ( + + ); + } + + renderError() { + let error = null; + + if (this.props.error){ + error = {this.props.error} ; + } + + return error; + } + + /*getEditorProps() { + let props = _.clone(this.props); + + props['aria-required'] = this.props.required; + props.className = 'text-area__input'; + props.ref = 'nativeTextArea'; + props.disabled = this.context.loading; + + delete props.required; + delete props.validation; + delete props.error; + delete props.password; + + return props; + }*/ + + getClass() { + let classes = { + 'text-area': true, + 'text-area_with-error': (this.props.error), + + [this.props.className]: (this.props.className) + }; + + return classNames(classes); + } + + focus() { + if (this.refs.nativeTextArea) { + this.refs.nativeTextArea.focus(); + } + } +} + +export default TextArea; \ No newline at end of file diff --git a/client/src/core-components/text-area.scss b/client/src/core-components/text-area.scss new file mode 100644 index 00000000..e51bea62 --- /dev/null +++ b/client/src/core-components/text-area.scss @@ -0,0 +1,42 @@ +@import "../scss/vars"; + +.text-area { + display: block; + + &__editor { + border: 1px solid $grey; + border-radius: 3px; + padding: 8px; + width: 100%; + + &:hover { + border-color: $medium-grey; + } + + &:focus { + outline: none; + border-color: $primary-blue; + } + } + + &__label { + color: $primary-black; + font-size: 15px; + display: block; + padding: 3px 0; + text-align: left; + } + + &_with-error { + .text-area__error { + color: $primary-red; + font-size: $font-size--sm; + display: block; + position: absolute; + } + .text-area__text { + border: 1px solid $primary-red; + } + } + +} \ No newline at end of file diff --git a/client/src/core-components/text-editor.js b/client/src/core-components/text-editor.js new file mode 100644 index 00000000..83f5f6c1 --- /dev/null +++ b/client/src/core-components/text-editor.js @@ -0,0 +1,94 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import classNames from 'classnames'; +import _ from 'lodash'; +import {Editor, EditorState, RichUtils} from 'draft-js'; +import Button from 'core-components/button'; + +class TextEditor extends React.Component { + + constructor(props) { + super(props); + + this.state = { + editorState: EditorState.createEmpty(), + focused: false + }; + } + + render() { + return ( +
+ {this.renderEditOptions()} +
+ +
+
+ ); + } + + renderEditOptions() { + const onBoldClick = (event) => { + event.preventDefault(); + this.onEditorChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD')); + }; + const onItalicsClick = (event) => { + event.preventDefault(); + this.onEditorChange(RichUtils.toggleInlineStyle(this.state.editorState, 'ITALICS')); + }; + const onUnderlineClick = (event) => { + event.preventDefault(); + this.onEditorChange(RichUtils.toggleInlineStyle(this.state.editorState, 'UNDERLINE')); + }; + + + return ( +
+
+ ) + } + + getClass() { + let classes = { + 'text-editor': true, + 'text-editor_focused': (this.state.focused), + + [this.props.className]: (this.props.className) + }; + + return classNames(classes); + } + + getEditorProps() { + return { + editorState: this.state.editorState, + ref: 'editor', + onChange: this.onEditorChange.bind(this), + onFocus: this.onEditorFocus.bind(this), + onBlur: this.onBlur.bind(this) + }; + } + + onEditorChange(editorState) { + this.setState({editorState}); + } + + onEditorFocus() { + this.setState({focused: true}); + } + + onBlur() { + this.setState({focused: false}); + } + + focus() { + if (this.refs.editor) { + this.refs.editor.focus(); + } + } +} + +export default TextEditor; \ No newline at end of file diff --git a/client/src/core-components/text-editor.scss b/client/src/core-components/text-editor.scss new file mode 100644 index 00000000..ce50e4bf --- /dev/null +++ b/client/src/core-components/text-editor.scss @@ -0,0 +1,33 @@ +@import "../scss/vars"; + +.text-editor { + + &__editor { + border: 1px solid $grey; + border-radius: 3px; + padding: 8px; + width: 100%; + height: 200px; + text-align: left; + overflow: auto; + + &:hover { + border-color: $medium-grey; + } + } + + &__options { + text-align: left; + margin-bottom: 5px; + + .button { + margin-right: 3px; + } + } + + &_focused { + .text-editor__editor { + border-color: $primary-blue; + } + } +} \ No newline at end of file