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 8661164e..9944e66f 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
@@ -1,14 +1,162 @@
import React from 'react';
+import i18n from 'lib-app/i18n';
+import API from 'lib-app/api-call';
+import DateTransformer from 'lib-core/date-transformer';
+
+import Header from 'core-components/header';
+import Table from 'core-components/table';
+import SearchBox from 'core-components/search-box';
+import Button from 'core-components/button';
+
class AdminPanelListUsers extends React.Component {
+ state = {
+ loading: true,
+ users: [],
+ orderBy: 'id',
+ desc: true,
+ page: 1,
+ pages: 1
+ };
+
+ componentDidMount() {
+ this.retrieveUsers({
+ page: 1,
+ orderBy: 'id',
+ desc: true,
+ search: ''
+ });
+ }
+
render() {
return (
-
- /admin/panel/users/list-users
+
);
}
+
+ getTableProps() {
+ return {
+ className: 'admin-panel-list-users__table',
+ loading: this.state.loading,
+ headers: this.getTableHeaders(),
+ rows: this.state.users.map(this.getUserRow.bind(this)),
+ pageSize: 10,
+ page: this.state.page,
+ pages: this.state.pages,
+ onPageChange: this.onPageChange.bind(this)
+ };
+ }
+
+ getTableHeaders() {
+ return [
+ {
+ key: 'name',
+ value: i18n('NAME'),
+ className: 'admin-panel-list-users__table-name col-md-3'
+ },
+ {
+ key: 'email',
+ value: i18n('EMAIL'),
+ className: 'admin-panel-list-users__table-email col-md-5'
+ },
+ {
+ key: 'tickets',
+ value: i18n('TICKETS'),
+ className: 'admin-panel-list-users__table-tickets col-md-2',
+ order: true,
+ onOrderUp: this.orderByTickets.bind(this, false),
+ onOrderDown: this.orderByTickets.bind(this, true)
+ },
+ {
+ key: 'signupDate',
+ value: i18n('SIGNUP_DATE'),
+ className: 'admin-panel-list-users__table-date col-md-2',
+ order: true,
+ onOrderUp: this.orderById.bind(this, false),
+ onOrderDown: this.orderById.bind(this, true)
+ }
+ ];
+ }
+
+ getUserRow(user) {
+ return {
+ name: (
+
+ ),
+ email: user.email,
+ tickets: (
+
+ {user.tickets}
+
+ ),
+ signupDate: DateTransformer.transformToString(user.signupDate)
+ };
+ }
+
+ onSearch(query) {
+ this.retrieveUsers({
+ page: 1,
+ orderBy: 'id',
+ desc: true,
+ search: query
+ });
+ }
+
+ onPageChange(event) {
+ this.retrieveUsers({
+ page: event.target.value,
+ orderBy: this.state.orderBy,
+ desc: this.state.desc,
+ search: this.state.search
+ });
+ }
+
+ orderByTickets(desc) {
+ this.retrieveUsers({
+ page: 1,
+ orderBy: 'tickets',
+ desc: desc,
+ search: this.state.search
+ });
+ }
+
+ orderById(desc) {
+ this.retrieveUsers({
+ page: 1,
+ orderBy: 'id',
+ desc: desc,
+ search: this.state.search
+ });
+ }
+
+ retrieveUsers(data) {
+ this.setState({
+ loading: true
+ });
+
+ API.call({
+ path: '/user/get-users',
+ data: data
+ }).then(this.onUsersRetrieved.bind(this));
+ }
+
+ onUsersRetrieved(result) {
+ this.setState({
+ page: result.data.page,
+ pages: result.data.pages,
+ users: result.data.users,
+ orderBy: result.data.orderBy,
+ desc: result.data.desc,
+ loading: false
+ });
+ }
}
export default AdminPanelListUsers;
\ No newline at end of file
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
new file mode 100644
index 00000000..7b76f23c
--- /dev/null
+++ b/client/src/app/admin/panel/users/admin-panel-list-users.scss
@@ -0,0 +1,24 @@
+@import '../../../../scss/vars';
+
+.admin-panel-list-users {
+
+ &__search-box {
+ margin: 20px;
+ }
+
+ &__table {
+ text-align: left;
+ }
+
+ &__name-link {
+ color: $secondary-blue;
+ }
+
+ &__tickets-number {
+ background-color: white;
+ border-radius: 10px;
+ width: 70px;
+ display: inline-block;
+ text-align: center;
+ }
+}
\ No newline at end of file
diff --git a/client/src/core-components/search-box.js b/client/src/core-components/search-box.js
index 13489a75..d7bb3a99 100644
--- a/client/src/core-components/search-box.js
+++ b/client/src/core-components/search-box.js
@@ -1,4 +1,5 @@
import React from 'react';
+import classNames from 'classnames';
import Input from 'core-components/input';
import Icon from 'core-components/icon';
@@ -7,7 +8,8 @@ import keyCode from 'keycode';
class SearchBox extends React.Component {
static propTypes = {
- onSearch: React.PropTypes.func
+ onSearch: React.PropTypes.func,
+ placeholder: React.PropTypes.string
};
state = {
@@ -16,8 +18,8 @@ class SearchBox extends React.Component {
render() {
return (
-
-
+
+
@@ -25,6 +27,16 @@ class SearchBox extends React.Component {
);
}
+ getClass() {
+ let classes = {
+ 'search-box': true
+ };
+
+ classes[this.props.className] = (this.props.className);
+
+ return classNames(classes);
+ }
+
onChange(event) {
this.setState({
value: event.target.value
diff --git a/client/src/core-components/table.js b/client/src/core-components/table.js
index 58494e05..2d0fc757 100644
--- a/client/src/core-components/table.js
+++ b/client/src/core-components/table.js
@@ -3,6 +3,7 @@ import _ from 'lodash';
import classNames from 'classnames';
import Menu from 'core-components/menu';
+import Icon from 'core-components/icon';
import Loading from 'core-components/loading';
class Table extends React.Component {
@@ -32,7 +33,7 @@ class Table extends React.Component {
render() {
return (
-
+
@@ -56,7 +57,23 @@ class Table extends React.Component {
};
return (
- {header.value} |
+
+ {header.value}
+ {(header.order) ? this.renderHeaderArrows(header.onOrderUp, header.onOrderDown) : null}
+ |
+ );
+ }
+
+ renderHeaderArrows(onArrowUp, onArrowDown) {
+ return (
+
+
+
+
+
+
+
+
);
}
@@ -92,7 +109,7 @@ class Table extends React.Component {
const items = _.range(1, this.getPages()).map((index) => {return {content: index};});
return (
-
+
);
}
@@ -104,6 +121,16 @@ class Table extends React.Component {
)
}
+ getClass() {
+ let classes = {
+ 'table__wrapper': true
+ };
+
+ classes[this.props.className] = (this.props.className);
+
+ return classNames(classes);
+ }
+
onNavigationItemClick(index) {
this.setState({
page: index + 1
diff --git a/client/src/core-components/table.scss b/client/src/core-components/table.scss
index fe29d346..079b941d 100644
--- a/client/src/core-components/table.scss
+++ b/client/src/core-components/table.scss
@@ -7,6 +7,18 @@
background-color: $primary-blue;
color: white;
font-weight: normal;
+
+ &-arrow-up {
+ cursor: pointer;
+ font-size: $font-size--xs;
+ margin-left: 10px;
+ }
+
+ &-arrow-down {
+ cursor: pointer;
+ font-size: $font-size--xs;
+ margin-left: 3px;
+ }
}
&__header-column {
diff --git a/client/src/data/fixtures/user-fixtures.js b/client/src/data/fixtures/user-fixtures.js
index 1177e941..dde8365e 100644
--- a/client/src/data/fixtures/user-fixtures.js
+++ b/client/src/data/fixtures/user-fixtures.js
@@ -124,6 +124,94 @@ module.exports = [
};
}
},
+ {
+ path: '/user/get-users',
+ time: 100,
+ response: function (data) {
+ return {
+ status: 'success',
+ data: {
+ page: data.page,
+ pages: 10,
+ orderBy: 'date',
+ desc: true,
+ search: '',
+ users: [
+ {
+ id: 101,
+ name: 'Haskell Curry',
+ email: 'haskell@currycurrylady.com',
+ tickets: 5,
+ signupDate: 20160415
+ },
+ {
+ id: 97,
+ name: 'Alan Turing',
+ email: 'turing@currycurrylady.com',
+ tickets: 1,
+ signupDate: 20160401
+ },
+ {
+ id: 89,
+ name: 'David Hilbert',
+ email: 'hilbert@currycurrylady.com',
+ tickets: 2,
+ signupDate: 20160208
+ },
+ {
+ id: 83,
+ name: 'Kurt Gödel',
+ email: 'kurt@currycurrylady.com',
+ tickets: 10,
+ signupDate: 20160110
+ },
+ {
+ id: 79,
+ name: 'Mojzesz Presburger',
+ email: 'presburger@currycurrylady.com',
+ tickets: 6,
+ signupDate: 20150415
+ },
+ {
+ id: 73,
+ name: 'Haskell Curry',
+ email: 'haskell@currycurrylady.com',
+ tickets: 5,
+ signupDate: 20160415
+ },
+ {
+ id: 71,
+ name: 'Alan Turing',
+ email: 'turing@currycurrylady.com',
+ tickets: 1,
+ signupDate: 20160401
+ },
+ {
+ id: 67,
+ name: 'David Hilbert',
+ email: 'hilbert@currycurrylady.com',
+ tickets: 2,
+ signupDate: 20160208
+ },
+ {
+ id: 61,
+ name: 'Kurt Gödel',
+ email: 'kurt@currycurrylady.com',
+ tickets: 10,
+ signupDate: 20160110
+ },
+ {
+ id: 59,
+ name: 'Mojzesz Presburger',
+ email: 'presburger@currycurrylady.com',
+ tickets: 6,
+ signupDate: 20150415
+ }
+ ]
+ }
+ };
+ }
+ },
{
path: '/user/get',
time: 100,
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js
index e964ceec..82f4e0a4 100644
--- a/client/src/data/languages/en.js
+++ b/client/src/data/languages/en.js
@@ -75,6 +75,9 @@ export default {
'WARNING': 'Warning',
'INFO': 'Information',
'ALL_DEPARTMENTS': 'All Departments',
+ 'NAME': 'Name',
+ 'SIGNUP_DATE': 'Sign up date',
+ 'SEARCH_USERS': 'Search users...',
//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.',
@@ -88,6 +91,7 @@ export default {
'NEW_TICKETS_DESCRIPTION': 'Here you can view all the new tickets that are not assigned by anyone.',
'ALL_TICKETS_DESCRIPTION': 'Here you can view the tickets of the departments you are assigned.',
'TICKET_VIEW_DESCRIPTION': 'This ticket has been sent by a customer. Here you can respond or assign the ticket',
+ 'LIST_USERS_DESCRIPTION': 'This is the list of users that are registered in this platform. You can search for someone in particular, delete it or ban it.',
//ERRORS
'EMAIL_OR_PASSWORD': 'Email or password invalid',
diff --git a/client/src/lib-core/date-transformer.js b/client/src/lib-core/date-transformer.js
index 9c036994..76719096 100644
--- a/client/src/lib-core/date-transformer.js
+++ b/client/src/lib-core/date-transformer.js
@@ -2,6 +2,7 @@ let month = ["", "Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
export default {
transformToString (date) {
+ date += ''; //Transform to string
let y = date.substring(0, 4);
let m = date.substring(4, 6);
let d = date.substring(6, 8);