From 528814be0769cc9cf1f4746a304b64140d7411bd Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 24 Sep 2016 16:35:26 -0300 Subject: [PATCH 1/7] Ivan - STAFF LOGIN - Add staff login fixtures [skip ci] --- client/src/data/fixtures/staff-fixtures.js | 22 ++++++++++++++++++++++ client/src/data/fixtures/user-fixtures.js | 1 + client/src/lib-app/fixtures-loader.js | 1 + 3 files changed, 24 insertions(+) create mode 100644 client/src/data/fixtures/staff-fixtures.js diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js new file mode 100644 index 00000000..c4f0a578 --- /dev/null +++ b/client/src/data/fixtures/staff-fixtures.js @@ -0,0 +1,22 @@ +module.exports = [ + { + path: '/staff/get', + time: 100, + response: function () { + return { + status: 'success', + data: { + name: 'Emilia Clarke', + email: 'staff@opensupports.com', + profilePic: 'http://i65.tinypic.com/9bep95.jpg', + level: 1, + departments: [ + {id: 1, name: 'Sales Support'}, + {id: 2, name: 'Technical Issues'}, + {id: 3, name: 'System and Administration'} + ] + } + }; + } + } +]; \ No newline at end of file diff --git a/client/src/data/fixtures/user-fixtures.js b/client/src/data/fixtures/user-fixtures.js index 833678fa..dd72ae59 100644 --- a/client/src/data/fixtures/user-fixtures.js +++ b/client/src/data/fixtures/user-fixtures.js @@ -9,6 +9,7 @@ module.exports = [ response = { status: 'success', data: { + 'staff': data.staff, 'userId': 12, 'token': 'cc6b4921e6733d6aafe284ec0d7be57e', 'rememberToken': (data.remember) ? 'aa41efe0a1b3eeb9bf303e4561ff8392' : null, diff --git a/client/src/lib-app/fixtures-loader.js b/client/src/lib-app/fixtures-loader.js index fcf645a2..896ff338 100644 --- a/client/src/lib-app/fixtures-loader.js +++ b/client/src/lib-app/fixtures-loader.js @@ -17,6 +17,7 @@ let fixtures = (function () { // FIXTURES fixtures.add(require('data/fixtures/user-fixtures')); +fixtures.add(require('data/fixtures/staff-fixtures')); fixtures.add(require('data/fixtures/ticket-fixtures')); fixtures.add(require('data/fixtures/system-fixtures')); From e3650f146f3b3c38081b143e5dbbc029dd799f60 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 24 Sep 2016 17:53:34 -0300 Subject: [PATCH 2/7] Ivan - STAFF LOGIN - Add all routes for admin panel [skip ci] --- client/src/app/Routes.js | 77 +++++++++++++++++-- .../src/app/admin/panel/admin-panel-layout.js | 20 +++++ ...min-panel.scss => admin-panel-layout.scss} | 0 client/src/app/admin/panel/admin-panel.js | 13 ---- .../articles/admin-panel-list-articles.js | 14 ++++ .../articles/admin-panel-view-article.js | 14 ++++ .../panel/dashboard/admin-panel-activity.js | 14 ++++ .../panel/dashboard/admin-panel-my-account.js | 14 ++++ .../panel/dashboard/admin-panel-stats.js | 14 ++++ .../settings/admin-panel-custom-fields.js | 14 ++++ .../settings/admin-panel-email-templates.js | 14 ++++ .../admin-panel-system-preferences.js | 14 ++++ .../panel/settings/admin-panel-user-system.js | 14 ++++ .../panel/staff/admin-panel-departments.js | 14 ++++ .../panel/staff/admin-panel-staff-members.js | 14 ++++ .../panel/staff/admin-panel-view-staff.js | 14 ++++ .../panel/tickets/admin-panel-all-tickets.js | 14 ++++ .../tickets/admin-panel-custom-responses.js | 14 ++++ .../panel/tickets/admin-panel-my-tickets.js | 14 ++++ .../panel/tickets/admin-panel-new-tickets.js | 14 ++++ .../panel/tickets/admin-panel-view-ticket.js | 14 ++++ .../panel/users/admin-panel-ban-users.js | 14 ++++ .../panel/users/admin-panel-list-users.js | 14 ++++ .../panel/users/admin-panel-view-user.js | 14 ++++ 24 files changed, 372 insertions(+), 18 deletions(-) create mode 100644 client/src/app/admin/panel/admin-panel-layout.js rename client/src/app/admin/panel/{admin-panel.scss => admin-panel-layout.scss} (100%) delete mode 100644 client/src/app/admin/panel/admin-panel.js create mode 100644 client/src/app/admin/panel/articles/admin-panel-list-articles.js create mode 100644 client/src/app/admin/panel/articles/admin-panel-view-article.js create mode 100644 client/src/app/admin/panel/dashboard/admin-panel-activity.js create mode 100644 client/src/app/admin/panel/dashboard/admin-panel-my-account.js create mode 100644 client/src/app/admin/panel/dashboard/admin-panel-stats.js create mode 100644 client/src/app/admin/panel/settings/admin-panel-custom-fields.js create mode 100644 client/src/app/admin/panel/settings/admin-panel-email-templates.js create mode 100644 client/src/app/admin/panel/settings/admin-panel-system-preferences.js create mode 100644 client/src/app/admin/panel/settings/admin-panel-user-system.js create mode 100644 client/src/app/admin/panel/staff/admin-panel-departments.js create mode 100644 client/src/app/admin/panel/staff/admin-panel-staff-members.js create mode 100644 client/src/app/admin/panel/staff/admin-panel-view-staff.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-all-tickets.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-custom-responses.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-my-tickets.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-new-tickets.js create mode 100644 client/src/app/admin/panel/tickets/admin-panel-view-ticket.js create mode 100644 client/src/app/admin/panel/users/admin-panel-ban-users.js create mode 100644 client/src/app/admin/panel/users/admin-panel-list-users.js create mode 100644 client/src/app/admin/panel/users/admin-panel-view-user.js diff --git a/client/src/app/Routes.js b/client/src/app/Routes.js index 389bf918..0470cd27 100644 --- a/client/src/app/Routes.js +++ b/client/src/app/Routes.js @@ -1,5 +1,5 @@ import React from 'react'; -import {Router, Route, IndexRoute, browserHistory} from 'react-router'; +import {Router, Route, IndexRoute, IndexRedirect, browserHistory} from 'react-router'; import { syncHistoryWithStore } from 'react-router-redux'; import store from 'app/store'; @@ -20,8 +20,35 @@ import DashboardEditProfilePage from 'app/main/dashboard/dashboard-edit-profile/ import DashboardArticlePage from 'app/main/dashboard/dashboard-article/dashboard-article-page'; import DashboardTicketPage from 'app/main/dashboard/dashboard-ticket/dashboard-ticket-page'; +// ADMIN PANEL import AdminLoginPage from 'app/admin/admin-login-page'; -import AdminPanel from 'app/admin/panel/admin-panel'; +import AdminPanelLayout from 'app/admin/panel/admin-panel-layout'; + +import AdminPanelStats from 'app/admin/panel/dashboard/admin-panel-stats'; +import AdminPanelActivity from 'app/admin/panel/dashboard/admin-panel-activity'; +import AdminPanelMyAccount from 'app/admin/panel/dashboard/admin-panel-my-account'; + +import AdminPanelMyTickets from 'app/admin/panel/tickets/admin-panel-my-tickets'; +import AdminPanelNewTickets from 'app/admin/panel/tickets/admin-panel-new-tickets'; +import AdminPanelAllTickets from 'app/admin/panel/tickets/admin-panel-all-tickets'; +import AdminPanelViewTicket from 'app/admin/panel/tickets/admin-panel-view-ticket'; +import AdminPanelCustomResponses from 'app/admin/panel/tickets/admin-panel-custom-responses'; + +import AdminPanelListUsers from 'app/admin/panel/users/admin-panel-list-users'; +import AdminPanelViewUser from 'app/admin/panel/users/admin-panel-view-user'; +import AdminPanelBanUsers from 'app/admin/panel/users/admin-panel-ban-users'; + +import AdminPanelListArticles from 'app/admin/panel/articles/admin-panel-list-articles'; +import AdminPanelViewArticle from 'app/admin/panel/articles/admin-panel-view-article'; + +import AdminPanelStaffMembers from 'app/admin/panel/staff/admin-panel-staff-members'; +import AdminPanelDepartments from 'app/admin/panel/staff/admin-panel-departments'; +import AdminPanelViewStaff from 'app/admin/panel/staff/admin-panel-view-staff'; + +import AdminPanelSystemPreferences from 'app/admin/panel/settings/admin-panel-system-preferences'; +import AdminPanelUserSystem from 'app/admin/panel/settings/admin-panel-user-system'; +import AdminPanelEmailTemplates from 'app/admin/panel/settings/admin-panel-email-templates'; +import AdminPanelCustomFields from 'app/admin/panel/settings/admin-panel-custom-fields'; const history = syncHistoryWithStore(browserHistory, store); @@ -43,10 +70,50 @@ export default ( - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/src/app/admin/panel/admin-panel-layout.js b/client/src/app/admin/panel/admin-panel-layout.js new file mode 100644 index 00000000..9ca12fa8 --- /dev/null +++ b/client/src/app/admin/panel/admin-panel-layout.js @@ -0,0 +1,20 @@ +import React from 'react'; +import MainLayout from 'app/main/main-layout'; + +class AdminPanel extends React.Component { + + render() { + return ( + +
+ THIS IS THE ADMIN PANEL +
+
+ {this.props.children} +
+
+ ); + } +} + +export default AdminPanel; \ No newline at end of file diff --git a/client/src/app/admin/panel/admin-panel.scss b/client/src/app/admin/panel/admin-panel-layout.scss similarity index 100% rename from client/src/app/admin/panel/admin-panel.scss rename to client/src/app/admin/panel/admin-panel-layout.scss diff --git a/client/src/app/admin/panel/admin-panel.js b/client/src/app/admin/panel/admin-panel.js deleted file mode 100644 index b0bb5113..00000000 --- a/client/src/app/admin/panel/admin-panel.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; - -class AdminPanel extends React.Component { - render(){ - return ( -
- Admin panel... -
- ); - } -} - -export default AdminPanel; \ No newline at end of file diff --git a/client/src/app/admin/panel/articles/admin-panel-list-articles.js b/client/src/app/admin/panel/articles/admin-panel-list-articles.js new file mode 100644 index 00000000..cb607d94 --- /dev/null +++ b/client/src/app/admin/panel/articles/admin-panel-list-articles.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelListArticles extends React.Component { + + render() { + return ( +
+ /admin/panel/articles/list-articles +
+ ); + } +} + +export default AdminPanelListArticles; \ No newline at end of file diff --git a/client/src/app/admin/panel/articles/admin-panel-view-article.js b/client/src/app/admin/panel/articles/admin-panel-view-article.js new file mode 100644 index 00000000..fa026870 --- /dev/null +++ b/client/src/app/admin/panel/articles/admin-panel-view-article.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelViewArticle extends React.Component { + + render() { + return ( +
+ /admin/panel/articles/view-article +
+ ); + } +} + +export default AdminPanelViewArticle; \ No newline at end of file diff --git a/client/src/app/admin/panel/dashboard/admin-panel-activity.js b/client/src/app/admin/panel/dashboard/admin-panel-activity.js new file mode 100644 index 00000000..9b0cc102 --- /dev/null +++ b/client/src/app/admin/panel/dashboard/admin-panel-activity.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelActivity extends React.Component { + + render() { + return ( +
+ /admin/panel/activity +
+ ); + } +} + +export default AdminPanelActivity; \ No newline at end of file diff --git a/client/src/app/admin/panel/dashboard/admin-panel-my-account.js b/client/src/app/admin/panel/dashboard/admin-panel-my-account.js new file mode 100644 index 00000000..9e938cdd --- /dev/null +++ b/client/src/app/admin/panel/dashboard/admin-panel-my-account.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelMyAccount extends React.Component { + + render() { + return ( +
+ /admin/panel/my-account +
+ ); + } +} + +export default AdminPanelMyAccount; \ No newline at end of file diff --git a/client/src/app/admin/panel/dashboard/admin-panel-stats.js b/client/src/app/admin/panel/dashboard/admin-panel-stats.js new file mode 100644 index 00000000..020264e4 --- /dev/null +++ b/client/src/app/admin/panel/dashboard/admin-panel-stats.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelStats extends React.Component { + + render() { + return ( +
+ /admin/panel/stats +
+ ); + } +} + +export default AdminPanelStats; \ No newline at end of file diff --git a/client/src/app/admin/panel/settings/admin-panel-custom-fields.js b/client/src/app/admin/panel/settings/admin-panel-custom-fields.js new file mode 100644 index 00000000..8ffce603 --- /dev/null +++ b/client/src/app/admin/panel/settings/admin-panel-custom-fields.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelCustomFields extends React.Component { + + render() { + return ( +
+ /admin/panel/settings/custom-fields +
+ ); + } +} + +export default AdminPanelCustomFields; \ No newline at end of file diff --git a/client/src/app/admin/panel/settings/admin-panel-email-templates.js b/client/src/app/admin/panel/settings/admin-panel-email-templates.js new file mode 100644 index 00000000..d111b0f6 --- /dev/null +++ b/client/src/app/admin/panel/settings/admin-panel-email-templates.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelEmailTemplates extends React.Component { + + render() { + return ( +
+ /admin/panel/settings/email-templates +
+ ); + } +} + +export default AdminPanelEmailTemplates; \ No newline at end of file diff --git a/client/src/app/admin/panel/settings/admin-panel-system-preferences.js b/client/src/app/admin/panel/settings/admin-panel-system-preferences.js new file mode 100644 index 00000000..cbeafabe --- /dev/null +++ b/client/src/app/admin/panel/settings/admin-panel-system-preferences.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelSystemPreferences extends React.Component { + + render() { + return ( +
+ /admin/panel/settings/system-preferences +
+ ); + } +} + +export default AdminPanelSystemPreferences; \ No newline at end of file diff --git a/client/src/app/admin/panel/settings/admin-panel-user-system.js b/client/src/app/admin/panel/settings/admin-panel-user-system.js new file mode 100644 index 00000000..671bd69b --- /dev/null +++ b/client/src/app/admin/panel/settings/admin-panel-user-system.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelUserSystem extends React.Component { + + render() { + return ( +
+ /admin/panel/settings/user-system +
+ ); + } +} + +export default AdminPanelUserSystem; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/admin-panel-departments.js b/client/src/app/admin/panel/staff/admin-panel-departments.js new file mode 100644 index 00000000..768add5f --- /dev/null +++ b/client/src/app/admin/panel/staff/admin-panel-departments.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelDepartments extends React.Component { + + render() { + return ( +
+ /admin/panel/staff/departments +
+ ); + } +} + +export default AdminPanelDepartments; \ 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 new file mode 100644 index 00000000..f869fc8b --- /dev/null +++ b/client/src/app/admin/panel/staff/admin-panel-staff-members.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelStaffMembers extends React.Component { + + render() { + return ( +
+ /admin/panel/staff/staff-members +
+ ); + } +} + +export default AdminPanelStaffMembers; \ No newline at end of file diff --git a/client/src/app/admin/panel/staff/admin-panel-view-staff.js b/client/src/app/admin/panel/staff/admin-panel-view-staff.js new file mode 100644 index 00000000..23076093 --- /dev/null +++ b/client/src/app/admin/panel/staff/admin-panel-view-staff.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelViewStaff extends React.Component { + + render() { + return ( +
+ /admin/panel/staff/view-staff +
+ ); + } +} + +export default AdminPanelViewStaff; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js new file mode 100644 index 00000000..93a4f327 --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-all-tickets.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelAllTickets extends React.Component { + + render() { + return ( +
+ /admin/panel/tickets/all-tickets +
+ ); + } +} + +export default AdminPanelAllTickets; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-custom-responses.js b/client/src/app/admin/panel/tickets/admin-panel-custom-responses.js new file mode 100644 index 00000000..a4d3c1cf --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-custom-responses.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelCustomResponses extends React.Component { + + render() { + return ( +
+ /admin/panel/tickets/custom-responses +
+ ); + } +} + +export default AdminPanelCustomResponses; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js new file mode 100644 index 00000000..03a0ffa2 --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-my-tickets.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelMyTickets extends React.Component { + + render() { + return ( +
+ /admin/panel/tickets/my-tickets +
+ ); + } +} + +export default AdminPanelMyTickets; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js new file mode 100644 index 00000000..42d250a8 --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-new-tickets.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelNewTickets extends React.Component { + + render() { + return ( +
+ /admin/panel/tickets/new-tickets +
+ ); + } +} + +export default AdminPanelNewTickets; \ No newline at end of file diff --git a/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js new file mode 100644 index 00000000..620324bb --- /dev/null +++ b/client/src/app/admin/panel/tickets/admin-panel-view-ticket.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelViewTicket extends React.Component { + + render() { + return ( +
+ /admin/panel/tickets/view-ticket +
+ ); + } +} + +export default AdminPanelViewTicket; \ No newline at end of file diff --git a/client/src/app/admin/panel/users/admin-panel-ban-users.js b/client/src/app/admin/panel/users/admin-panel-ban-users.js new file mode 100644 index 00000000..acb259e4 --- /dev/null +++ b/client/src/app/admin/panel/users/admin-panel-ban-users.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelBanUsers extends React.Component { + + render() { + return ( +
+ /admin/panel/users/ban-users +
+ ); + } +} + +export default AdminPanelBanUsers; \ No newline at end of file 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 new file mode 100644 index 00000000..8661164e --- /dev/null +++ b/client/src/app/admin/panel/users/admin-panel-list-users.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelListUsers extends React.Component { + + render() { + return ( +
+ /admin/panel/users/list-users +
+ ); + } +} + +export default AdminPanelListUsers; \ No newline at end of file diff --git a/client/src/app/admin/panel/users/admin-panel-view-user.js b/client/src/app/admin/panel/users/admin-panel-view-user.js new file mode 100644 index 00000000..57b828e6 --- /dev/null +++ b/client/src/app/admin/panel/users/admin-panel-view-user.js @@ -0,0 +1,14 @@ +import React from 'react'; + +class AdminPanelViewUser extends React.Component { + + render() { + return ( +
+ /admin/panel/users/view-user +
+ ); + } +} + +export default AdminPanelViewUser; \ No newline at end of file From 3936e772d7460dd58d89a11382e122f565896585 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 24 Sep 2016 18:16:55 -0300 Subject: [PATCH 3/7] Ivan - STAFF LOGIN - Add session architecture for staff login [skip ci] --- client/src/actions/session-actions.js | 6 +++--- client/src/app/App.js | 12 ++++++++++-- client/src/app/admin/admin-login-page.js | 22 +++++++++++++++------- client/src/data/fixtures/staff-fixtures.js | 1 + client/src/reducers/session-reducer.js | 15 ++++++++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/client/src/actions/session-actions.js b/client/src/actions/session-actions.js index 90aa07ae..08c95be8 100644 --- a/client/src/actions/session-actions.js +++ b/client/src/actions/session-actions.js @@ -12,7 +12,7 @@ export default { path: '/user/login', data: loginData }).then((result) => { - store.dispatch(this.getUserData(result.data.userId, result.data.token)); + store.dispatch(this.getUserData(result.data.userId, result.data.token, result.data.staff)); return result; }) @@ -49,7 +49,7 @@ export default { }; }, - getUserData(userId, token) { + getUserData(userId, token, staff) { let data = {}; if (userId && token) { @@ -62,7 +62,7 @@ export default { return { type: 'USER_DATA', payload: API.call({ - path: '/user/get', + path: (staff) ? '/staff/get' : '/user/get', data: data }) } diff --git a/client/src/app/App.js b/client/src/app/App.js index 00f2efdf..90197430 100644 --- a/client/src/app/App.js +++ b/client/src/app/App.js @@ -44,7 +44,9 @@ class App extends React.Component { const validations = { languageChanged: props.config.language !== this.props.config.language, loggedIn: !_.includes(props.location.pathname, '/dashboard') && props.session.logged, - loggedOut: _.includes(props.location.pathname, '/dashboard') && !props.session.logged + loggedOut: _.includes(props.location.pathname, '/dashboard') && !props.session.logged, + loggedInStaff: !_.includes(props.location.pathname, '/admin/panel') && props.session.staff, + loggedOutStaff: _.includes(props.location.pathname, '/admin/panel') && !props.session.logged }; if (validations.languageChanged) { @@ -55,8 +57,14 @@ class App extends React.Component { browserHistory.push('/'); } - if (validations.loggedIn) { + if (validations.loggedOutStaff) { + browserHistory.push('/admin'); + } + + if (validations.loggedIn && !props.session.staff) { browserHistory.push('/dashboard'); + } else if(validations.loggedInStaff) { + browserHistory.push('/admin/panel'); } } } diff --git a/client/src/app/admin/admin-login-page.js b/client/src/app/admin/admin-login-page.js index e4727f21..12d74dc5 100644 --- a/client/src/app/admin/admin-login-page.js +++ b/client/src/app/admin/admin-login-page.js @@ -1,23 +1,25 @@ import React from 'react'; +import _ from 'lodash'; +import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; -import API from 'lib-app/api-call'; +import SessionActions from 'actions/session-actions'; import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; class AdminLoginPage extends React.Component { - render(){ + render() { return (
OpenSupports Admin Panel
-
+ - - {i18n('LOG_IN')} + + {i18n('LOG_IN')}
@@ -26,8 +28,14 @@ class AdminLoginPage extends React.Component { } onSubmit(formState) { - + this.props.dispatch(SessionActions.login(_.extend({}, formState, { + staff: true + }))); } } -export default AdminLoginPage; \ No newline at end of file +export default connect((store) => { + return { + session: store.session + }; +})(AdminLoginPage); diff --git a/client/src/data/fixtures/staff-fixtures.js b/client/src/data/fixtures/staff-fixtures.js index c4f0a578..ea6afbcd 100644 --- a/client/src/data/fixtures/staff-fixtures.js +++ b/client/src/data/fixtures/staff-fixtures.js @@ -10,6 +10,7 @@ module.exports = [ email: 'staff@opensupports.com', profilePic: 'http://i65.tinypic.com/9bep95.jpg', level: 1, + staff: true, departments: [ {id: 1, name: 'Sales Support'}, {id: 2, name: 'Technical Issues'}, diff --git a/client/src/reducers/session-reducer.js b/client/src/reducers/session-reducer.js index 877bb590..92251dce 100644 --- a/client/src/reducers/session-reducer.js +++ b/client/src/reducers/session-reducer.js @@ -41,7 +41,8 @@ class SessionReducer extends Reducer { return _.extend({}, state, { logged: true, pending: false, - failed: false + failed: false, + staff: payload.data.staff }); } @@ -101,8 +102,12 @@ class SessionReducer extends Reducer { sessionStore.storeUserData(payload.data); return _.extend({}, state, { - userName: userData.name, - userEmail: userData.email, + staff: userData.staff, + userName: userData.name, + userEmail: userData.email, + userProfilePic: userData.profilePic, + userLevel: userData.level, + userDepartments: userData.departments, userTickets: userData.tickets }); } @@ -113,8 +118,12 @@ class SessionReducer extends Reducer { return _.extend({}, state, { initDone: true, logged: true, + staff: userData.staff, userName: userData.name, userEmail: userData.email, + userProfilePic: userData.profilePic, + userLevel: userData.level, + userDepartments: userData.departments, userTickets: userData.tickets }); } From b5dcaa900912b44c2057f702dfcd84c9fa63c6e3 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 24 Sep 2016 20:19:24 -0300 Subject: [PATCH 4/7] Ivan - STAFF LOGIN - Add header for staff panel with profile pic and menu [skip ci] --- .../src/app/admin/panel/admin-panel-layout.js | 26 ++- .../app/admin/panel/admin-panel-layout.scss | 7 + .../src/app/admin/panel/admin-panel-menu.js | 203 ++++++++++++++++++ .../src/app/admin/panel/admin-panel-menu.scss | 3 + .../admin/panel/admin-panel-staff-widget.js | 47 ++++ .../admin/panel/admin-panel-staff-widget.scss | 47 ++++ client/src/data/languages/en.js | 19 ++ 7 files changed, 347 insertions(+), 5 deletions(-) create mode 100644 client/src/app/admin/panel/admin-panel-menu.js create mode 100644 client/src/app/admin/panel/admin-panel-menu.scss create mode 100644 client/src/app/admin/panel/admin-panel-staff-widget.js create mode 100644 client/src/app/admin/panel/admin-panel-staff-widget.scss diff --git a/client/src/app/admin/panel/admin-panel-layout.js b/client/src/app/admin/panel/admin-panel-layout.js index 9ca12fa8..59a5e7d9 100644 --- a/client/src/app/admin/panel/admin-panel-layout.js +++ b/client/src/app/admin/panel/admin-panel-layout.js @@ -1,16 +1,32 @@ import React from 'react'; + import MainLayout from 'app/main/main-layout'; +import AdminPanelStaffWidget from 'app/admin/panel/admin-panel-staff-widget'; +import AdminPanelMenu from 'app/admin/panel/admin-panel-menu'; + +import Widget from 'core-components/widget'; class AdminPanel extends React.Component { render() { return ( -
- THIS IS THE ADMIN PANEL -
-
- {this.props.children} +
+
+
+ +
+
+ +
+
+
+
+ + {this.props.children} + +
+
); diff --git a/client/src/app/admin/panel/admin-panel-layout.scss b/client/src/app/admin/panel/admin-panel-layout.scss index e69de29b..42a68014 100644 --- a/client/src/app/admin/panel/admin-panel-layout.scss +++ b/client/src/app/admin/panel/admin-panel-layout.scss @@ -0,0 +1,7 @@ +.admin-panel-layout { + padding: 0 10px; + + &__header { + margin-bottom: 20px; + } +} \ No newline at end of file diff --git a/client/src/app/admin/panel/admin-panel-menu.js b/client/src/app/admin/panel/admin-panel-menu.js new file mode 100644 index 00000000..de97eaf4 --- /dev/null +++ b/client/src/app/admin/panel/admin-panel-menu.js @@ -0,0 +1,203 @@ +import React from 'react'; +import _ from 'lodash'; + +import {dispatch} from 'app/store'; +import i18n from 'lib-app/i18n'; + +import Menu from 'core-components/menu'; + +class AdminPanelMenu extends React.Component { + static contextTypes = { + router: React.PropTypes.object + }; + + static propTypes = { + location: React.PropTypes.object + }; + + render() { + return ( +
+ + +
+ ); + } + + getGroupsMenuProps() { + return { + items: this.getGroups(), + selectedIndex: this.getGroupIndex(), + onItemClick: this.onGroupClick.bind(this), + tabbable: true, + type: 'primary' + }; + } + + getGroupMenuProps() { + return { + items: this.getGroupItems(), + selectedIndex: this.getGroupItemIndex(), + onItemClick: this.onGroupItemClick.bind(this), + tabbable: true, + type: 'secondary' + }; + } + + getGroups() { + return this.getRoutes().map((group) => { + return { + content: group.groupName, + icon: group.icon + }; + }); + } + + getGroupItems() { + const group = this.getRoutes()[this.getGroupIndex()]; + + return group.items.map((item) => { + return { + content: item.name + }; + }); + } + + onGroupClick(index) { + this.context.router.push(this.getRoutes()[index].path); + } + + onGroupItemClick(index) { + const group = this.getRoutes()[this.getGroupIndex()]; + + this.context.router.push(group.items[index].path); + } + + getGroupItemIndex() { + const group = this.getRoutes()[this.getGroupIndex()]; + const pathname = this.props.location.pathname; + const itemIndex = _.findIndex(group.items, {path: pathname}); + + return (itemIndex === -1) ? 0 : itemIndex; + } + + getGroupIndex() { + const pathname = this.props.location.pathname; + const groupIndex = _.findLastIndex(this.getRoutes(), (group) => { + return _.includes(pathname, group.path); + }); + + return (groupIndex === -1) ? 0 : groupIndex; + } + + getRoutes() { + return [ + { + groupName: i18n('DASHBOARD'), + path: '/admin/panel', + icon: 'tachometer', + items: [ + { + name: i18n('TICKET_STATS'), + path: '/admin/panel/stats' + }, + { + name: i18n('LAST_ACTIVITY'), + path: '/admin/panel/activity' + } + ] + }, + { + groupName: i18n('TICKETS'), + path: '/admin/panel/tickets', + icon: 'ticket', + items: [ + { + name: i18n('MY_TICKETS'), + path: '/admin/panel/tickets/my-tickets' + }, + { + name: i18n('NEW_TICKETS'), + path: '/admin/panel/tickets/new-tickets' + }, + { + name: i18n('ALL_TICKETS'), + path: '/admin/panel/tickets/all-tickets' + }, + { + name: i18n('CUSTOM_RESPONSES'), + path: '/admin/panel/tickets/custom-responses' + } + ] + }, + { + groupName: i18n('USERS'), + path: '/admin/panel/users', + icon: 'user', + items: [ + { + name: i18n('LIST_USERS'), + path: '/admin/panel/users/list-users' + }, + { + name: i18n('BAN_USERS'), + path: '/admin/panel/users/ban-users' + } + ] + }, + { + groupName: i18n('ARTICLES'), + path: '/admin/panel/articles', + icon: 'book', + items: [ + { + name: i18n('LIST_ARTICLES'), + path: '/admin/panel/articles/list-articles' + } + ] + }, + { + + groupName: i18n('STAFF'), + path: '/admin/panel/staff', + icon: 'users', + items: [ + { + name: i18n('STAFF_MEMBERS'), + path: '/admin/panel/staff/staff-members' + }, + { + name: i18n('DEPARTMENTS'), + path: '/admin/panel/staff/departments' + } + ] + }, + { + + groupName: i18n('SETTINGS'), + path: '/admin/panel/settings', + icon: 'cogs', + items: [ + { + name: i18n('SYSTEM_PREFERENCES'), + path: '/admin/panel/settings/system-preferences' + }, + { + name: i18n('USER_SYSTEM'), + path: '/admin/panel/settings/user-system' + }, + { + name: i18n('EMAIL_TEMPLATES'), + path: '/admin/panel/settings/email-templates' + }, + { + name: i18n('FILTERS_CUSTOM_FIELDS'), + path: '/admin/panel/settings/custom-fields' + } + ] + } + ]; + } +} + +export default AdminPanelMenu; diff --git a/client/src/app/admin/panel/admin-panel-menu.scss b/client/src/app/admin/panel/admin-panel-menu.scss new file mode 100644 index 00000000..89d1a17b --- /dev/null +++ b/client/src/app/admin/panel/admin-panel-menu.scss @@ -0,0 +1,3 @@ +.admin-panel-menu { + +} \ No newline at end of file diff --git a/client/src/app/admin/panel/admin-panel-staff-widget.js b/client/src/app/admin/panel/admin-panel-staff-widget.js new file mode 100644 index 00000000..c213a752 --- /dev/null +++ b/client/src/app/admin/panel/admin-panel-staff-widget.js @@ -0,0 +1,47 @@ +import React from 'react'; +import classNames from 'classnames'; +import {connect} from 'react-redux'; + +import i18n from 'lib-app/i18n'; +import Button from 'core-components/button'; + +class AdminPanelStaffWidget extends React.Component { + + render() { + return ( +
+
+
{this.props.session.userName}
+
+ + | + +
+
+
+ +
+
+ ); + } + + getClass() { + let classes = { + 'admin-panel-staff-widget': true + }; + + classes[this.props.className] = (this.props.className); + + return classNames(classes); + } +} + +export default connect((store) => { + return { + session: store.session + }; +})(AdminPanelStaffWidget); diff --git a/client/src/app/admin/panel/admin-panel-staff-widget.scss b/client/src/app/admin/panel/admin-panel-staff-widget.scss new file mode 100644 index 00000000..1de336ad --- /dev/null +++ b/client/src/app/admin/panel/admin-panel-staff-widget.scss @@ -0,0 +1,47 @@ +@import '../../../scss/vars'; + +.admin-panel-staff-widget { + background-color: $secondary-blue; + position: relative; + width: 100%; + height: 165px; + text-align: center; + + &__profile-pic-wrapper { + position: absolute; + top: 8px; + border: 4px solid $grey; + border-radius: 50%; + width: 90px; + height: 90px; + overflow: hidden; + text-align: center; + left: 50%; + transform: translate(-50%, 0); + } + + &__profile-pic { + height: 100%; + position: absolute; + left: 50%; + transform: translate(-50%, 0); + } + + &__user-data { + position: absolute; + background-color: white; + bottom: 0; + width: 100%; + height: 110px; + padding-top: 48px; + } + + &__name { + font-size: $font-size--md; + } + + &__actions { + font-size: $font-size--xs; + margin-top: 10px; + } +} \ No newline at end of file diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 0eea85dc..c41e460c 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -36,6 +36,25 @@ export default { 'CUSTOMER': 'Customer', 'YES': 'Yes', 'CANCEL': 'Cancel', + 'MY_ACCOUNT': 'My Account', + 'DASHBOARD': 'Dashboard', + 'USERS': 'Users', + 'SETTINGS': 'Settings', + 'TICKET_STATS': 'Ticket Stats', + 'LAST_ACTIVITY': 'Last Activity', + 'MY_TICKETS': 'My Tickets', + 'NEW_TICKETS': 'New Tickets', + 'ALL_TICKETS': 'All Tickets', + 'CUSTOM_RESPONSES': 'Custom Responses', + 'LIST_USERS': 'List Users', + 'BAN_USERS': 'Ban Users', + 'LIST_ARTICLES': 'List Articles', + 'STAFF_MEMBERS': 'Staff Members', + 'DEPARTMENTS': 'Departments', + 'SYSTEM_PREFERENCES': 'System Preferences', + 'USER_SYSTEM': 'User System', + 'EMAIL_TEMPLATES': 'Email Templates', + 'FILTERS_CUSTOM_FIELDS': 'Filters and Custom Fields', //ERRORS 'EMAIL_NOT_EXIST': 'Email does not exist', From 116c974f9cbc83c9c6d00a2b06b69c906672a415 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 24 Sep 2016 21:33:09 -0300 Subject: [PATCH 5/7] Ivan - STAFF LOGIN - Add horizontal and horizontal-list menu [skip ci] --- .../src/app/admin/panel/admin-panel-menu.js | 7 +- client/src/app/demo/components-demo-page.js | 30 ++++-- client/src/core-components/menu.js | 4 +- client/src/core-components/menu.scss | 93 ++++++++++++++++++- 4 files changed, 122 insertions(+), 12 deletions(-) diff --git a/client/src/app/admin/panel/admin-panel-menu.js b/client/src/app/admin/panel/admin-panel-menu.js index de97eaf4..5f77ef37 100644 --- a/client/src/app/admin/panel/admin-panel-menu.js +++ b/client/src/app/admin/panel/admin-panel-menu.js @@ -30,7 +30,7 @@ class AdminPanelMenu extends React.Component { selectedIndex: this.getGroupIndex(), onItemClick: this.onGroupClick.bind(this), tabbable: true, - type: 'primary' + type: 'horizontal' }; } @@ -40,7 +40,7 @@ class AdminPanelMenu extends React.Component { selectedIndex: this.getGroupItemIndex(), onItemClick: this.onGroupItemClick.bind(this), tabbable: true, - type: 'secondary' + type: 'horizontal-list' }; } @@ -76,9 +76,8 @@ class AdminPanelMenu extends React.Component { getGroupItemIndex() { const group = this.getRoutes()[this.getGroupIndex()]; const pathname = this.props.location.pathname; - const itemIndex = _.findIndex(group.items, {path: pathname}); - return (itemIndex === -1) ? 0 : itemIndex; + return _.findIndex(group.items, {path: pathname}); } getGroupIndex() { diff --git a/client/src/app/demo/components-demo-page.js b/client/src/app/demo/components-demo-page.js index 363d4873..122bff4a 100644 --- a/client/src/app/demo/components-demo-page.js +++ b/client/src/app/demo/components-demo-page.js @@ -65,12 +65,6 @@ let DemoPage = React.createClass({ ) }, - { - title: 'DropDown', - render: ( - - ) - }, { title: 'Primary Menu', render: ( @@ -83,6 +77,30 @@ let DemoPage = React.createClass({ ) }, + { + title: 'Navigation Menu', + render: ( + + ) + }, + { + title: 'Horizontal Menu', + render: ( + + ) + }, + { + title: 'HorizontalList Menu', + render: ( + + ) + }, + { + title: 'DropDown', + render: ( + + ) + }, { title: 'Tooltip', render: ( diff --git a/client/src/core-components/menu.js b/client/src/core-components/menu.js index 18158405..3a7d849f 100644 --- a/client/src/core-components/menu.js +++ b/client/src/core-components/menu.js @@ -84,7 +84,9 @@ class Menu extends React.Component { let classes = { 'menu': true, 'menu_secondary': (this.props.type === 'secondary'), - 'menu_navigation': (this.props.type === 'navigation') + 'menu_navigation': (this.props.type === 'navigation'), + 'menu_horizontal': (this.props.type === 'horizontal'), + 'menu_horizontal-list': (this.props.type === 'horizontal-list') }; classes[this.props.className] = true; diff --git a/client/src/core-components/menu.scss b/client/src/core-components/menu.scss index ab2c661b..3a425f87 100644 --- a/client/src/core-components/menu.scss +++ b/client/src/core-components/menu.scss @@ -1,5 +1,7 @@ @import "../scss/vars"; +$transition: background-color 0.3s ease, color 0.3s ease; + .menu { &__list { @@ -13,7 +15,7 @@ &__list-item { padding: 8px; - transition: background-color 0.3s ease, color 0.3s ease; + transition: $transition; &_selected, &:hover { @@ -78,4 +80,93 @@ color: $primary-blue; } } + + &_horizontal { + text-align: center; + + .menu__list { + background-color: transparent; + font-size: $font-size--md; + } + + .menu__icon { + display: block; + margin-right: 0; + margin-bottom: 20px; + margin-top: 20px; + font-size: $font-size--xl; + } + + .menu__list-item { + background-color: white; + color: $primary-black; + cursor: pointer; + display: inline-block; + height: 120px; + width: 16.6667%; + + @media (max-width: 667px) { + width: 33.3333%; + } + } + + .menu__list-item_selected { + background-color: $secondary-blue; + color: white; + } + + .menu__list-item:hover, + .menu__list-item:focus { + color: $dark-grey; + outline: none; + } + + .menu__list-item_selected:focus, + .menu__list-item_selected:hover { + color: white; + } + } + + &_horizontal-list { + text-align: left; + background-color: $secondary-blue; + min-height: 45px; + + .menu__list { + background-color: transparent; + font-size: $font-size--sm; + } + + .menu__list-item { + transition: none; + background-color: transparent; + color: white; + cursor: pointer; + display: inline-block; + margin-top: 11px; + margin-bottom: 10px; + margin-left: 20px; + padding: 2px 13px; + } + + .menu__list-item:hover { + transition: $transition; + background-color: transparent; + color: $primary-black; + } + + .menu__list-item:focus { + color: $grey; + outline: none; + } + + .menu__list-item_selected, + .menu__list-item_selected:hover { + transition: $transition; + padding: 2px 13px; + border-radius: 30px; + background-color: $primary-blue; + color: white; + } + } } \ No newline at end of file From cc7c5bfb3da689f690d16a6ef4dc4621325b9c66 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 25 Sep 2016 01:16:10 -0300 Subject: [PATCH 6/7] Ivan - STAFF LOGIN - Add Staff login to backend [skip ci] --- server/controllers/staff.php | 9 ++++++ server/controllers/staff/get.php | 36 +++++++++++++++++++++ server/controllers/user/get.php | 5 +++ server/controllers/user/login.php | 9 ++++-- server/libs/Controller.php | 16 +++++---- server/libs/Validator.php | 5 +-- server/models/Session.php | 7 +++- server/models/Staff.php | 5 +++ server/models/User.php | 5 +-- server/tests/controllers/user/loginTest.php | 3 +- tests/init.rb | 1 + tests/libs.rb | 5 +++ tests/scripts.rb | 5 +-- tests/staff/get.rb | 15 +++++++++ tests/user/login.rb | 33 ++++++++++++++++--- tests/user/signup.rb | 1 - 16 files changed, 135 insertions(+), 25 deletions(-) create mode 100644 server/controllers/staff.php create mode 100644 server/controllers/staff/get.php create mode 100644 tests/staff/get.rb diff --git a/server/controllers/staff.php b/server/controllers/staff.php new file mode 100644 index 00000000..21df1a90 --- /dev/null +++ b/server/controllers/staff.php @@ -0,0 +1,9 @@ +setGroupPath('/staff'); + +$systemControllerGroup->addController(new GetStaffController); + +$systemControllerGroup->finalize(); \ No newline at end of file diff --git a/server/controllers/staff/get.php b/server/controllers/staff/get.php new file mode 100644 index 00000000..db922c80 --- /dev/null +++ b/server/controllers/staff/get.php @@ -0,0 +1,36 @@ + 'staff_1', + 'requestData' => [] + ]; + } + + public function handler() { + $user = Controller::getLoggedUser(); + $parsedDepartmentList = []; + $departmentList = $user->sharedDepartmentList; + + foreach($departmentList as $department) { + $parsedDepartmentList[] = [ + 'id' => $department->id, + 'name' => $department->name + ]; + } + + Response::respondSuccess([ + 'name' => $user->name, + 'email' => $user->email, + 'profilePic' => $user->profilePic, + 'level' => $user->level, + 'staff' => true, + 'departments' => $parsedDepartmentList + ]); + } +} \ No newline at end of file diff --git a/server/controllers/user/get.php b/server/controllers/user/get.php index 9310c5cf..23aa331e 100644 --- a/server/controllers/user/get.php +++ b/server/controllers/user/get.php @@ -13,6 +13,11 @@ class GetUserController extends Controller { } public function handler() { + if (Controller::isStaffLogged()) { + Response::respondError(ERRORS::INVALID_CREDENTIALS); + return; + } + $user = Controller::getLoggedUser(); $parsedTicketList = []; $ticketList = $user->sharedTicketList; diff --git a/server/controllers/user/login.php b/server/controllers/user/login.php index b32e757e..07cb3340 100644 --- a/server/controllers/user/login.php +++ b/server/controllers/user/login.php @@ -46,7 +46,7 @@ class LoginController extends Controller { } private function createUserSession() { - Session::getInstance()->createSession($this->userInstance->id); + Session::getInstance()->createSession($this->userInstance->id, Controller::request('staff')); } private function getUserData() { @@ -55,6 +55,7 @@ class LoginController extends Controller { return array( 'userId' => $userInstance->id, 'userEmail' => $userInstance->email, + 'staff' => Controller::request('staff'), 'token' => Session::getInstance()->getToken(), 'rememberToken' => $this->rememberToken ); @@ -64,7 +65,11 @@ class LoginController extends Controller { $email = Controller::request('email'); $password = Controller::request('password'); - return User::authenticate($email, $password); + if(Controller::request('staff')) { + return Staff::authenticate($email, $password); + } else { + return User::authenticate($email, $password); + } } private function getUserByRememberToken() { diff --git a/server/libs/Controller.php b/server/libs/Controller.php index 73a642b2..8403f7c5 100644 --- a/server/libs/Controller.php +++ b/server/libs/Controller.php @@ -36,7 +36,13 @@ abstract class Controller { } public static function getLoggedUser() { - return User::getUser((int)self::request('csrf_userid')); + $session = Session::getInstance(); + + if ($session->isStaffLogged()) { + return Staff::getUser((int)self::request('csrf_userid')); + } else { + return User::getUser((int)self::request('csrf_userid')); + } } public static function isUserLogged() { @@ -48,12 +54,8 @@ abstract class Controller { )); } - public static function isStaffLogged() { - return Controller::isUserLogged() && (Controller::getLoggedUser()->admin === 1); - } - - public static function isAdminLogged() { - return Controller::isUserLogged() && (Controller::getLoggedUser()->admin === 2); + public static function isStaffLogged($level = 1) { + return Controller::isUserLogged() && (Controller::getLoggedUser()->level >= $level); } public static function getAppInstance() { diff --git a/server/libs/Validator.php b/server/libs/Validator.php index 7bf85acc..a3c19a98 100644 --- a/server/libs/Validator.php +++ b/server/libs/Validator.php @@ -16,8 +16,9 @@ class Validator { $permissions = [ 'any' => true, 'user' => Controller::isUserLogged(), - 'staff' => Controller::isStaffLogged(), - 'admin' => Controller::isAdminLogged() + 'staff_1' => Controller::isStaffLogged(1), + 'staff_2' => Controller::isStaffLogged(2), + 'staff_3' => Controller::isStaffLogged(3) ]; if (!$permissions[$permission]) { diff --git a/server/models/Session.php b/server/models/Session.php index 9bb54dd6..9535876a 100644 --- a/server/models/Session.php +++ b/server/models/Session.php @@ -24,8 +24,9 @@ class Session { return self::$instance; } - public function createSession($userId) { + public function createSession($userId, $staff = false) { $this->store('userId', $userId); + $this->store('staff', $staff); $this->store('token', Hashing::generateRandomToken()); } @@ -37,6 +38,10 @@ class Session { return !!$this->getToken(); } + public function isStaffLogged() { + return $this->getStoredData('staff'); + } + public function checkAuthentication($data) { $userId = $this->getStoredData('userId'); $token = $this->getStoredData('token'); diff --git a/server/models/Staff.php b/server/models/Staff.php index 1f5b7084..03e3e078 100644 --- a/server/models/Staff.php +++ b/server/models/Staff.php @@ -3,6 +3,11 @@ class Staff extends DataStore { const TABLE = 'staff'; + public static function authenticate($userEmail, $userPassword) { + $user = Staff::getUser($userEmail, 'email'); + + return ($user && Hashing::verifyPassword($userPassword, $user->password)) ? $user : new NullDataStore(); + } public static function getProps() { return [ diff --git a/server/models/User.php b/server/models/User.php index eefbc4c5..b25f5a1a 100644 --- a/server/models/User.php +++ b/server/models/User.php @@ -15,16 +15,13 @@ class User extends DataStore { 'email', 'password', 'name', - 'admin', 'sharedTicketList', 'verificationToken', ]; } public function getDefaultProps() { - return [ - 'admin' => 0 - ]; + return []; } public static function getUser($value, $property = 'id') { diff --git a/server/tests/controllers/user/loginTest.php b/server/tests/controllers/user/loginTest.php index 0f78bc03..2a1583f7 100644 --- a/server/tests/controllers/user/loginTest.php +++ b/server/tests/controllers/user/loginTest.php @@ -35,10 +35,11 @@ class LoginControllerTest extends PHPUnit_Framework_TestCase { $this->loginController->handler(); - $this->assertTrue(Session::getInstance()->createSession->hasBeenCalledWithArgs('MOCK_ID')); + $this->assertTrue(Session::getInstance()->createSession->hasBeenCalledWithArgs('MOCK_ID', null)); $this->assertTrue(Response::get('respondSuccess')->hasBeenCalledWithArgs(array( 'userId' => 'MOCK_ID', 'userEmail' => 'MOCK_EMAIL', + 'staff' => null, 'token' => 'TEST_TOKEN', 'rememberToken' => null ))); diff --git a/tests/init.rb b/tests/init.rb index fb875785..db0b6d11 100644 --- a/tests/init.rb +++ b/tests/init.rb @@ -21,3 +21,4 @@ require './user/get.rb' require './ticket/create.rb' require './ticket/comment.rb' require './ticket/get.rb' +require './staff/get.rb' diff --git a/tests/libs.rb b/tests/libs.rb index 907ef709..b8431702 100644 --- a/tests/libs.rb +++ b/tests/libs.rb @@ -26,3 +26,8 @@ class Database end $database = Database.new + +$staff = { + :email => 'staff@opensupports.com', + :password => 'staff' +} diff --git a/tests/scripts.rb b/tests/scripts.rb index f6b3e18d..6b91569e 100644 --- a/tests/scripts.rb +++ b/tests/scripts.rb @@ -11,11 +11,12 @@ class Scripts end end - def self.login(email = 'steve@jobs.com', password = 'custompassword') + def self.login(email = 'steve@jobs.com', password = 'custompassword', staff = false) request('/user/logout') response = request('/user/login', { :email => email, - :password => password + :password => password, + :staff => staff }) if response['data'].any? diff --git a/tests/staff/get.rb b/tests/staff/get.rb new file mode 100644 index 00000000..a0abd11b --- /dev/null +++ b/tests/staff/get.rb @@ -0,0 +1,15 @@ +describe '/staff/get/' do + request('/user/logout') + Scripts.login($staff[:email], $staff[:password], true) + + it 'should return staff member data' do + result = request('/staff/get', { + csrf_userid: $csrf_userid, + csrf_token: $csrf_token + }) + + (result['status']).should.equal('success') + (result['data']['name']).should.equal('Emilia Clarke') + (result['data']['staff']).should.equal(true) + end +end \ No newline at end of file diff --git a/tests/user/login.rb b/tests/user/login.rb index 7c0d5738..870cbc1f 100644 --- a/tests/user/login.rb +++ b/tests/user/login.rb @@ -13,13 +13,36 @@ describe '/user/login' do (result['status']).should.equal('fail') end -# it 'should login correctly' do + it 'should login correctly' do + result = request('/user/login', { + email: @loginEmail, + password: @loginPass + }) -# end + (result['status']).should.equal('success') + end -# it 'should fail if already logged in' do + it 'should fail if already logged in' do + result = request('/user/login', { + email: @loginEmail, + password: @loginPass + }) -# end + (result['status']).should.equal('fail') + (result['message']).should.equal('User is already logged in') + end + + it 'should login staff member' do + request('/user/logout', {}) + result = request('/user/login', { + email: $staff[:email], + password: $staff[:password], + staff: true + }) + + (result['status']).should.equal('success') + (result['data']['staff']).should.equal('true') + end it 'should return remember token' do request('/user/logout', {}) @@ -31,7 +54,7 @@ describe '/user/login' do (result['status']).should.equal('success') - @rememberToken = result['data']['rememberToken']# falta comproversion + @rememberToken = result['data']['rememberToken'] @userid = result['data']['userId'] end diff --git a/tests/user/signup.rb b/tests/user/signup.rb index f1309ddc..bebf131d 100644 --- a/tests/user/signup.rb +++ b/tests/user/signup.rb @@ -10,7 +10,6 @@ describe '/user/signup' do (userRow['email']).should.equal('steve@jobs.com') (userRow['name']).should.equal('Steve Jobs') - (userRow['admin']).should.equal('0') end it 'should fail if name is invalid' do From 842afe49eb4edd6d2ddb7ec761696bb39249dbc5 Mon Sep 17 00:00:00 2001 From: ivan Date: Sun, 25 Sep 2016 01:30:38 -0300 Subject: [PATCH 7/7] Ivan - STAFF LOGIN - Fix issues and improve frontend login [skip ci] --- client/src/app/App.js | 2 +- client/src/app/admin/admin-login-page.js | 21 +++++++++++++++++-- client/src/app/admin/admin-login-page.scss | 8 +++---- .../admin/panel/admin-panel-staff-widget.js | 7 ++++++- .../dashboard-edit-profile-page.js | 1 - client/src/data/languages/en.js | 1 + 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/client/src/app/App.js b/client/src/app/App.js index 90197430..52d55cb5 100644 --- a/client/src/app/App.js +++ b/client/src/app/App.js @@ -45,7 +45,7 @@ class App extends React.Component { languageChanged: props.config.language !== this.props.config.language, loggedIn: !_.includes(props.location.pathname, '/dashboard') && props.session.logged, loggedOut: _.includes(props.location.pathname, '/dashboard') && !props.session.logged, - loggedInStaff: !_.includes(props.location.pathname, '/admin/panel') && props.session.staff, + loggedInStaff: !_.includes(props.location.pathname, '/admin/panel') && props.session.logged && props.session.staff, loggedOutStaff: _.includes(props.location.pathname, '/admin/panel') && !props.session.logged }; diff --git a/client/src/app/admin/admin-login-page.js b/client/src/app/admin/admin-login-page.js index 12d74dc5..9d7f2770 100644 --- a/client/src/app/admin/admin-login-page.js +++ b/client/src/app/admin/admin-login-page.js @@ -8,12 +8,14 @@ import SessionActions from 'actions/session-actions'; import Form from 'core-components/form'; import FormField from 'core-components/form-field'; import SubmitButton from 'core-components/submit-button'; +import Message from 'core-components/message'; +import Widget from 'core-components/widget'; class AdminLoginPage extends React.Component { render() { return (
-
+
OpenSupports Admin Panel
@@ -22,11 +24,26 @@ class AdminLoginPage extends React.Component { {i18n('LOG_IN')}
-
+ {this.renderMessage()} +
); } + renderMessage() { + let message = null; + + if(this.props.session.failed) { + message = ( + + {i18n('EMAIL_OR_PASSWORD')} + + ); + } + + return message; + } + onSubmit(formState) { this.props.dispatch(SessionActions.login(_.extend({}, formState, { staff: true diff --git a/client/src/app/admin/admin-login-page.scss b/client/src/app/admin/admin-login-page.scss index 60a5a738..57b07631 100644 --- a/client/src/app/admin/admin-login-page.scss +++ b/client/src/app/admin/admin-login-page.scss @@ -5,11 +5,7 @@ &__content { margin: 0 auto; - display: inline-block; - background-color: white; padding: 40px; - border-radius: 4px; - text-align: center; } &__image { @@ -21,4 +17,8 @@ margin: 0 auto; display: inline-block; } + + &__error { + margin-top: 30px; + } } \ No newline at end of file diff --git a/client/src/app/admin/panel/admin-panel-staff-widget.js b/client/src/app/admin/panel/admin-panel-staff-widget.js index c213a752..913f151d 100644 --- a/client/src/app/admin/panel/admin-panel-staff-widget.js +++ b/client/src/app/admin/panel/admin-panel-staff-widget.js @@ -4,6 +4,7 @@ import {connect} from 'react-redux'; import i18n from 'lib-app/i18n'; import Button from 'core-components/button'; +import SessionActions from 'actions/session-actions'; class AdminPanelStaffWidget extends React.Component { @@ -17,7 +18,7 @@ class AdminPanelStaffWidget extends React.Component { {i18n('MY_ACCOUNT')} | -
@@ -38,6 +39,10 @@ class AdminPanelStaffWidget extends React.Component { return classNames(classes); } + + closeSession() { + this.props.dispatch(SessionActions.logout()); + } } export default connect((store) => { diff --git a/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js b/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js index 4e32405f..fed82146 100644 --- a/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js +++ b/client/src/app/main/dashboard/dashboard-edit-profile/dashboard-edit-profile-page.js @@ -20,7 +20,6 @@ class DashboardEditProfilePage extends React.Component { messagePass:'' }; - render() { return (
diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index c41e460c..8335a733 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -57,6 +57,7 @@ export default { 'FILTERS_CUSTOM_FIELDS': 'Filters and Custom Fields', //ERRORS + 'EMAIL_OR_PASSWORD': 'Email or password invalid', 'EMAIL_NOT_EXIST': 'Email does not exist', 'ERROR_EMPTY': 'Invalid value', 'ERROR_PASSWORD': 'Invalid password',