Merged in dashboard-view-ticket (pull request #42)
Dashboard view ticket
This commit is contained in:
commit
e0ae9d113e
|
@ -65,7 +65,7 @@
|
|||
"react": "^15.0.1",
|
||||
"react-document-title": "^1.0.2",
|
||||
"react-dom": "^15.0.1",
|
||||
"react-google-recaptcha": "^0.5.4",
|
||||
"react-google-recaptcha": "^0.5.2",
|
||||
"react-motion": "^0.3.0",
|
||||
"react-redux": "^4.4.5",
|
||||
"react-router": "^2.4.0",
|
||||
|
|
|
@ -1,14 +1,30 @@
|
|||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import TicketViewer from 'app/main/dashboard/dashboard-ticket/ticket-viewer';
|
||||
|
||||
class DashboardTicketPage extends React.Component {
|
||||
|
||||
static propTypes = {
|
||||
tickets: React.PropTypes.array
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
DASHBOARD TICKET PAGE
|
||||
<div className="dashboard-ticket-page">
|
||||
<TicketViewer ticket={this.getTicketData()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
getTicketData() {
|
||||
return _.find(this.props.tickets, {ticketNumber: this.props.params.ticketNumber});
|
||||
}
|
||||
}
|
||||
|
||||
export default DashboardTicketPage;
|
||||
export default connect((store) => {
|
||||
return {
|
||||
tickets: store.session.userTickets
|
||||
};
|
||||
})(DashboardTicketPage);
|
|
@ -0,0 +1,3 @@
|
|||
.dashboard-ticket-page {
|
||||
padding: 0 10px;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import Icon from 'core-components/icon';
|
||||
|
||||
class TicketAction extends React.Component {
|
||||
static propTypes = {
|
||||
type: React.PropTypes.oneOf(['comment', 'assign']),
|
||||
config: React.PropTypes.object
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
type: 'comment'
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className={this.getClass()}>
|
||||
<span className="ticket-action__connector" />
|
||||
<div className="col-md-1">
|
||||
<div className="ticket-action__icon">
|
||||
<Icon name="comment-o" size="2x" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-md-11">
|
||||
{this.renderActionDescription()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderActionDescription() {
|
||||
const renders = {
|
||||
'comment': this.renderComment.bind(this),
|
||||
'assign': this.renderAssignment.bind(this)
|
||||
};
|
||||
|
||||
return renders[this.props.type]();
|
||||
}
|
||||
|
||||
renderComment() {
|
||||
const {config} = this.props;
|
||||
|
||||
return (
|
||||
<div className="ticket-action__comment">
|
||||
<span className="ticket-action__comment-pointer" />
|
||||
<div className="ticket-action__comment-author">
|
||||
<span className="ticket-action__comment-author-name">{config.author.name}</span>
|
||||
<span className="ticket-action__comment-author-type">({i18n((config.author.staff) ? 'STAFF' : 'CUSTOMER')})</span>
|
||||
</div>
|
||||
<div className="ticket-action__comment-date">{config.date}</div>
|
||||
<div className="ticket-action__comment-content">{config.content}</div>
|
||||
{this.renderFileRow(config.file)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderAssignment() {
|
||||
// TODO: Add actions architecture instead of just comments
|
||||
|
||||
return (
|
||||
<div className="ticket-action__assignment">
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderFileRow(file) {
|
||||
let node = null;
|
||||
|
||||
if (file) {
|
||||
node = <span> {this.getFileLink(file)} <Icon name="paperclip" /> </span>;
|
||||
} else {
|
||||
node = i18n('NO_ATTACHMENT');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ticket-viewer__file">
|
||||
{node}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
getClass() {
|
||||
const {config} = this.props;
|
||||
|
||||
let classes = {
|
||||
'row': true,
|
||||
'ticket-action': true,
|
||||
'ticket-action_staff': config.author && config.author.staff
|
||||
};
|
||||
|
||||
return classNames(classes);
|
||||
}
|
||||
|
||||
getFileLink(filePath = '') {
|
||||
const fileName = filePath.replace(/^.*[\\\/]/, '');
|
||||
|
||||
return (
|
||||
<a href={filePath} target="_blank">{fileName}</a>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TicketAction;
|
|
@ -0,0 +1,83 @@
|
|||
@import "../../../../scss/vars";
|
||||
|
||||
.ticket-action {
|
||||
margin-top: 20px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
|
||||
&__connector {
|
||||
position: absolute;
|
||||
background-color: $light-grey;
|
||||
width: 3px;
|
||||
height: 100%;
|
||||
top: 38px;
|
||||
left: 33px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&__icon {
|
||||
vertical-align: top;
|
||||
background-color: $secondary-blue;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
padding-left: 8px;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
&__comment {
|
||||
position: relative;
|
||||
|
||||
&-pointer {
|
||||
right: 100%;
|
||||
border: solid transparent;
|
||||
position: absolute;
|
||||
border-right-color: $light-grey;
|
||||
border-width: 13px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
&-author {
|
||||
text-align: left;
|
||||
float: left;
|
||||
position: relative;
|
||||
padding: 12px;
|
||||
color: $primary-black;
|
||||
|
||||
&-type {
|
||||
font-size: 10px;
|
||||
padding-left: 10px;
|
||||
color: $secondary-blue;
|
||||
font-variant: small-caps;
|
||||
}
|
||||
}
|
||||
|
||||
&-date {
|
||||
text-align: right;
|
||||
border: 2px solid $light-grey;
|
||||
border-bottom: none;
|
||||
padding: 12px;
|
||||
background-color: $light-grey;
|
||||
|
||||
}
|
||||
|
||||
&-content {
|
||||
background-color: white;
|
||||
border: 2px solid $very-light-grey;
|
||||
border-top: none;
|
||||
padding: 20px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
&_staff {
|
||||
.ticket-action__icon {
|
||||
background-color: $primary-blue;
|
||||
}
|
||||
|
||||
.ticket-action__comment-author-type {
|
||||
color: $primary-blue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import React from 'react';
|
||||
|
||||
import i18n from 'lib-app/i18n';
|
||||
import TicketAction from 'app/main/dashboard/dashboard-ticket/ticket-action';
|
||||
import Form from 'core-components/form';
|
||||
import FormField from 'core-components/form-field';
|
||||
import SubmitButton from 'core-components/submit-button';
|
||||
|
||||
class TicketViewer extends React.Component {
|
||||
static propTypes = {
|
||||
ticket: React.PropTypes.object
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
ticket: {
|
||||
author: {},
|
||||
department: {},
|
||||
comments: []
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="ticket-viewer">
|
||||
<div className="ticket-viewer__header row">
|
||||
<span className="ticket-viewer__number">#{this.props.ticket.ticketNumber}</span>
|
||||
<span className="ticket-viewer__title">{this.props.ticket.title}</span>
|
||||
</div>
|
||||
<div className="ticket-viewer__info-row-header row">
|
||||
<div className="ticket-viewer__department col-md-4">{i18n('DEPARTMENT')}</div>
|
||||
<div className="ticket-viewer__author col-md-4">{i18n('AUTHOR')}</div>
|
||||
<div className="ticket-viewer__date col-md-4">{i18n('DATE')}</div>
|
||||
</div>
|
||||
<div className="ticket-viewer__info-row-values row">
|
||||
<div className="ticket-viewer__department col-md-4">{this.props.ticket.department.name}</div>
|
||||
<div className="ticket-viewer__author col-md-4">{this.props.ticket.author.name}</div>
|
||||
<div className="ticket-viewer__date col-md-4">{this.props.ticket.date}</div>
|
||||
</div>
|
||||
<div className="ticket-viewer__content">
|
||||
<TicketAction type="comment" config={this.props.ticket} />
|
||||
</div>
|
||||
<div className="ticket-viewer__comments">
|
||||
{this.props.ticket.comments.map(this.renderComment.bind(this))}
|
||||
</div>
|
||||
<div className="ticket-viewer__response">
|
||||
<div className="ticket-viewer__response-title row">{i18n('RESPOND')}</div>
|
||||
<div className="ticket-viewer__response-field row">
|
||||
<Form>
|
||||
<FormField name="content" validation="TEXT_AREA" required field="textarea" />
|
||||
<SubmitButton>{i18n('RESPOND_TICKET')}</SubmitButton>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderComment(comment, index) {
|
||||
return (
|
||||
<TicketAction type="comment" config={comment} key={index} />
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TicketViewer;
|
|
@ -0,0 +1,79 @@
|
|||
@import "../../../../scss/vars";
|
||||
|
||||
.ticket-viewer {
|
||||
&__header {
|
||||
background-color: $primary-blue;
|
||||
border-top-right-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
&__number {
|
||||
color: white;
|
||||
margin-right: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&__title {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&__info-row-header {
|
||||
background-color: $light-grey;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__info-row-values {
|
||||
background-color: $light-grey;
|
||||
color: $secondary-blue;
|
||||
}
|
||||
|
||||
&__date {
|
||||
|
||||
}
|
||||
|
||||
&__author {
|
||||
|
||||
}
|
||||
|
||||
&__department {
|
||||
|
||||
}
|
||||
|
||||
&__content {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&__file {
|
||||
background-color: $very-light-grey;
|
||||
text-align: right;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&__comments {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__response {
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
|
||||
&-title {
|
||||
background-color: $primary-blue;
|
||||
text-align: left;
|
||||
padding: 5px;
|
||||
color: white;
|
||||
border-top-right-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
|
||||
&-field {
|
||||
background-color: $very-light-grey;
|
||||
padding: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
.text-editor {
|
||||
|
||||
&__editor {
|
||||
background-color: white;
|
||||
border: 1px solid $grey;
|
||||
border-radius: 3px;
|
||||
padding: 8px;
|
||||
|
|
|
@ -22,6 +22,14 @@ export default {
|
|||
'TICKETS_DESCRIPTION': 'A random text about tickets',
|
||||
'ARTICLES_DESCRIPTION': 'A random text about articles',
|
||||
'ACCOUNT_DESCRIPTION': 'A random text about account',
|
||||
'DEPARTMENT': 'Department',
|
||||
'AUTHOR': 'Author',
|
||||
'DATE': 'Date',
|
||||
'RESPOND': 'Respond',
|
||||
'RESPOND_TICKET': 'Respond Ticket',
|
||||
'NO_ATTACHMENT': 'No file attachment',
|
||||
'STAFF': 'Staff',
|
||||
'CUSTOMER': 'Customer',
|
||||
|
||||
//ERRORS
|
||||
'EMAIL_NOT_EXIST': 'Email does not exist',
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<title>App Name</title>
|
||||
<title>OS4</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
</head>
|
||||
|
|
|
@ -6,6 +6,8 @@ $primary-blue: #414A59;
|
|||
$secondary-blue: #20B8c5;
|
||||
|
||||
$primary-green: #82CA9C;
|
||||
|
||||
$very-light-grey: #F7F7F7;
|
||||
$light-grey: #EEEEEE;
|
||||
$grey: #E7E7E7;
|
||||
$medium-grey: #D9D9D9;
|
||||
|
|
Loading…
Reference in New Issue