diff --git a/assets/css/style.css b/assets/css/style.css
index 77cf861..7db0d11 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -780,15 +780,31 @@ label {
/* line 166, ../sass/_base.scss */
#filter-side-bar {
+ display: block;
padding: 3.6rem 5rem;
+ width: 350px;
+ right: -350px;
+ transition: 0.2s ease right;
+}
+/* line 172, ../sass/_base.scss */
+#filter-side-bar.active {
+ right: 0;
+ transition: 0.2s ease all;
+}
+/* line 177, ../sass/_base.scss */
+#filter-side-bar .uib-datepicker .btn-sm {
+ padding: 7px 10px;
+ font-size: 12px;
+ line-height: 1.5;
+ border-radius: 3px;
}
-/* line 173, ../sass/_base.scss */
+/* line 189, ../sass/_base.scss */
.panel-container {
height: 100vh;
padding-top: 10vh;
}
-/* line 176, ../sass/_base.scss */
+/* line 192, ../sass/_base.scss */
.panel-container .panel-body {
width: 500px;
border-radius: 4px;
@@ -799,7 +815,7 @@ label {
-moz-box-shadow: 0 2px 6px rgba(153, 170, 190, 0.16);
box-shadow: 0 2px 6px rgba(153, 170, 190, 0.16);
}
-/* line 183, ../sass/_base.scss */
+/* line 199, ../sass/_base.scss */
.panel-container .panel-body .panel-title {
letter-spacing: 0.03rem;
color: #5d58de;
@@ -807,27 +823,27 @@ label {
margin-bottom: 1.5rem;
}
-/* line 194, ../sass/_base.scss */
+/* line 210, ../sass/_base.scss */
.modal .modal-dialog .modal-content {
border: none;
border-radius: 6px;
}
-/* line 198, ../sass/_base.scss */
+/* line 214, ../sass/_base.scss */
.modal .modal-dialog .modal-content .modal-header {
border-bottom: none;
}
-/* line 201, ../sass/_base.scss */
+/* line 217, ../sass/_base.scss */
.modal .modal-dialog .modal-content .modal-body {
padding: 2rem 3rem;
min-height: 200px;
}
-/* line 203, ../sass/_base.scss */
+/* line 219, ../sass/_base.scss */
.modal .modal-dialog .modal-content .modal-body h3 {
font-family: 'Roboto-Medium', sans-serif;
color: #221d76;
margin-bottom: 3rem;
}
-/* line 210, ../sass/_base.scss */
+/* line 226, ../sass/_base.scss */
.modal .modal-dialog .modal-content .modal-footer {
border-top: none;
padding-bottom: 4rem;
diff --git a/assets/frontend/app.js b/assets/frontend/app.js
index b061e93..59f08f6 100644
--- a/assets/frontend/app.js
+++ b/assets/frontend/app.js
@@ -4,8 +4,13 @@
angular
.module('portal', [
'ui.router',
+ 'ngAnimate',
+ 'ngSanitize',
+ 'ngTouch',
+ 'ui.bootstrap',
'invoices.portal',
'users.portal',
+ 'dashboard.portal',
])
.constant('TEMPLATE_URL', '/static/frontend/templates/')
;
diff --git a/assets/frontend/dashboard/controllers.js b/assets/frontend/dashboard/controllers.js
new file mode 100644
index 0000000..7591207
--- /dev/null
+++ b/assets/frontend/dashboard/controllers.js
@@ -0,0 +1,110 @@
+(function() {
+ 'use strict';
+
+ angular
+ .module('dashboard.portal')
+ .controller('DashBoardController', DashBoardController)
+ .controller('asideInvoiceController', asideInvoiceController)
+ ;
+
+ /* DashBoardController
+ * @ desc: This will displat the list of user invoices
+ */
+ function DashBoardController($scope, $rootScope, InvoiceService) {
+ feather.replace();
+ var self = this;
+ var order = 'asc';
+
+ self.invoiceService = InvoiceService;
+ self.sorting = {
+ 'customer': false,
+ 'code': false,
+ 'due_date': false,
+ 'status': false,
+ };
+
+ //request to the backend
+ self.sortBy = function(field, order) {
+ var page_number = {"page": self.invoiceService.list.page.number}
+ self.invoiceService.getList(page_number, field, order);
+ };
+
+ // Sort the display
+ self.sort = function (field) {
+ feather.replace();
+ self.sorting[field] = !self.sorting[field];
+ self.order = self.order == 'asc' ? 'desc' : 'asc';
+
+ if(self.order === 'asc') {
+ self.sortBy(field, 'asc');
+ } else if (self.order === 'desc') {
+ self.sortBy(field, 'desc');
+ };
+ };
+
+ // this will trigger the filter button
+ self.onFilterClick = function () {
+ $rootScope.isSideBarActive = true;
+ };
+
+ $scope.$watch('ctrl.invoiceService.filter', function (newItem, oldItem){
+ self.invoiceService.filter = newItem;
+ }, true);
+
+ self.deleteItem = function() {
+ self.invoiceService.filter = {};
+
+ self.invoiceService.navData = {};
+ };
+
+ self.clearItem = function() {
+ self.invoiceService.filter = {};
+
+ self.invoiceService.navData = {};
+ };
+
+ }; // end of DashBoardController
+
+ /* aside Controller
+ * @desc: this will display the sidebar for invoice filter
+ */
+ function asideInvoiceController($scope, $rootScope, InvoiceService) {
+ var self = this;
+ feather.replace();
+ self.invoiceService = InvoiceService;
+
+ self.onsideBarClose = function() {
+ $rootScope.isSideBarActive = false;
+ };
+
+ self.onSelectFilter = function(data, key) {
+ feather.replace();
+ self.invoiceService.filter[key] = data[key];
+
+ self.invoiceService.navData[key] = data[key];
+
+ if(key === 'due_date') {
+ self.invoiceService.navData['due_date'] = moment(data['due_date']).format("ll")
+ };
+
+ if(key === 'total_amount') {
+ self.invoiceService.navData['total_amount'] = data['total_amount']
+ .toLocaleString('en-US', {
+ style: 'currency',
+ currency: 'USD',
+ })
+ };
+
+ };
+
+ self.resetFilter = function() {
+ self.invoiceService.filter = {};
+ $scope.filter = undefined;
+ $scope.filter_due_date = undefined;
+ $scope.filter_status = undefined;
+ $scope.filter_total_amount = undefined;
+ };
+
+ }; // end of asideInvoiceController
+
+})();
diff --git a/assets/frontend/dashboard/directives.js b/assets/frontend/dashboard/directives.js
new file mode 100644
index 0000000..90bec60
--- /dev/null
+++ b/assets/frontend/dashboard/directives.js
@@ -0,0 +1,26 @@
+(function() {
+ 'use strict';
+
+ angular
+ .module('dashboard.portal')
+ .directive('sideBar', sideBar)
+ ;
+
+ /* side bar directive
+ * @desc: directive for invoice sidebar
+ */
+ function sideBar(TEMPLATE_URL) {
+ var directive = {
+ restrict: 'EA',
+ scope: {
+ active: '='
+ },
+ templateUrl: TEMPLATE_URL + '/dashboard/sidebar.html',
+ controller: 'asideInvoiceController',
+ controllerAs: 'ctrl',
+ bindToController: true
+ };
+ return directive;
+ }; // end of sideBar
+
+})();
diff --git a/assets/frontend/dashboard/init.js b/assets/frontend/dashboard/init.js
new file mode 100644
index 0000000..02bf788
--- /dev/null
+++ b/assets/frontend/dashboard/init.js
@@ -0,0 +1,9 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('dashboard.portal', [])
+ .constant('TEMPLATE_URL', '/static/frontend/templates/dashboard/')
+ ;
+
+})();
diff --git a/assets/frontend/dashboard/routes.js b/assets/frontend/dashboard/routes.js
new file mode 100644
index 0000000..ac52d77
--- /dev/null
+++ b/assets/frontend/dashboard/routes.js
@@ -0,0 +1,19 @@
+(function () {
+ 'use strict';
+
+ angular
+ .module('dashboard.portal')
+ .config(routes)
+ ;
+
+ function routes($stateProvider, TEMPLATE_URL) {
+ $stateProvider
+ .state('dashboard', {
+ url: '/dashboard/',
+ templateUrl: TEMPLATE_URL + '/dashboard.html/',
+ controller: 'DashBoardController',
+ controllerAs: 'ctrl',
+ });
+ }; // end of routes
+
+})();
diff --git a/assets/frontend/dashboard/services.js b/assets/frontend/dashboard/services.js
new file mode 100644
index 0000000..e69de29
diff --git a/assets/frontend/invoices/services.js b/assets/frontend/invoices/services.js
index 4cd4ae3..f3588e3 100644
--- a/assets/frontend/invoices/services.js
+++ b/assets/frontend/invoices/services.js
@@ -21,7 +21,19 @@
update : update,
addItems : addItems,
updateItems: updateItems,
- deleteInv : deleteInv
+ deleteInv : deleteInv,
+ filter : {
+ customer : undefined,
+ due_date : undefined,
+ status : undefined,
+ total_amount : undefined,
+ },
+ navData : {
+ customer : undefined,
+ due_date : undefined,
+ status : undefined,
+ total_amount : undefined,
+ },
}
getList();
@@ -31,12 +43,12 @@
/* Gets list of all invoices
*/
- function getList (params) {
- return $http.get(API_INVOICE_URL + $httpParamSerializer(params))
+ function getList (params, field, order) {
+ return $http.get(API_INVOICE_URL + '?' + $httpParamSerializer(params) + (field ? '&sort='+field : '') + (order ? '&order='+order : ''))
.then(function (response) {
- services.list = response.data.result;
+ services.list = response.data;
});
- }
+ };
/* Gets detail of the invoice by id
*/
@@ -91,4 +103,4 @@
}
-})();
\ No newline at end of file
+})();
diff --git a/assets/frontend/templates/dashboard/dashboard.html b/assets/frontend/templates/dashboard/dashboard.html
new file mode 100644
index 0000000..68bb343
--- /dev/null
+++ b/assets/frontend/templates/dashboard/dashboard.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+
My invoices
+
+ {{ ctrl.invoiceService.list.page.count }} invoices total with {{ ctrl.invoiceService.list.due_dates }} on due and {{ ctrl.invoiceService.list.drafts }} drafts
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/frontend/templates/dashboard/sidebar.html b/assets/frontend/templates/dashboard/sidebar.html
new file mode 100644
index 0000000..b90c0ef
--- /dev/null
+++ b/assets/frontend/templates/dashboard/sidebar.html
@@ -0,0 +1,45 @@
+
diff --git a/assets/frontend/templates/invoices/invoice.html b/assets/frontend/templates/invoices/invoice.html
index aebc7bb..fc29a01 100644
--- a/assets/frontend/templates/invoices/invoice.html
+++ b/assets/frontend/templates/invoices/invoice.html
@@ -4,23 +4,23 @@
@@ -214,4 +214,4 @@ ${{ctrl.invoice.total_amount}}
-
\ No newline at end of file
+
diff --git a/assets/frontend/templates/navbar.html b/assets/frontend/templates/navbar.html
index 90ace4f..af15721 100644
--- a/assets/frontend/templates/navbar.html
+++ b/assets/frontend/templates/navbar.html
@@ -8,7 +8,7 @@
-
- Dashboard
+ Dashboard
-
Clients
diff --git a/assets/frontend/users/controllers.js b/assets/frontend/users/controllers.js
index 7800374..b18c024 100644
--- a/assets/frontend/users/controllers.js
+++ b/assets/frontend/users/controllers.js
@@ -34,7 +34,7 @@
InvoiceService
.create(invoice)
.then(function (response) {
- InvoiceService.list.push(response.data);
+ InvoiceService.list.result.push(response.data);
$state.go('invoiceDetail', {id: response.data.id});
});
};
@@ -79,7 +79,7 @@
self.loginUser = function (form) {
UserService.userLogin(form);
- $state.go('invoices');
+ $state.go('dashboard');
};
}; // end of LoginController
diff --git a/assets/package.json b/assets/package.json
index 7e27378..7af7c9e 100644
--- a/assets/package.json
+++ b/assets/package.json
@@ -11,13 +11,20 @@
"dependencies": {
"@uirouter/angularjs": "^1.0.15",
"angular": "^1.6.9",
+ "angular-animate": "^1.6.9",
+ "angular-sanitize": "^1.6.9",
+ "angular-selector": "^1.6.1",
+ "angular-touch": "^1.6.9",
+ "angular-ui-bootstrap": "^2.5.6",
"bootstrap": "^4.0.0",
"bootstrap-select": "^1.12.4",
"datepicker-bootstrap": "^1.8.0",
"dripicons": "^2.0.0",
"feather-icons": "^4.6.0",
"jquery": "^3.3.1",
+ "moment": "^2.22.0",
"popper.js": "^1.12.9",
- "roboto-fontface-woff": "^0.8.0"
+ "roboto-fontface-woff": "^0.8.0",
+ "ui-select": "^0.19.8"
}
}
diff --git a/assets/sass/_base.scss b/assets/sass/_base.scss
index de46993..a9bac0b 100644
--- a/assets/sass/_base.scss
+++ b/assets/sass/_base.scss
@@ -164,7 +164,15 @@
}
#filter-side-bar {
+ display: block;
padding: 3.6rem 5rem;
+ width: 350px;
+ right:-350px;
+ transition: 0.2s ease right;
+ &.active {
+ right: 0;
+ transition: 0.2s ease all;
+ }
}
diff --git a/invoices/mixins.py b/invoices/mixins.py
index 76986e2..a92924b 100644
--- a/invoices/mixins.py
+++ b/invoices/mixins.py
@@ -39,4 +39,6 @@ def paginate(self, query):
'number': self.page.number,
},
'result': serializer.data,
- }
\ No newline at end of file
+ 'drafts': Invoice.objects.drafts().count(),
+ 'due_dates': Invoice.objects.past_due().count(),
+ }
diff --git a/invoices/views.py b/invoices/views.py
index c840217..afeb26f 100644
--- a/invoices/views.py
+++ b/invoices/views.py
@@ -40,7 +40,13 @@ class InvoicesAPI(LoginRequiredMixin, Paginate ,ViewSet):
serializer_class = InvoiceSerializer
def list(self, *args, **kwargs):
+ query = self.request.query_params.get('sort')
+ order = self.request.query_params.get('order')
invoices = self.serializer_class.Meta.model.objects.all()
+ if order == 'asc':
+ invoices = invoices.order_by('-' + query)
+ elif order == 'desc':
+ invoices = invoices.order_by(query)
data = self.paginate(invoices)
return Response(data, status=200)
diff --git a/templates/base.html b/templates/base.html
index 002b438..75a3e74 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -21,6 +21,7 @@
+
@@ -30,12 +31,17 @@
+
+
+
+
+
{% include 'includes/angular_modules.html' %}
diff --git a/templates/includes/angular_modules.html b/templates/includes/angular_modules.html
index ef63b93..be6c343 100644
--- a/templates/includes/angular_modules.html
+++ b/templates/includes/angular_modules.html
@@ -3,10 +3,15 @@
+
+
+
+
+
+
-
-
+