diff --git a/client/src/app-components/people-list.js b/client/src/app-components/people-list.js new file mode 100644 index 00000000..1fd18346 --- /dev/null +++ b/client/src/app-components/people-list.js @@ -0,0 +1,117 @@ +import React from 'react'; +import _ from 'lodash'; +import {StaggeredMotion, spring} from 'react-motion'; +import Menu from 'core-components/menu' + +import DateTransformer from 'lib-core/date-transformer'; +import i18n from 'lib-app/i18n'; + +class PeopleList extends React.Component { + static propTypes = { + list: React.PropTypes.arrayOf(React.PropTypes.shape({ + profilePic: React.PropTypes.string, + name: React.PropTypes.string, + assignedTickets: React.PropTypes.number, + closedTickets: React.PropTypes.number, + lastLogin: React.PropTypes.number + })), + pageSize: React.PropTypes.number, + page: React.PropTypes.number, + onPageSelect: React.PropTypes.func + }; + + static defaultProps = { + pageSize: 4, + list: [] + }; + + render() { + const pages = _.range(1, this.getPages() + 1).map((index) => {return {content: index};}); + + return ( +
+
+ + {this.renderList.bind(this)} + +
+
+ +
+
+ ); + } + + getDefaultStyles() { + return _.times(this.props.pageSize).map(() => {return {offset: -100, alpha: 0}}); + } + + getStyles(prevStyles) { + return prevStyles.map((_, i) => { + return i === 0 + ? {offset: spring(0), alpha: spring(1)} + : {offset: spring(prevStyles[i - 1].offset), alpha: spring(prevStyles[i - 1].alpha)} + }); + } + + renderList(styles) { + return ( +
+ {styles.map(this.renderAnimatedItem.bind(this))} +
+ ); + } + + renderAnimatedItem(style, index) { + return ( +
+ {this.renderItem(index + this.props.pageSize * (this.props.page - 1))} +
+ ); + } + + renderItem(index) { + if(index >= this.props.list.length) { + return null; + } + + const item = this.props.list[index]; + const minIndex = this.props.pageSize * (this.props.page - 1); + const maxIndex = this.props.pageSize * this.props.page; + + return (minIndex <= index && index < maxIndex) ? ( +
+
+ +
+
{item.name}
+
+ {i18n('ASSIGNED_TICKETS', {tickets: item.assignedTickets})} +
+
+ {i18n('CLOSED_TICKETS', {tickets: item.closedTickets})} +
+
+
{i18n('LAST_LOGIN')}
+
{DateTransformer.transformToString(item.lastLogin)}
+
+
+ ) : null; + } + + getRowsQuantity() { + if(this.props.page == this.getPages()){ + return this.props.list.length % this.props.pageSize; + } + else { + return this.props.pageSize; + } + } + + getPages() { + return Math.ceil(this.props.list.length / this.props.pageSize); + } + +} + +export default PeopleList; \ No newline at end of file diff --git a/client/src/app-components/people-list.scss b/client/src/app-components/people-list.scss new file mode 100644 index 00000000..8c52b03d --- /dev/null +++ b/client/src/app-components/people-list.scss @@ -0,0 +1,64 @@ +@import "../scss/vars"; + +.people-list { + max-width: 800px; + margin: 0 auto; + + &__list { + } + + &__item { + border: 2px solid $grey; + border-radius: 4px; + margin-bottom: 12px; + position: relative; + height: 105px; + padding-left: 60px; + font-size: $font-size--md; + + &-profile-pic-wrapper { + vertical-align: top; + background-color: $secondary-blue; + color: white; + border-radius: 5px; + width: 60px; + height: 60px; + top: 20px; + left: 20px; + + overflow: hidden; + position: absolute; + border: 2px solid $light-grey; + } + + &-profile-pic { + position: absolute; + height: 100%; + left: 50%; + transform: translate(-50%, 0) + } + + &-block { + padding: 30px 0; + width: 25%; + display: inline-block; + vertical-align: middle; + } + + &-assigned-tickets { + + } + + &-closed-tickets { + + } + + &-last-login { + + } + } + + &__pagination { + + } +} \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.js b/client/src/app/admin/panel/staff/admin-panel-staff-members.js index f869fc8b..2c47a6b3 100644 --- a/client/src/app/admin/panel/staff/admin-panel-staff-members.js +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -1,14 +1,92 @@ import React from 'react'; +import _ from 'lodash'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; +import SessionStore from 'lib-app/session-store'; +import PeopleList from 'app-components/people-list'; + +import Header from 'core-components/header'; +import DropDown from 'core-components/drop-down'; +import Button from 'core-components/button'; +import Icon from 'core-components/icon'; +import Loading from 'core-components/loading'; class AdminPanelStaffMembers extends React.Component { + state = { + selectedDepartment: 0, + staffList: [], + loading: true, + page: 1 + }; + + componentDidMount() { + API.call({ + path: '/staff/get-all', + data: {} + }).then(this.onStaffRetrieved.bind(this)); + } + render() { return ( -
- /admin/panel/staff/staff-members +
+
+
+ + +
+ {(this.state.loading) ? : this.setState({page: index+1})} />}
); } + + getDepartmentDropdownProps() { + return { + items: this.getDepartments(), + onChange: (event) => { + let departments = SessionStore.getDepartments(); + this.setState({ + selectedDepartment: event.index && departments[event.index - 1].id, + page: 1 + }); + }, + size: 'medium' + }; + } + + getStaffList() { + if(!this.state.selectedDepartment) { + return this.state.staffList; + } + + return _.filter(this.state.staffList, (o) => { + return _.findIndex(o.departments, {id: this.state.selectedDepartment}) !== -1; + }); + } + + getDepartments() { + let departments = SessionStore.getDepartments().map((department) => { + return {content: department.name}; + }); + + departments.unshift({ + content: i18n('ALL_DEPARTMENTS') + }); + + return departments; + } + + onStaffRetrieved(result) { + if(result.status == 'success'){ + this.setState({ + loading: false, + staffList: result.data + }); + } + } } export default AdminPanelStaffMembers; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/admin-panel-staff-members.scss b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss new file mode 100644 index 00000000..d31be626 --- /dev/null +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.scss @@ -0,0 +1,17 @@ +@import "../../../../scss/vars"; + +.admin-panel-staff-members { + + &__wrapper { + height: 60px; + } + + &__dropdown { + float: left; + } + + &__button { + float: right; + margin-top: -5px; + } +} \ No newline at end of file diff --git a/client/src/data/fixtures/article-fixtures.js b/client/src/data/fixtures/article-fixtures.js index ea394582..1181ffe9 100644 --- a/client/src/data/fixtures/article-fixtures.js +++ b/client/src/data/fixtures/article-fixtures.js @@ -13,35 +13,35 @@ module.exports = [ iconColor: '#82CA9C', articles: [ { - id: 1, + id: '1', title: 'Mannaging apps for your account', content: 'Curabitur sed dignissim turpis, sed lacinia urna. Vestibulum semper suscipit interdum. Proin sed sem gravida massa tristique rhoncus auctor eu diam. Donec fringilla in ex non dignissim. Praesent sed ultricies eros. Nullam vel augue eget libero volutpat sodales sit amet et orci.', lastEdited: 20160516, position: 1 }, { - id: 2, + id: '2', title: 'How to assign new task and files', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150429, position: 2 }, { - id: 3, + id: '3', title: 'Updating your profile picture', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150429, position: 3 }, { - id: 4, + id: '4', title: 'Deleting your account', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150929, position: 4 }, { - id: 5, + id: '5', title: 'Upload files to your cloud drive', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20131229, @@ -56,35 +56,35 @@ module.exports = [ iconColor: 'red', articles: [ { - id: 1, + id: '1', title: 'Mannaging apps for your account', content: 'Curabitur sed dignissim turpis, sed lacinia urna. Vestibulum semper suscipit interdum. Proin sed sem gravida massa tristique rhoncus auctor eu diam. Donec fringilla in ex non dignissim. Praesent sed ultricies eros. Nullam vel augue eget libero volutpat sodales sit amet et orci.', lastEdited: 20160516, position: 1 }, { - id: 2, + id: '2', title: 'How to assign new task and files', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150429, position: 2 }, { - id: 3, + id: '3', title: 'Updating your profile picture', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150429, position: 3 }, { - id: 4, + id: '4', title: 'Deleting your account', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20150929, position: 4 }, { - id: 5, + id: '5', title: 'Upload files to your cloud drive', content: 'Aliquam aliquet mi nulla. Nam vel orci diam. Suspendisse euismod orci efficitur nulla mattis eleifend vitae quis neque. Etiam orci dolor, dignissim quis convallis quis, rhoncus eu tellus. Phasellus aliquam ut enim id ultrices. Nunc dolor arcu, viverra vel ullamcorper nec, dignissim a lectus. Praesent fringilla, neque nec suscipit placerat, augue elit suscipit velit, in feugiat leo justo id tortor.', lastEdited: 20131229, diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index 97d3fe28..73bbd707 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -578,5 +578,57 @@ module.exports = [ } } } + }, + { + path: '/staff/get-all', + time: 100, + response: function() { + return { + status: 'success', + data: [ + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emilia Clarke', + departments: [{id: 2, name: 'Technical issues'}], + assignedTickets: 4, + closedTickets: 21, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Yulian A GUI Yermo', + departments: [{id: 2, name: 'Technical issues'}, {id: 1, name: 'Sales Support'}], + assignedTickets: 9, + closedTickets: 0, + lastLogin: 20161212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Miltona Costa', + departments: [{id: 1, name: 'Sales Support'}], + assignedTickets: -1, + closedTickets: -1, + lastLogin: 20160212 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Emiliasnikova Rusachestkvuy', + departments: [{id: 1, name: 'Sales Support'}, {id: 3, name: 'System and Administration'}], + assignedTickets: 100, + closedTickets: 21, + lastLogin: 20130101 + }, + { + profilePic: 'http://www.opensupports.com/profilepic.jpg', + name: 'Laurita Morrechaga Rusachestkvuy', + departments: [{id: 3, name: 'System and Administration'}], + assignedTickets: 1, + closedTickets: 1, + lastLogin: 2012050 + } + ] + }; + } + } ]; \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index e60a8f4e..f608dcfa 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -94,6 +94,11 @@ export default { 'EDIT': 'Edit', 'NO_RESULTS': 'No results', 'DELETE_AND_BAN': 'Delete and ban', + 'ASSIGNED_TICKETS': '{tickets} assigned tickets', + 'CLOSED_TICKETS': '{tickets} closed tickets', + 'LAST_LOGIN': 'Last login', + 'STAFF_MEMBERS': 'Staff members', + 'ADD_NEW_STAFF': 'Add new staff', //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', @@ -116,6 +121,7 @@ export default { 'ADD_ARTICLE_DESCRIPTION': 'Here you can add an article that will be available for every user. It will be added inside the category {category}.', 'LIST_ARTICLES_DESCRIPTION': 'This is a list of articles that includes information about our services.', 'ADD_TOPIC_DESCRIPTION': 'Here you can add a topic that works as a category for articles.', + 'STAFF_MEMBERS_DESCRIPTION': 'Here you can see who are your staff members.', //ERRORS 'EMAIL_OR_PASSWORD': 'Email or password invalid',