Merge pull request #2 from Pear-Trading/finn/MoreCoreUI
Putting all the work into dev branch
This commit is contained in:
commit
d24666362d
492 changed files with 29230 additions and 1651 deletions
58
.angular-cli.json
Normal file
58
.angular-cli.json
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"project": {
|
||||
"version": "1.0.0-alpha.4",
|
||||
"name": "coreui-angular"
|
||||
},
|
||||
"apps": [
|
||||
{
|
||||
"root": "src",
|
||||
"outDir": "dist",
|
||||
"assets": ["assets"],
|
||||
"index": "index.html",
|
||||
"main": "main.ts",
|
||||
"polyfills": "polyfills.ts",
|
||||
"test": "test.ts",
|
||||
"tsconfig": "tsconfig.app.json",
|
||||
"testTsconfig": "tsconfig.spec.json",
|
||||
"prefix": "app",
|
||||
"scripts": [
|
||||
"../node_modules/moment/min/moment.min.js"
|
||||
],
|
||||
"styles": [
|
||||
"scss/style.scss"
|
||||
],
|
||||
"environmentSource": "environments/environment.ts",
|
||||
"environments": {
|
||||
"dev": "environments/environment.ts",
|
||||
"prod": "environments/environment.prod.ts",
|
||||
"local": "environments/environment.local.ts"
|
||||
}
|
||||
}
|
||||
],
|
||||
"e2e": {
|
||||
"protractor": {
|
||||
"config": "./protractor.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": [
|
||||
{
|
||||
"project": "src/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"project": "src/tsconfig.spec.json"
|
||||
},
|
||||
{
|
||||
"project": "e2e/tsconfig.e2e.json"
|
||||
}
|
||||
],
|
||||
"test": {
|
||||
"karma": {
|
||||
"config": "./karma.conf.js"
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"styleExt": "scss",
|
||||
"prefixInterfaces": false
|
||||
}
|
||||
}
|
14
.editorconfig
Normal file
14
.editorconfig
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = 0
|
||||
trim_trailing_whitespace = false
|
27
.gitignore
vendored
27
.gitignore
vendored
|
@ -17,6 +17,33 @@ $RECYCLE.BIN/
|
|||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/bower_components
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
*.launch
|
||||
.settings/
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage/*
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# local env variable
|
||||
/src/environments/environment.local.ts
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 creativeLabs Lukasz Holeczek.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the Software), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, andor sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
65
README.md
65
README.md
|
@ -1,2 +1,63 @@
|
|||
# FoodLoop-Web
|
||||
For information on how to edit the CoreUI, see here: http://coreui.io/docs/getting-started/introduction
|
||||
# LocalLoop Web Interface
|
||||
|
||||
This is the repository for the LocalLoop web interface, for traders and
|
||||
customers to see and submit data to the service.
|
||||
|
||||
## Getting Started
|
||||
|
||||
To get started with development, you will need an up to date version of
|
||||
node.js, git, and access to either the backend dev server, or a local running
|
||||
copy of the backend server from [LocalLoop Server][LocalLoop-Server].
|
||||
|
||||
For your local node.js, We reccomend using [n][tj/n] on \*nix and Mac, for
|
||||
Windows take a look at [nodist][marcelklehr/nodist] - although other options
|
||||
exist. We reccomend Node.js version 8.0.0+ and npm version 5.3.0+.
|
||||
|
||||
To get this repository set up, first clone it and then run the following
|
||||
commands:
|
||||
|
||||
```
|
||||
npm install -g @angular/cli
|
||||
npm install
|
||||
```
|
||||
|
||||
[LocalLoop-Server]:https://github.com/Pear-Trading/Foodloop-Server
|
||||
[tj/n]:https://github.com/tj/n
|
||||
[marcelklehr/nodist]:https://github.com/marcelklehr/nodist
|
||||
|
||||
## Environments
|
||||
|
||||
The app defaults to using the development server. For other options, see
|
||||
`src/environments/environments.ts`
|
||||
|
||||
# Old README
|
||||
|
||||
This is the old README with some minor tips on getting started, and more reading.
|
||||
|
||||
## Angular2DevelopmentCLI
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.0.0-beta.32.3.
|
||||
|
||||
### Development server
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
### Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class/module`.
|
||||
|
||||
### Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
||||
|
||||
### Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
### Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
Before running the tests make sure you are serving the app via `ng serve`.
|
||||
|
||||
### Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
|
|
149
app.js
149
app.js
|
@ -1,149 +0,0 @@
|
|||
var app = angular.module(
|
||||
"FoodLoop",
|
||||
[
|
||||
'ngRoute',
|
||||
'ui.router'
|
||||
]
|
||||
);
|
||||
|
||||
// calling order
|
||||
// 1-> app.config()
|
||||
// 2-> app.run()
|
||||
// 3-> directive's compile functions (if they are found in the dom)
|
||||
// 4-> app.controller()
|
||||
// 5-> directive's link functions (again, if found)
|
||||
|
||||
|
||||
app.config(function($stateProvider, $urlRouterProvider) {
|
||||
// use $urlRouterProvider to catch all the illeage cases
|
||||
// $urlRouterProvider.otherwise("/login");
|
||||
|
||||
$stateProvider
|
||||
// if loggin as user
|
||||
.state('user',{
|
||||
url:"/user",
|
||||
views:{
|
||||
'': {templateUrl:'pages/home/home.html',controller:'userCtrl'},
|
||||
'header@user': {templateUrl:'pages/user/header.user.html'}, // nested view
|
||||
'sidebar@user': {templateUrl:'pages/user/sidebar.user.html'},
|
||||
'main@user': {templateUrl:'pages/user/main.user.html'},
|
||||
},data:{
|
||||
requireLogin: false
|
||||
}
|
||||
})
|
||||
.state('user.receipt',{
|
||||
url:"",
|
||||
views:{
|
||||
'main@user': {templateUrl:'pages/receipt/receipt.html',controller:"receiptCtrl"},
|
||||
}
|
||||
})
|
||||
.state('user.leaderboard',{
|
||||
url:"",
|
||||
views:{
|
||||
'main@user': {templateUrl:'pages/user/main.leaderboard.html'},
|
||||
}
|
||||
})
|
||||
.state('user.settings',{
|
||||
url:"",
|
||||
views:{
|
||||
'main@user': {templateUrl:'pages/user/main.settings.html'},
|
||||
}
|
||||
})
|
||||
.state('user.help',{
|
||||
url:"",
|
||||
views:{
|
||||
'main@user': {templateUrl:'pages/user/main.settings.html'},
|
||||
}
|
||||
})
|
||||
.state('admin.view_receipt',{
|
||||
url:"",
|
||||
params: {
|
||||
receipt: null,
|
||||
},
|
||||
views:{
|
||||
'main@admin': {
|
||||
templateUrl:'pages/admin/main.receipt.html',
|
||||
controller: function($scope,$stateParams){
|
||||
$scope.receipt = $stateParams.receipt;
|
||||
console.log($scope.receipt);
|
||||
}},
|
||||
},data:{
|
||||
requireLogin: false
|
||||
}
|
||||
}
|
||||
)
|
||||
.state('admin',{
|
||||
url:"/admin",
|
||||
controller: 'adminCtrl',
|
||||
views:{
|
||||
'': { templateUrl: 'pages/home/home.html',controller:'adminCtrl'}, // default view}
|
||||
'header@admin': {templateUrl:'pages/admin/header.admin.html'}, // nested view
|
||||
'sidebar@admin': {templateUrl:'pages/admin/sidebar.admin.html'},
|
||||
'main@admin': {templateUrl:'pages/admin/main.admin.html'},
|
||||
},data:{
|
||||
requireLogin: false
|
||||
}
|
||||
})
|
||||
.state('trader',{
|
||||
url:"/trader",
|
||||
views:{
|
||||
'': { templateUrl: 'pages/home/home.html',controller:'traderCtrl'}, // default view}
|
||||
'header@trader': {templateUrl:'pages/trader/header.trader.html'}, // nested view
|
||||
'sidebar@trader': {templateUrl:'pages/trader/sidebar.trader.html'},
|
||||
'main@trader': {templateUrl:'pages/trader/main.trader.html'},
|
||||
},data:{
|
||||
requireLogin: false
|
||||
}
|
||||
})
|
||||
|
||||
.state('map',{
|
||||
url: '/map',
|
||||
templateUrl: 'pages/map/map.html',
|
||||
controller: 'mapCtrl',
|
||||
data: {
|
||||
requireLogin : false
|
||||
}
|
||||
})
|
||||
.state('login',{
|
||||
url: '',
|
||||
templateUrl: 'pages/login/login.html',
|
||||
controller: 'loginCtrl',
|
||||
data: {
|
||||
requireLogin : false
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* redirects to different page based on whether the user is login or not and */
|
||||
/* if log on, check user type and redirect/construct a custom dashboard page */
|
||||
/* to extend, users may have a custome dashboard with different layout, this */
|
||||
/* needs to be handled using HTML page which is specifically constucted by */
|
||||
/* page'controller and obtain variable setting from server */
|
||||
// /* if not, redirect to login in page */
|
||||
app.run(function ($rootScope,$state,authService) { // kickstart the application
|
||||
// listening to the when a state change start
|
||||
console.log("State changes");
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
|
||||
console.log(toState);
|
||||
// var requireLogin = toState.data.requireLogin;
|
||||
// redirect to login page if satisfy the following conditions
|
||||
// 1. seesion expired and user tries to access a page
|
||||
// if ((requireLogin && typeof $rootScope.currentUser === 'undefined')) {
|
||||
// event.preventDefault();
|
||||
// $state.transitionTo('login');
|
||||
// }
|
||||
});
|
||||
// Testing, configuration to firebase
|
||||
var config = {
|
||||
apiKey: "AIzaSyDypwjmMD818GQTTfyhTpx76ChJpDsZGek",
|
||||
authDomain: "foodloop-666db.firebaseapp.com",
|
||||
databaseURL: "https://foodloop-666db.firebaseio.com",
|
||||
storageBucket: "foodloop-666db.appspot.com",
|
||||
messagingSenderId: "832579459759"
|
||||
};
|
||||
firebase.initializeApp(config);
|
||||
|
||||
})
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[0212/144844:ERROR:tcp_listen_socket.cc(76)] Could not bind socket to 127.0.0.1:6004
|
||||
[0212/144844:ERROR:node_debugger.cc(86)] Cannot start debugger server
|
24
e2e/login.e2e-spec.ts
Normal file
24
e2e/login.e2e-spec.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { LoginPageObject } from './login.po';
|
||||
|
||||
describe('Login Page', () => {
|
||||
let page: LoginPageObject;
|
||||
|
||||
beforeEach(() => {
|
||||
page = new LoginPageObject();
|
||||
page.navigateTo();
|
||||
});
|
||||
|
||||
it('should have a header saying login', () => {
|
||||
expect(page.getLoginHeaderText()).toEqual('Login');
|
||||
});
|
||||
|
||||
it('should have a username box of type text', () => {
|
||||
expect(page.isUsernameFieldPresent()).toBeTruthy();
|
||||
expect(page.getUsernameFieldType()).toBe('text');
|
||||
});
|
||||
|
||||
it('should have a password box of type password', () => {
|
||||
expect(page.isPasswordFieldPresent()).toBeTruthy();
|
||||
expect(page.getPasswordFieldType()).toBe('password');
|
||||
});
|
||||
});
|
20
e2e/login.po.ts
Normal file
20
e2e/login.po.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { browser, element, by } from 'protractor';
|
||||
|
||||
export class LoginPageObject {
|
||||
navigateTo() {
|
||||
return browser.get('/login');
|
||||
}
|
||||
|
||||
getLoginHeaderText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
|
||||
getUsernameField() { return element(by.id('username')); }
|
||||
getPasswordField() { return element(by.id('password')); }
|
||||
|
||||
isUsernameFieldPresent() { return this.getUsernameField().isPresent(); }
|
||||
isPasswordFieldPresent() { return this.getPasswordField().isPresent(); }
|
||||
|
||||
getUsernameFieldType() { return this.getUsernameField().getAttribute('type'); }
|
||||
getPasswordFieldType() { return this.getPasswordField().getAttribute('type'); }
|
||||
}
|
13
e2e/tsconfig.e2e.json
Normal file
13
e2e/tsconfig.e2e.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
75
index.html
75
index.html
|
@ -1,75 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html ng-app="FoodLoop" >
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
|
||||
<head>
|
||||
<title>FoodLoop Login</title>
|
||||
|
||||
<!-- Bootstrap and jQuery js -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="app.js"></script>
|
||||
|
||||
<!-- Include the ui-router script -->
|
||||
<script src="//unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
|
||||
|
||||
<!-- D3 chart js -->
|
||||
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||||
|
||||
<!-- Map js dependecies -->
|
||||
<script src="https://d3js.org/topojson.v2.min.js"></script>
|
||||
|
||||
<!-- Chart js -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js"></script>
|
||||
|
||||
|
||||
|
||||
<!-- MVC for FoodLoop app -->
|
||||
<script src="pages/login/loginCtrl.js"></script>
|
||||
<!--<link rel="stylesheet" href="pages/login/login.css">-->
|
||||
|
||||
<script src="pages/home/homeCtrl.js"></script>
|
||||
<link rel="stylesheet" href="pages/home/home.css">
|
||||
|
||||
<script src="pages/admin/adminCtrl.js"></script>
|
||||
<!--<link rel="stylesheet" href="pages/admin/admin.css">-->
|
||||
|
||||
<script src="pages/receipt/receiptCtrl.js"></script>
|
||||
<!--<link rel="stylesheet" href="pages/receipt/receipt.css">-->
|
||||
|
||||
<script src="pages/user/userCtrl.js"></script>
|
||||
<!--<link rel="stylesheet" href="pages/user/user.css">-->
|
||||
|
||||
<script src="pages/trader/traderCtrl.js"></script>
|
||||
<!--<link rel="stylesheet" href="pages/trader/trader.css">-->
|
||||
|
||||
<script src="pages/map/mapCtrl.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"></script>
|
||||
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.33.0/mapbox-gl.js'></script>
|
||||
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.33.0/mapbox-gl.css' rel='stylesheet' />
|
||||
<!-- Import services-->
|
||||
<script src="services/authService.js"></script>
|
||||
<script src="services/chartService.js"></script>
|
||||
<script src="services/uploadReceiptservice.js"></script>
|
||||
|
||||
<!-- firebase for testing -->
|
||||
<script src="https://www.gstatic.com/firebasejs/3.6.9/firebase.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body >
|
||||
|
||||
<!-- Dsiplay the main content -->
|
||||
<ui-view></ui-view>
|
||||
</body>
|
||||
</html>
|
44
karma.conf.js
Normal file
44
karma.conf.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/0.13/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular/cli'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular/cli/plugins/karma')
|
||||
],
|
||||
client:{
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
files: [
|
||||
{ pattern: './src/test.ts', watched: false }
|
||||
],
|
||||
preprocessors: {
|
||||
'./src/test.ts': ['@angular/cli']
|
||||
},
|
||||
mime: {
|
||||
'text/x-typescript': ['ts','tsx']
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
reports: [ 'html', 'lcovonly' ],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
reporters: config.angularCli && config.angularCli.codeCoverage
|
||||
? ['progress', 'coverage-istanbul']
|
||||
: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
});
|
||||
};
|
9979
package-lock.json
generated
Normal file
9979
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
62
package.json
Normal file
62
package.json
Normal file
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "coreui-angular",
|
||||
"version": "1.0.0-alpha.5",
|
||||
"description": "Open Source Bootstrap Admin Template",
|
||||
"author": "",
|
||||
"url": "http://coreui.io",
|
||||
"copyright": "Copyright 2017 creativeLabs Łukasz Holeczek",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/common": "4.0.3",
|
||||
"@angular/compiler": "4.0.3",
|
||||
"@angular/core": "4.0.3",
|
||||
"@angular/forms": "4.0.3",
|
||||
"@angular/http": "4.0.3",
|
||||
"@angular/platform-browser": "4.0.3",
|
||||
"@angular/platform-browser-dynamic": "4.0.3",
|
||||
"@angular/router": "4.0.3",
|
||||
"@angular/upgrade": "4.0.3",
|
||||
"@types/moment": "^2.13.0",
|
||||
"angular-in-memory-web-api": "^0.3.1",
|
||||
"chart.js": "2.5.0",
|
||||
"core-js": "2.4.1",
|
||||
"moment": "^2.18.1",
|
||||
"ng2-charts": "1.6.0",
|
||||
"ng2-validation-manager": "^0.3.1",
|
||||
"ngx-bootstrap": "1.6.6",
|
||||
"rxjs": "5.4.2",
|
||||
"ts-helpers": "1.1.2",
|
||||
"webpack": "3.5.4",
|
||||
"webpack-dev-server": "2.7.1",
|
||||
"zone.js": "0.8.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.3.0",
|
||||
"@angular/compiler-cli": "4.0.3",
|
||||
"@types/jasmine": "2.5.54",
|
||||
"@types/jasminewd2": "2.0.2",
|
||||
"@types/node": "8.0.24",
|
||||
"codelyzer": "2.1.1",
|
||||
"jasmine-core": "2.7.0",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"karma": "1.7.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "1.3.0",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.1.2",
|
||||
"ts-node": "3.3.0",
|
||||
"tslint": "4.5.1",
|
||||
"typescript": "2.4.2"
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
<div ui-view="header"></div>
|
||||
<div ui-view="sidebar"></div>
|
||||
<div ui-view="main"></div>
|
|
@ -1,67 +0,0 @@
|
|||
/* this controller specifies the logic layer of the admin page */
|
||||
/* including the content to be display, sidebar, header */
|
||||
/* functionailities involve for an admin */
|
||||
app.controller('adminCtrl', function($scope,$state) {
|
||||
$scope.users;
|
||||
$scope.controllby = "admin";
|
||||
// Initialize Firebase
|
||||
$scope.pending_receipt_sum = 2;
|
||||
$scope.pending_receipt = [
|
||||
{
|
||||
receipt_ref: "r1",
|
||||
submitted_by : "John Lemon",
|
||||
submitted_time: "31",
|
||||
submitted_amount: "8.66",
|
||||
details: "sjadsjoiadsj iasdn aisdn alsdi jadi jasdi ajsdoi ndi snd"
|
||||
}
|
||||
,
|
||||
{
|
||||
submitted_by : "User007",
|
||||
submitted_time: "21",
|
||||
submitted_amount: "22.22"
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
/* section for receipt management start * /
|
||||
/* review a pending receipt */
|
||||
/* fetch a list of pending receipt from server */
|
||||
/* fetch a list of approve receipt from server */
|
||||
$scope.reviewReceipt = function(myReceipt){
|
||||
// testing
|
||||
console.log("[DEBUG]: reviewReceipt called");
|
||||
// show page for review this receipt
|
||||
$state.go('admin.view_receipt', {receipt: myReceipt})
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
$scope.approve_receipt = function(receipt_ref){
|
||||
// call api to approve a pending receipt
|
||||
// notify user
|
||||
}
|
||||
|
||||
|
||||
$scope.fetch_pending_receipt = function(){
|
||||
|
||||
}
|
||||
|
||||
$scope.fetch_submitted_receipt = function(){
|
||||
|
||||
}
|
||||
/* section for receipt management end */
|
||||
|
||||
|
||||
// Get a reference to the database service
|
||||
var database = firebase.database();
|
||||
firebase.database().ref('/users/').once('value').then(function(snapshot) {
|
||||
$scope.users = snapshot.val();
|
||||
});
|
||||
|
||||
$scope.test = function(){
|
||||
|
||||
console.log("CLiced ");
|
||||
console.log($scope.users);
|
||||
}
|
||||
});
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse" style="background-color:#0091EA;">
|
||||
<button class="navbar-toggler navbar-toggler-right hidden-lg-up" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">FoodLoop</a>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Help</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline mt-2 mt-md-0">
|
||||
<input class="form-control mr-sm-2" type="text" placeholder="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
|
@ -1,50 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
|
||||
<div class="row no-gutters">
|
||||
<div class="col-2">
|
||||
<div class="rankCard">
|
||||
<div class="receiptCardHeader"> Section toolbox </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="receiptCard">
|
||||
<div class="receiptCardHeader"> List/Table </div>
|
||||
<div class="tableCard">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Action</th>
|
||||
<th>#</th>
|
||||
<th>From</th>
|
||||
<th>When</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat-start="receipt in pending_receipt">
|
||||
<td>
|
||||
<button type="button" class="btn btn-primary" ng-if="receipt.expanded" ng-click="receipt.expanded = false">review</button>
|
||||
<button type="button" class="btn btn-primary" ng-if="!receipt.expanded" ng-click="receipt.expanded = true">review</button>
|
||||
</td>
|
||||
<td>{{$index + 1}}</td>
|
||||
<td>{{receipt.submitted_by}}</td>
|
||||
<td>{{receipt.submitted_time}} minutes ago</td>
|
||||
<td>£{{receipt.submitted_amount}}</td>
|
||||
</tr>
|
||||
<tr ng-if="receipt.expanded" ng-repeat-end="">
|
||||
<td colspan="5">
|
||||
<div class="receiptDetailCard">
|
||||
{{receipt.details}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- row first -->
|
||||
|
||||
</main>
|
|
@ -1,43 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
|
||||
<div class="row no-gutters">
|
||||
<div class="col-2">
|
||||
<div class="rankCard">
|
||||
<div class="receiptCardHeader"> Section toolbox </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="receiptCard">
|
||||
<div class="receiptCardHeader">{{receipt.receipt_ref}}</div>
|
||||
<div class="tableCard">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>From</th>
|
||||
<th>When</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{$index + 1}}</td>
|
||||
<td>{{receipt.submitted_by}}</td>
|
||||
<td>{{receipt.submitted_time}} minutes ago</td>
|
||||
<td>£{{receipt.submitted_amount}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- table card-->
|
||||
<div class="receiptImageCard">
|
||||
<div> </div>
|
||||
</div>
|
||||
<!-- receiptImageCard-->
|
||||
</div>
|
||||
<!-- receipt card -->
|
||||
</div>
|
||||
<!-- col -->
|
||||
</div>
|
||||
<!-- row first -->
|
||||
</main>
|
|
@ -1,46 +0,0 @@
|
|||
<!-- This page defines a side bar for admin -->
|
||||
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Admin Portal <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">User Management</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Trader Management</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav nav-pills flex-column" id="meq">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Receipt Management</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Pending receipt
|
||||
<span class="badge badge-danger">{{pending_receipt_sum}}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Option 2</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Option 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Nav item again</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">One more nav</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Another nav item</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
|
@ -1,353 +0,0 @@
|
|||
/*
|
||||
* Base structure
|
||||
*/
|
||||
|
||||
/* Move down content because we have a fixed navbar that is 50px tall */
|
||||
body {
|
||||
padding-top: 50px;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
/*
|
||||
* Typography
|
||||
*/
|
||||
|
||||
h1 {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 9px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
main{
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 51px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 1000;
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
border-right: 1px solid #eee;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
|
||||
}
|
||||
|
||||
/* Sidebar navigation */
|
||||
.sidebar {
|
||||
margin-top: -16px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.sidebar .nav {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.sidebar .nav-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar .nav-item + .nav-item {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.profile-pic {
|
||||
border-radius: 80%;
|
||||
background-color: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: dodgerblue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.profilePic{
|
||||
padding: 16px;
|
||||
background-color: transparent;
|
||||
max-width: 100%;
|
||||
height: 130px;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.profileInfo{
|
||||
color:white;
|
||||
padding: 16px;
|
||||
padding-top: 30px;
|
||||
height: 130px;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.profileTitle{
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dashboard
|
||||
*/
|
||||
|
||||
/* Placeholders */
|
||||
.placeholders {
|
||||
padding-bottom: 3rem;
|
||||
}
|
||||
|
||||
.placeholder img {
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
.title{
|
||||
color: black;
|
||||
}
|
||||
.flCard{
|
||||
color:black;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
/*width: 100%;*/
|
||||
height: 110px;;
|
||||
margin-top: 16px;
|
||||
background-color: white;
|
||||
border: green;
|
||||
padding:16px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.rankCard{
|
||||
color:black;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
height: 300px;;
|
||||
margin-top: 16px;
|
||||
background-color: white;
|
||||
border: green;
|
||||
|
||||
}
|
||||
|
||||
.rankCardHeader{
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: 3px;
|
||||
color:white;
|
||||
height:30px;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.chartCardHeader{
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: 3px;
|
||||
color:white;
|
||||
height:30px;
|
||||
background-color: orangered;
|
||||
}
|
||||
|
||||
.rankCardContent{
|
||||
padding: 3px;
|
||||
/*color:white;*/
|
||||
/*background-color: dodgerblue;*/
|
||||
}
|
||||
|
||||
.flCardHeader{
|
||||
height: 25px;
|
||||
}
|
||||
.flCardMain{
|
||||
margin: -16px;
|
||||
font-size: 3.0em;
|
||||
color: dimgray;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.chartCard{
|
||||
color:black;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
height: 300px;;
|
||||
margin-top: 16px;
|
||||
background-color: white;
|
||||
|
||||
}
|
||||
.flCardNote{
|
||||
font-size: 0.8em;
|
||||
color: dodgerblue;
|
||||
text-align: right;
|
||||
}
|
||||
#receiptTable{
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
|
||||
/* CSS FOR RECEIPT */
|
||||
|
||||
.receiptItem{
|
||||
color:black;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
padding: 16px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.receiptCard{
|
||||
color:black;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
margin-top: 16px;
|
||||
padding:16px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.receiptCardHeader{
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: 3px;
|
||||
color:white;
|
||||
padding: 16px;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
|
||||
.receiptDetailCard{
|
||||
color:black;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
height: 300px;
|
||||
margin-top: 16px;
|
||||
background-color: lightcyan;
|
||||
}
|
||||
|
||||
.addButton{
|
||||
background-color: transparent;
|
||||
font-size: 1.0em;
|
||||
margin-left: 50%;
|
||||
|
||||
}
|
||||
|
||||
.dragImageBox:hover{
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
.dragImageBox{
|
||||
border: 2px dashed dodgerblue;
|
||||
border-radius: 4px;
|
||||
background-color:white;
|
||||
height: 150px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
|
||||
.thumb{
|
||||
color:black;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
background-color: white;
|
||||
width: 50px;
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
/* TEMPALTE CSS FOR DISPLAY A CUSTOM CARD */
|
||||
|
||||
.pearCard{
|
||||
color:black;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* On mouse-over, add a deeper shadow */
|
||||
.pearCard:hover {
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.pearCardFooter{
|
||||
width: 100%;
|
||||
margin-bottom: -16px;
|
||||
background-color: lightcyan;
|
||||
}
|
||||
.pearAutoHeight{
|
||||
height: auto;
|
||||
}
|
||||
.pearCardHeader{
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: 9px;
|
||||
color:white;
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
|
||||
.pearOrange{
|
||||
background-color: orangered;
|
||||
}
|
||||
.pearBlue{
|
||||
background-color: dodgerblue;
|
||||
}
|
||||
.pearGreen{
|
||||
background-color: lawngreen;
|
||||
}
|
||||
.pearYellow{
|
||||
background-color: yellow;
|
||||
}
|
||||
.pearPurple{
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
.padding16{
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.margin16{
|
||||
margin-top:16px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* LOGIN CSS */
|
||||
.mainSection{
|
||||
margin-top: 20%;
|
||||
padding:16px;
|
||||
color:black;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.2);
|
||||
transition: 0.3s;
|
||||
border-radius: 3px;
|
||||
font-size: 1em;
|
||||
/*height: 150px;*/
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.mainItem{
|
||||
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.mainItem input[type=text] {
|
||||
/*border: 2px solid ;*/
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mainItem input[type=password] {
|
||||
/*border: 2px solid ;*/
|
||||
border-radius: 4px;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<!-- ideally, this page would be the tempalte for all user types, admin -->
|
||||
<!-- user, trader etc. this home page will defines the common html structure-->
|
||||
<!-- among differnet user page -->
|
||||
|
||||
|
||||
<!-- use ui-view to display header,sidebar and main content of differnet types -->
|
||||
<!-- this would the common layout, header, siderbar, main -->
|
||||
<!-- the actual content and logic within will be managed by -->
|
||||
<!-- seperate controller,css, html files -->
|
||||
|
||||
<div ui-view="header"></div>
|
||||
<div ui-view="sidebar"></div>
|
||||
<div ui-view="main"></div>
|
|
@ -1,18 +0,0 @@
|
|||
app.controller('homeCtrl', function($scope) {
|
||||
|
||||
// $stateProvider.state('contacts', {
|
||||
// template: '<h1>My Contacts</h1>'
|
||||
// }) $scope.username = "user";
|
||||
$scope.controllby = "home";
|
||||
|
||||
// $rootScope.userType = "admin";
|
||||
// $scope.getViewByUserType = function(){
|
||||
// return {
|
||||
// '': {templateUrl: 'pages/home/home.html',controller:'adminCtrl'}, // default view
|
||||
// 'header@home-admin': {templateUrl:'pages/admin/header.admin.html'}, // nested view
|
||||
// 'sidebar@home-admin': {templateUrl:'pages/admin/sidebar.admin.html'},
|
||||
// 'main@home-admin': {templateUrl:'pages/admin/main.admin.html'},
|
||||
// }
|
||||
// }
|
||||
// $scope.header = "i m not a header";
|
||||
});
|
|
@ -1,69 +0,0 @@
|
|||
<nav class="navbar fixed-top navbar-light bg-faded">
|
||||
|
||||
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">Navbar</a>
|
||||
<div class="collapse navbar-collapse" id="navbarNavDropdown">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Features</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Pricing</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Dropdown link
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container-fluid">
|
||||
<div class="row justify-content-center">
|
||||
<!-- Fluid Gird, this login box stay in the middle of screen -->
|
||||
<div class="col-5">
|
||||
|
||||
<div class="mainSection" ng-controller="loginCtrl">
|
||||
<div class="row">
|
||||
<div class="col-3 mainItem">
|
||||
Username/Email
|
||||
</div>
|
||||
|
||||
<div class="col mainItem">
|
||||
<input type="text" ng-model="username" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-3 mainItem">
|
||||
Password
|
||||
</div>
|
||||
|
||||
<div class="col mainItem">
|
||||
<input type="password" ng-model="password" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mainItem">
|
||||
<button type="button" class="btn btn-primary" ng-click="signin()"> S2ign I1n </button>
|
||||
|
||||
<button type="button" class="btn btn-danger" ng-click="createAccount()">Create an account
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div><!-- Container fluid-->
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
app.controller('loginCtrl', function($scope,$state,$http,$rootScope,authService) {
|
||||
/* login variables */
|
||||
$scope.username = "user";
|
||||
$scope.password = "Doe";
|
||||
$scope.fullName = function() {
|
||||
return $scope.firstName + " " + $scope.lastName;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// 1. send request to server to authenticate login information
|
||||
// 2. on succeed, redirect to page
|
||||
// 2.1 on failed, display error message
|
||||
$scope.signin = function(){
|
||||
var foodloop_token_url_login = "http://192.168.2.172:3000/login";
|
||||
var loginData = JSON.stringify({
|
||||
email : this.username,
|
||||
password: this.password
|
||||
});
|
||||
console.log("Attempting to login in");
|
||||
|
||||
$http.post(foodloop_token_url_login,loginData).success(function(repsonse){
|
||||
console.log("Resolving response from server");
|
||||
console.log(repsonse.data);
|
||||
},function(repsonse){
|
||||
console.log("Ooops, Something went wrong");
|
||||
});
|
||||
authService.setUsername($scope.username);
|
||||
// $state.go("user");
|
||||
// if($scope.username === "admin"){
|
||||
// $state.go('admin');
|
||||
// }
|
||||
// else if($scope.username === "user"){
|
||||
// $state.go('user');
|
||||
// }
|
||||
// else{
|
||||
// $state.go('home');
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
$scope.createAccount = function(){
|
||||
|
||||
console.log("Create account button clicked");
|
||||
}
|
||||
|
||||
});
|
|
@ -1,7 +0,0 @@
|
|||
{"objects":[
|
||||
{"circle":{"coordinates":[54.0472, -2.8018]}},
|
||||
{"circle":{"coordinates":[-41.29,174.76]}},
|
||||
{"circle":{"coordinates":[-41.30,174.79]}},
|
||||
{"circle":{"coordinates":[-41.27,174.80]}},
|
||||
{"circle":{"coordinates":[-41.29,174.78]}}
|
||||
]}
|
|
@ -1,3 +0,0 @@
|
|||
#mapid { height: 180px; }
|
||||
|
||||
#map { width:600px; height: 600px }
|
|
@ -1,15 +0,0 @@
|
|||
<div id="map" style="width: 100%; height: 400px"></div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<button class="btn btn-secondary btn-block" type="button">Track my spent</button>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search for...">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-secondary" type="button">Go!</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,61 +0,0 @@
|
|||
app.controller('mapCtrl',function($scope,$http,uploadReceiptService) {
|
||||
|
||||
|
||||
// data
|
||||
var traderGeoData = [
|
||||
{ Latitude:54.04,Longitude:2.80,trader:"sample_1" },
|
||||
{ Latitude:54.04,Longitude:2.80,trader:"sample_2" },
|
||||
{ Latitude:54.01,Longitude:2.78,trader:"sample_3" },
|
||||
];
|
||||
|
||||
var map = L.map('map').setView([54.0472, -2.8018], 13);
|
||||
mapLink =
|
||||
'<a href="http://openstreetmap.org">OpenStreetMap</a>';
|
||||
L.tileLayer(
|
||||
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© ' + mapLink + ' Contributors',
|
||||
maxZoom: 18,
|
||||
}).addTo(map);
|
||||
|
||||
var svgLayer = L.svg();
|
||||
svgLayer.addTo(map);
|
||||
|
||||
var svg = d3.select("#map").select("svg");
|
||||
var g = d3.select("#map").select("svg").select('g');
|
||||
g.attr("class", "leaflet-zoom-hide");
|
||||
|
||||
|
||||
/* We simply pick up the SVG from the map object */
|
||||
var svg = d3.select("#map").select("svg"),
|
||||
g = svg.append("g");
|
||||
|
||||
d3.json("../pages/map/circles.json", function(collection) {
|
||||
/* Add a LatLng object to each item in the dataset */
|
||||
collection.objects.forEach(function(d) {
|
||||
d.LatLng = new L.LatLng(d.circle.coordinates[0],
|
||||
d.circle.coordinates[1])
|
||||
})
|
||||
|
||||
var feature = g.selectAll("circle")
|
||||
.data(collection.objects)
|
||||
.enter().append("circle")
|
||||
.style("stroke", "black")
|
||||
.style("opacity", .6)
|
||||
.style("fill", "red")
|
||||
.attr("r", 20);
|
||||
|
||||
map.on("viewreset", update);
|
||||
update();
|
||||
|
||||
function update() {
|
||||
console.log("update!");
|
||||
feature.attr("transform",
|
||||
function(d) {
|
||||
return "translate("+
|
||||
map.latLngToLayerPoint(d.LatLng).x +","+
|
||||
map.latLngToLayerPoint(d.LatLng).y +")";
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
|
@ -1,108 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
<form>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
<div class="pearCard">
|
||||
<div class="pearCardHeader .pearGreen">Fill in to submit </div>
|
||||
<div class="padding16">
|
||||
<!-- from group start -->
|
||||
<div class="form-group row">
|
||||
<label for="example-text-input" class="col-2 col-form-label">Store name</label>
|
||||
<div class="col">
|
||||
<input class="form-control" type="text" ng-model="storename" placeholder="e.g. Three" id="example-text-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col">
|
||||
<div class="searchList">
|
||||
<ul class="list-group" ng-repeat="store in storeList">
|
||||
<li class="list-group-item ">{{store.store_id}}</li>
|
||||
<li class="list-group-item ">{{store.store_name}}</li>
|
||||
<li class="list-group-item ">{{store.store_address}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="example-search-input" class="col-2 col-form-label">amount</label>
|
||||
<div class="col">
|
||||
<input class="form-control" type="decimal" ng-model="amount" placeholder="e.g. 6.66" id="example-search-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row justify-content-center">
|
||||
<label for="example-email-input" class="col col-form-label">Image(Click 'Add' button or Drag an image into the box below)</label>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input type='file' ng-model ="receiptPhoto" accept="image/*"
|
||||
onchange="angular.element(this).scope().getImage(this)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="dragImageBox">
|
||||
<div class="row no-gutters">
|
||||
<img class="col-2 thumb" ng-src="{{receiptPhotoSrc}}"/>
|
||||
<!-- image details, progress bar etc. -->
|
||||
<div class="col-5 thumb">
|
||||
filename:{{receiptPhoto.filename}}<br> filesize:{{receiptPhoto.filesize}}<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="pearCardFooter">
|
||||
<button type="button" ng-click="uploadReceipt()" class="btn btn-primary"> Submit </button>
|
||||
<button type="button" class="btn btn-danger"> Reset </button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- from group end -->
|
||||
</div>
|
||||
<!-- PADDING -->
|
||||
</div>
|
||||
<!-- pear card -->
|
||||
</div>
|
||||
<!-- first col-5 -->
|
||||
|
||||
<div class="col">
|
||||
<div class="pearCard">
|
||||
<div class="pearCardHeader pearOrange"> Pending receipt
|
||||
<span class="badge badge-info">5 </span> </div>
|
||||
<!-- content start here -->
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>When</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="receipt in pending_list">
|
||||
<td>{{$index + 1}}</td>
|
||||
<td>{{receipt.submitted_time}}</td>
|
||||
<td>{{receipt.submitted_amount}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- second col -->
|
||||
</div>
|
||||
<!-- first row-->
|
||||
|
||||
|
||||
|
||||
</main>
|
|
@ -1,62 +0,0 @@
|
|||
app.controller('receiptCtrl',function($scope,$http,uploadReceiptService) {
|
||||
|
||||
// display the list of all exsiting store, validated and not validated
|
||||
$scope.storelist;
|
||||
|
||||
// require param for upload api
|
||||
$scope.microCurrencyValue;
|
||||
$scope.transactionAdditionType;
|
||||
$scope.addValidatedId;
|
||||
|
||||
$scope.storename;
|
||||
|
||||
// photo and path to the photo
|
||||
$scope.receiptPhoto;
|
||||
$scope.receiptPhotoSrc;
|
||||
|
||||
// list of pending reciepts await for approval from admin
|
||||
$scope.pending_list = [
|
||||
{submitted_time: 30 },{submitted_time:20},{submitted_time:10},{submitted_time:5},{submitted_time:1}
|
||||
];
|
||||
|
||||
|
||||
var foodloop_token_url_search = "http://192.168.2.172:3000/search";
|
||||
|
||||
|
||||
// get the latest store list
|
||||
$scope.getStoreList = function(){
|
||||
var data = {
|
||||
"searchName": "",
|
||||
"searchLocation": ""
|
||||
};
|
||||
$http.post(foodloop_token_url_search,data).then(function(response){
|
||||
console.log(response);
|
||||
});
|
||||
|
||||
// API call to /search to fetch a list of store
|
||||
}
|
||||
|
||||
$scope.storelist = $scope.getStoreList();
|
||||
|
||||
// select the image
|
||||
$scope.getImage = function(element) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(event) {
|
||||
$scope.$apply(function($scope) {
|
||||
$scope.receiptPhoto = element.files[0];
|
||||
$scope.receiptPhotoSrc = event.target.result
|
||||
});
|
||||
}
|
||||
reader.readAsDataURL(element.files[0]);
|
||||
}
|
||||
|
||||
// upload the receipt to the server
|
||||
$scope.uploadReceipt = function(){
|
||||
uploadReceiptService.uploadReceipt();
|
||||
}
|
||||
|
||||
|
||||
// test
|
||||
// firebase api to upload an image
|
||||
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse" style="background-color:#0091EA;">
|
||||
<button class="navbar-toggler navbar-toggler-right hidden-lg-up" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">FoodLoop</a>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Help</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline mt-2 mt-md-0">
|
||||
<input class="form-control mr-sm-2" type="text" placeholder="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
|
@ -1,6 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
<div id="layouter">
|
||||
i m the main content in trader page
|
||||
</div>
|
||||
<!-- Layouter -->
|
||||
</main>
|
|
@ -1,44 +0,0 @@
|
|||
<!-- This page defines a side bar for admin -->
|
||||
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Admin Portal <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Add User</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Add Trader</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Sign out</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav nav-pills flex-column" id="meq">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Receipt Management</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">View receipt</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Option 2</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Option 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Nav item again</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">One more nav</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Another nav item</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
|
@ -1,15 +0,0 @@
|
|||
app.controller('traderCtrl', function($scope,$location) {
|
||||
|
||||
$scope.content = "I am not a header";
|
||||
$scope.headerContent = "FoodLoop Admin Portal";
|
||||
|
||||
|
||||
/* This block of code handles recepit management */
|
||||
$scope.receiptNumber = 0;
|
||||
|
||||
|
||||
/* This block of code handles user management */
|
||||
/* Including the management of registered user, trader */
|
||||
$scope.registeredUsers = 1;
|
||||
|
||||
});
|
|
@ -1,24 +0,0 @@
|
|||
<nav class="navbar navbar-toggleable-md fixed-top navbar-inverse" style="background-color:#0091EA;">
|
||||
<button class="navbar-toggler navbar-toggler-right hidden-lg-up" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#">FoodLoop</a>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" ui-sref="user">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" ui-sref=".settings">Settings</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href=".help">Help</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline mt-2 mt-md-0">
|
||||
<input class="form-control mr-sm-2" type="text" placeholder="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
|
@ -1,28 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Position</th>
|
||||
<th>Name</th>
|
||||
<th>Pear points</th>
|
||||
<th>Retailers spent with</th>
|
||||
<th>Receipt submitted</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="user in leaderboard">
|
||||
<td>{{$index + 1}}</td>
|
||||
<td>{{user.name}}</td>
|
||||
<td>{{user.pear_points}}</td>
|
||||
<td>{{user.retailer_spent}}</td>
|
||||
<td>{{user.receipt_submitted}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- col -->
|
||||
</div>
|
||||
<!-- row first -->
|
||||
</main>
|
|
@ -1,21 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="pearCard pearAutoHeight">
|
||||
<div class="pearCardHeader"> Personal details </div>
|
||||
<div class="pearCardContent">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-2">
|
||||
<label>Username</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
<input type="text" placeholder="{{username}}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- col -->
|
||||
</div>
|
||||
<!-- row first -->
|
||||
</main>
|
|
@ -1,90 +0,0 @@
|
|||
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 pt-3">
|
||||
<!--display my ranking -->
|
||||
<div class="row">
|
||||
|
||||
<div class="col-3">
|
||||
<div class="flCard">
|
||||
<div class="flCardHeader">
|
||||
<div class="title">Rank</div>
|
||||
</div>
|
||||
<div class="flCardMain"> 1 </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<div class="flCard">
|
||||
<div class="flCardHeader">Points</div>
|
||||
<div class="flCardMain"> 888 </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<div class="flCard">
|
||||
<div class="flCardHeader">Spend</div>
|
||||
<div class="flCardMain"> £100 </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-3">
|
||||
<div class="flCard">
|
||||
<div class="flCardHeader">Re-spend</div>
|
||||
<div class="flCardMain"> £5.00 </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- first row end -->
|
||||
|
||||
<div class="row">
|
||||
|
||||
|
||||
<div class="col-3">
|
||||
<div class="pearCard margin16">
|
||||
<div class="pearCardHeader"> My receipt </div>
|
||||
<div class="receiptItem">
|
||||
Pending receipt <span class="badge badge-danger">5</span>
|
||||
</div>
|
||||
<div class="receiptItem">
|
||||
Submit a receipt
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-5">
|
||||
<div class="pearCard margin16">
|
||||
<div class="pearCardHeader"> Personal overview </div>
|
||||
<flChart> </flChart>
|
||||
<canvas id="myChart"></canvas>
|
||||
</div>
|
||||
<!-- flCard-->
|
||||
</div>
|
||||
<!-- col-5 receipt-->
|
||||
|
||||
<div class="col">
|
||||
<div class="pearCard margin16">
|
||||
<div class="pearCardHeader"> Top players of the month </div>
|
||||
<div class="rankCardContent">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Username</th>
|
||||
<th>Points</th>
|
||||
<th>Receipts submitted</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- col for pending receipt -->
|
||||
</div>
|
||||
<!-- row -->
|
||||
<!--<button ng-click="displayChart()"> Hit me </button>-->
|
||||
</main>
|
|
@ -1,30 +0,0 @@
|
|||
<!-- This page defines a side bar for admin -->
|
||||
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
|
||||
|
||||
<!--<div class="row no-gutters">
|
||||
<div class="col-5">
|
||||
<div class="profilePic">
|
||||
<img src="../../pages/user/icon1.png" class="profile-pic">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="profileInfo">
|
||||
<h6>{{username}}</h6>
|
||||
<div class="profileTitle">{{email}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
<ul class="nav nav-pills flex-column" id="meq">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="#">Key features</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" ui-sref=".receipt">Submit a receipt</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" ui-sref=".leaderboard">View Leaderboard</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</nav>
|
|
@ -1,3 +0,0 @@
|
|||
<user-header> </user-header>
|
||||
<user-sidebar> </user-sidebar>
|
||||
<user-main> </user-main>
|
|
@ -1,65 +0,0 @@
|
|||
app.controller('userCtrl', function($scope,$location) {
|
||||
$scope.user_rank = 1;
|
||||
$scope.controllby = "user";
|
||||
$scope.username = "John Smith";
|
||||
$scope.email = "test007@test.com";
|
||||
$scope.createChart = function(){
|
||||
var ctx = document.getElementById("myChart");
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
|
||||
datasets: [{
|
||||
label: '# of Votes',
|
||||
data: [12, 19, 3, 5, 2, 3],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.2)',
|
||||
'rgba(54, 162, 235, 0.2)',
|
||||
'rgba(255, 206, 86, 0.2)',
|
||||
'rgba(75, 192, 192, 0.2)',
|
||||
'rgba(153, 102, 255, 0.2)',
|
||||
'rgba(255, 159, 64, 0.2)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255,99,132,1)',
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 206, 86, 1)',
|
||||
'rgba(75, 192, 192, 1)',
|
||||
'rgba(153, 102, 255, 1)',
|
||||
'rgba(255, 159, 64, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero:true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.displayChart = function(){
|
||||
// chart sample
|
||||
var flData = [{x: 100, y: 100}, {x: 200, y: 200}, {x: 300, y: 300}];
|
||||
var svg = d3.select("flChart").append("svg")
|
||||
.attr("width","300px").attr("height","300px");
|
||||
svg
|
||||
.selectAll("circle").data(flData)
|
||||
.enter().append("circle")
|
||||
.attr("cx", function(d) { return d.x; })
|
||||
.attr("cy", function(d) { return d.y; })
|
||||
.attr("r", 2.5);
|
||||
|
||||
console.log(svg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
30
protractor.conf.js
Normal file
30
protractor.conf.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
beforeLaunch: function() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
},
|
||||
onPrepare() {
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
|
@ -1,14 +0,0 @@
|
|||
/* this service handles all the authentication between client and server */
|
||||
app.service('authService', function ($http) {
|
||||
// send a login information to server
|
||||
// upon success, set sessionToken and store data in dataService
|
||||
// upon failed, return error
|
||||
this.username = "";
|
||||
this.getUsername = function(){
|
||||
return this.username;
|
||||
}
|
||||
|
||||
this.setUsername = function(setTo){
|
||||
this.username = setTo;
|
||||
}
|
||||
});
|
|
@ -1,56 +0,0 @@
|
|||
/* this service handles all the authentication between client and server */
|
||||
app.service('chartService', function () {
|
||||
// send a login information to server
|
||||
// upon success, set sessionToken and store data in dataService
|
||||
// upon failed, return error
|
||||
this.username = "";
|
||||
this.getUsername = function(){
|
||||
return this.username;
|
||||
}
|
||||
|
||||
this.setUsername = function(setTo){
|
||||
this.username = setTo;
|
||||
}
|
||||
|
||||
|
||||
this.createChart = function(){
|
||||
var ctx = document.getElementById("myChart");
|
||||
var myChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
|
||||
datasets: [{
|
||||
label: '# of Votes',
|
||||
data: [12, 19, 3, 5, 2, 3],
|
||||
backgroundColor: [
|
||||
'rgba(255, 99, 132, 0.2)',
|
||||
'rgba(54, 162, 235, 0.2)',
|
||||
'rgba(255, 206, 86, 0.2)',
|
||||
'rgba(75, 192, 192, 0.2)',
|
||||
'rgba(153, 102, 255, 0.2)',
|
||||
'rgba(255, 159, 64, 0.2)'
|
||||
],
|
||||
borderColor: [
|
||||
'rgba(255,99,132,1)',
|
||||
'rgba(54, 162, 235, 1)',
|
||||
'rgba(255, 206, 86, 1)',
|
||||
'rgba(75, 192, 192, 1)',
|
||||
'rgba(153, 102, 255, 1)',
|
||||
'rgba(255, 159, 64, 1)'
|
||||
],
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero:true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
/* this service handles receipt upload process */
|
||||
app.service('uploadReceiptService', function () {
|
||||
this.uploadReceipt = function(){
|
||||
console.log("Upload successful");
|
||||
}
|
||||
});
|
21
src/app/_guards/auth.guard.ts
Normal file
21
src/app/_guards/auth.guard.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuard implements CanActivate {
|
||||
|
||||
constructor(private router: Router) { }
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
if (localStorage.getItem('sessionKey')) {
|
||||
console.log('session key found')
|
||||
// logged in so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// not logged in so redirect to login page with the return url
|
||||
console.log('no session key found')
|
||||
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
|
||||
return false;
|
||||
}
|
||||
}
|
21
src/app/_guards/customer.guard.ts
Normal file
21
src/app/_guards/customer.guard.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
|
||||
@Injectable()
|
||||
export class CustomerGuard implements CanActivate {
|
||||
|
||||
constructor(private router: Router) { }
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
if (localStorage.getItem('usertype') == 'customer') {
|
||||
console.log('Customer logged in')
|
||||
// customer logged in so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// customer not logged in so redirect to org dashboard
|
||||
console.log('not an customer')
|
||||
this.router.navigate(['/dashboard']);
|
||||
return false;
|
||||
}
|
||||
}
|
21
src/app/_guards/org.guard.ts
Normal file
21
src/app/_guards/org.guard.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||
|
||||
@Injectable()
|
||||
export class OrgGuard implements CanActivate {
|
||||
|
||||
constructor(private router: Router) { }
|
||||
|
||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||
if (localStorage.getItem('usertype') == 'organisation') {
|
||||
console.log('Organisation logged in')
|
||||
// org logged in so return true
|
||||
return true;
|
||||
}
|
||||
|
||||
// org not logged in so redirect to customer dashboard
|
||||
console.log('not an organisation')
|
||||
this.router.navigate(['/dashboard-customer']);
|
||||
return false;
|
||||
}
|
||||
}
|
44
src/app/app.component.spec.ts
Normal file
44
src/app/app.component.spec.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
// Items under test
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
let fixture: ComponentFixture<AppComponent>;
|
||||
let app: AppComponent;
|
||||
let de: DebugElement;
|
||||
let appDocument: any;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed
|
||||
.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
RouterTestingModule.withRoutes(
|
||||
[{path: '', component: AppComponent}]
|
||||
)
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AppComponent);
|
||||
app = fixture.componentInstance;
|
||||
de = fixture.debugElement;
|
||||
appDocument = de.nativeElement;
|
||||
});
|
||||
|
||||
it('should create the app', async(() => {
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('should have a router-outlet', async(() => {
|
||||
expect(appDocument.querySelector('router-outlet')).toBeTruthy();
|
||||
}));
|
||||
});
|
7
src/app/app.component.ts
Normal file
7
src/app/app.component.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
template: '<router-outlet></router-outlet>'
|
||||
})
|
||||
export class AppComponent { }
|
71
src/app/app.module.ts
Normal file
71
src/app/app.module.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
|
||||
import { HttpModule } from '@angular/http';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
|
||||
import { TabsModule } from 'ngx-bootstrap/tabs';
|
||||
import { NAV_DROPDOWN_DIRECTIVES } from './shared/nav-dropdown.directive';
|
||||
|
||||
import { SIDEBAR_TOGGLE_DIRECTIVES } from './shared/sidebar.directive';
|
||||
import { AsideToggleDirective } from './shared/aside.directive';
|
||||
import { BreadcrumbsComponent } from './shared/breadcrumb.component';
|
||||
|
||||
// Routing & Guard Module
|
||||
import { AppRoutingModule } from './app.routing';
|
||||
import { AuthGuard } from './_guards/auth.guard';
|
||||
import { OrgGuard } from './_guards/org.guard';
|
||||
import { CustomerGuard } from './_guards/customer.guard';
|
||||
import { ApiService } from './providers/api-service';
|
||||
|
||||
import { OrgGraphsService } from './providers/org-graphs.service';
|
||||
|
||||
// Layouts
|
||||
import { FullLayoutComponent } from './layouts/full-layout.component';
|
||||
import { SimpleLayoutComponent } from './layouts/simple-layout.component';
|
||||
|
||||
// Error Pages
|
||||
import { P404Component } from './pages/404.component';
|
||||
import { P500Component } from './pages/500.component';
|
||||
|
||||
// Submodules
|
||||
import { AuthModule } from './auth/auth.module';
|
||||
import { DashboardModule } from './dashboard/dashboard.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
HttpModule,
|
||||
BsDropdownModule.forRoot(),
|
||||
TabsModule.forRoot(),
|
||||
AuthModule,
|
||||
DashboardModule,
|
||||
// Loaded last to allow for 404 catchall
|
||||
AppRoutingModule,
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
FullLayoutComponent,
|
||||
SimpleLayoutComponent,
|
||||
NAV_DROPDOWN_DIRECTIVES,
|
||||
BreadcrumbsComponent,
|
||||
SIDEBAR_TOGGLE_DIRECTIVES,
|
||||
AsideToggleDirective,
|
||||
P404Component,
|
||||
P500Component,
|
||||
],
|
||||
providers: [
|
||||
AuthGuard,
|
||||
OrgGuard,
|
||||
CustomerGuard,
|
||||
ApiService,
|
||||
OrgGraphsService,
|
||||
{
|
||||
provide: LocationStrategy,
|
||||
useClass: HashLocationStrategy
|
||||
}
|
||||
],
|
||||
bootstrap: [ AppComponent ]
|
||||
})
|
||||
export class AppModule { }
|
17
src/app/app.routing.ts
Normal file
17
src/app/app.routing.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { P404Component } from './pages/404.component';
|
||||
import { P500Component } from './pages/500.component';
|
||||
|
||||
export const routes: Routes = [
|
||||
{ path: '404', component: P404Component },
|
||||
{ path: '500', component: P500Component },
|
||||
{ path: '**', redirectTo: '/404' },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {}
|
21
src/app/auth/auth.module.ts
Normal file
21
src/app/auth/auth.module.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
import { RegisterComponent } from './register.component';
|
||||
import { AuthRoutingModule } from './auth.routing';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
AuthRoutingModule,
|
||||
],
|
||||
declarations: [
|
||||
LoginComponent,
|
||||
RegisterComponent,
|
||||
]
|
||||
})
|
||||
export class AuthModule {}
|
15
src/app/auth/auth.routing.ts
Normal file
15
src/app/auth/auth.routing.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { LoginComponent } from './login.component';
|
||||
import { RegisterComponent } from './register.component';
|
||||
|
||||
const authRoutes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: 'register', component: RegisterComponent },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forChild(authRoutes) ],
|
||||
exports: [ RouterModule ],
|
||||
})
|
||||
export class AuthRoutingModule {}
|
53
src/app/auth/login.component.html
Normal file
53
src/app/auth/login.component.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<div class="app flex-row align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card-group mb-0">
|
||||
<div class="card p-4">
|
||||
<div class="card-block">
|
||||
<h1>Login</h1>
|
||||
<p class="text-muted">Sign In to your account</p>
|
||||
<form [formGroup]="signin" (ngSubmit)="onSubmit()">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon">@</span>
|
||||
<input id="username" type="text" class="form-control" formControlName="email" placeholder="Email">
|
||||
</div>
|
||||
<div class="input-group mb-4">
|
||||
<span class="input-group-addon"><i class="icon-lock"></i></span>
|
||||
<input id="password" type="password" class="form-control" formControlName="password" placeholder="Password">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<div [ngSwitch]="loginStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Login Succeeded, routing to homepage.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Error received, please try again.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button type="submit" [disabled]="!signin.valid" class="btn btn-primary px-4">Login</button>
|
||||
</div>
|
||||
<div class="col-6 text-right">
|
||||
<button type="button" class="btn btn-link px-0">Forgot password?</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card card-inverse card-primary py-5 d-md-down-none" style="width:44%">
|
||||
<div class="card-block text-center">
|
||||
<div>
|
||||
<h2>Sign up</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
|
||||
<button type="button" class="btn btn-primary active mt-3" routerLinkActive="active" [routerLink]="['/register']">Register Now!</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
70
src/app/auth/login.component.ts
Normal file
70
src/app/auth/login.component.ts
Normal file
|
@ -0,0 +1,70 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'login.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
signin: FormGroup;
|
||||
returnUrl: string;
|
||||
loginStatus: any;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private http: Http,
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private api: ApiService
|
||||
) {
|
||||
this.signin = this.formBuilder.group({
|
||||
email: ['', [Validators.required]],
|
||||
password: ['', [Validators.required]],
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
// reset login status
|
||||
this.api
|
||||
.logout()
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('Logged out!');
|
||||
localStorage.clear();
|
||||
}
|
||||
);
|
||||
|
||||
this.api.graph_data(undefined).subscribe(
|
||||
result => { console.log(result) }
|
||||
)
|
||||
|
||||
// get return url from route parameters or default to '/'
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
console.log(this.signin.value);
|
||||
|
||||
this.api
|
||||
.login(this.signin.value)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('logged in!');
|
||||
this.loginStatus = "success";
|
||||
console.log(this.loginStatus);
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.loginStatus = "send_failed";
|
||||
console.log(this.loginStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
148
src/app/auth/register.component.html
Normal file
148
src/app/auth/register.component.html
Normal file
|
@ -0,0 +1,148 @@
|
|||
<div class="app flex-row align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card mx-4">
|
||||
<div class="card-block p-4">
|
||||
<h1>Register</h1>
|
||||
<p class="text-muted">Create your account</p>
|
||||
|
||||
<!-- <div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-people"></i></span>
|
||||
<select required class="form-control" type="text" formControlName="usertype">
|
||||
<option value=''>Please select</option>
|
||||
<option value='organisation'>Organisation</option>
|
||||
<option value='customer'>Customer</option>
|
||||
</select>
|
||||
</div> -->
|
||||
<form [formGroup]="signupForm.getForm()">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-key"></i></span>
|
||||
<input type="text" class="form-control" formControlName="token" placeholder="Token">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon">@</span>
|
||||
<input type="text" class="form-control" formControlName="email" placeholder="Email">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-lock"></i></span>
|
||||
<input type="password" class="form-control" formControlName="password" placeholder="Password">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-4">
|
||||
<span class="input-group-addon"><i class="icon-lock"></i></span>
|
||||
<input type="password" class="form-control" formControlName="confirmpassword" placeholder="Repeat password">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-people"></i></span>
|
||||
<select required class="form-control" type="text" formControlName="usertype">
|
||||
<option value=''>Please select</option>
|
||||
<option value='organisation'>Organisation</option>
|
||||
<option value='customer'>Customer</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div [ngSwitch]="signupForm.getForm().value.usertype">
|
||||
<div *ngSwitchCase="'customer'" >
|
||||
<form [formGroup]="customerForm.getForm()" (ngSubmit)="onSubmitCustomer()">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="display_name" placeholder="Display Name">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="full_name" placeholder="Full Name">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="postcode" placeholder="Postcode">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon">Year of Birth</span>
|
||||
<select class="form-control" type="text" formControlName="year_of_birth">
|
||||
<option *ngFor="let range of years" [value]="range">{{ range }}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-block btn-success">Create Account</button>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngSwitchCase="'organisation'">
|
||||
<form [formGroup]="organisationForm.getForm()" (ngSubmit)="onSubmitOrganisation()">
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="name" placeholder="Organisation Name">
|
||||
</div>
|
||||
|
||||
<!-- Uses the UK SIC 2007 classifications for sector as used by ONS -->
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<select required class="form-control" type="text" formControlName="sector">
|
||||
<option value=''>Select Organisation Sector</option>
|
||||
<option value='A'>Agriculture, Forestry & Fishing</option>
|
||||
<option value='B'>Mining & Quarrying</option>
|
||||
<option value='C'>Manufacturing</option>
|
||||
<option value='D'>Electricity, Gas, Steam & Air Conditioning</option>
|
||||
<option value='E'>Water & Waste Management</option>
|
||||
<option value='F'>Construction</option>
|
||||
<option value='G'>Wholesale & Retail Trade</option>
|
||||
<option value='H'>Transportation & Storage</option>
|
||||
<option value='I'>Accomodation & Food Services</option>
|
||||
<option value='J'>Information & Communication</option>
|
||||
<option value='K'>Financial & Insurance Activities</option>
|
||||
<option value='L'>Real Estate</option>
|
||||
<option value='M'>Professional, Scientfic & Technical</option>
|
||||
<option value='N'>Administrative & Support Services</option>
|
||||
<option value='O'>Public Administration, Defence & Social Security</option>
|
||||
<option value='P'>Education</option>
|
||||
<option value='Q'>Human Health & Social Work</option>
|
||||
<option value='R'>Arts, Entertainment & Recreation</option>
|
||||
<option value='S'>Other Service Activities</option>
|
||||
<option value='T'>Household Domestic Business</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="street_name" placeholder="Street Name">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="town" placeholder="Town">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<span class="input-group-addon"><i class="icon-user"></i></span>
|
||||
<input type="text" class="form-control" formControlName="postcode" placeholder="Postcode">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-block btn-success">Create Account</button>
|
||||
</form>
|
||||
</div>
|
||||
<div heading="Pending" *ngSwitchDefault>Please Select a User Type</div>
|
||||
</div>
|
||||
<div class="mb-3" [ngSwitch]="registerStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Register Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'validation_failed'" class="alert alert-danger" role="alert">
|
||||
Form validation failed, please ensure the form is filled correctly.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Failed to send to server, please try again later.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
137
src/app/auth/register.component.ts
Normal file
137
src/app/auth/register.component.ts
Normal file
|
@ -0,0 +1,137 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { ValidationManager } from "ng2-validation-manager";
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import {Router } from '@angular/router';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'register.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
|
||||
export class RegisterComponent {
|
||||
signupForm: ValidationManager;
|
||||
customerForm: ValidationManager;
|
||||
organisationForm: ValidationManager;
|
||||
years: Object[];
|
||||
registerStatus: any;
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.years = [];
|
||||
let max = new Date().getFullYear() - 10,
|
||||
min = max - 140;
|
||||
|
||||
for (let i = max; i>=min; i--){
|
||||
this.years.push(i);
|
||||
}
|
||||
this.signupForm = new ValidationManager({
|
||||
token: 'required',
|
||||
usertype: 'required',
|
||||
email: 'required|email',
|
||||
password: 'required',
|
||||
confirmpassword: 'required|equalTo:password'
|
||||
});
|
||||
this.customerForm = new ValidationManager({
|
||||
display_name: 'required',
|
||||
full_name: 'required',
|
||||
postcode: 'required',
|
||||
year_of_birth:'required',
|
||||
});
|
||||
this.organisationForm = new ValidationManager({
|
||||
name: 'required',
|
||||
sector: 'required',
|
||||
street_name: 'required',
|
||||
town: 'required',
|
||||
postcode: 'required',
|
||||
});
|
||||
}
|
||||
|
||||
onSubmitCustomer() {
|
||||
|
||||
console.log(this.signupForm.isValid());
|
||||
if (!this.signupForm.isValid() && !this.customerForm.isValid()) {
|
||||
console.log("Not Valid!");
|
||||
this.registerStatus = "validation_failed";
|
||||
console.log(this.registerStatus);
|
||||
return;
|
||||
}
|
||||
let signupForm = this.signupForm.getForm().value;
|
||||
let customerForm = this.customerForm.getForm().value;
|
||||
|
||||
let data = {
|
||||
token: signupForm.token,
|
||||
usertype: signupForm.usertype,
|
||||
email: signupForm.email,
|
||||
password: signupForm.password,
|
||||
display_name: customerForm.display_name,
|
||||
full_name: customerForm.full_name,
|
||||
postcode: customerForm.postcode,
|
||||
year_of_birth:customerForm.year_of_birth,
|
||||
};
|
||||
console.log(data);
|
||||
this.api
|
||||
.register(data)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('registered!');
|
||||
this.registerStatus = "success";
|
||||
console.log(this.registerStatus);
|
||||
this.router.navigate(['/dashboard']);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.registerStatus = "send_failed";
|
||||
console.log(this.registerStatus)
|
||||
}
|
||||
);
|
||||
}
|
||||
onSubmitOrganisation() {
|
||||
|
||||
console.log(this.signupForm.isValid());
|
||||
if (!this.signupForm.isValid() || !this.organisationForm.isValid()) {
|
||||
console.log("Not Valid!");
|
||||
this.registerStatus = "validation_failed";
|
||||
console.log(this.registerStatus);
|
||||
return;
|
||||
}
|
||||
let signupForm = this.signupForm.getForm().value;
|
||||
let organisationForm = this.organisationForm.getForm().value;
|
||||
|
||||
let data = {
|
||||
token: signupForm.token,
|
||||
usertype: signupForm.usertype,
|
||||
email: signupForm.email,
|
||||
password: signupForm.password,
|
||||
name: organisationForm.name,
|
||||
sector: organisationForm.sector,
|
||||
street_name: organisationForm.street_name,
|
||||
town: organisationForm.town,
|
||||
postcode: organisationForm.postcode,
|
||||
};
|
||||
console.log(data);
|
||||
this.api
|
||||
.register(data)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('registered!');
|
||||
this.registerStatus = "success";
|
||||
console.log(this.registerStatus);
|
||||
this.router.navigate(['/dashboard']);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.registerStatus = "send_failed";
|
||||
console.log(this.registerStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
145
src/app/dashboard/account-edit.component.html
Normal file
145
src/app/dashboard/account-edit.component.html
Normal file
|
@ -0,0 +1,145 @@
|
|||
<div class="animated fadeIn">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Update Account Info</strong>
|
||||
<small>Required Data marked in <strong>bold</strong>.</small>
|
||||
</div>
|
||||
<form class="form-horizontal" [formGroup]="settingForm">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Confirm Current Password</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="password" class="form-control" formControlName="password">
|
||||
<span class="help-block">Required for security purposes.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Email</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="email">
|
||||
<span class="help-block">Change this to alter your current account email.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Enter New Password</label>
|
||||
<div class="col-md-9">
|
||||
<input type="password" class="form-control" formControlName="new_password">
|
||||
<span class="help-block">Enter a new password here if you wish to alter your current one.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Postcode</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="postcode">
|
||||
<span class="help-block">Change this if your location of residence has changed.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="file-input">Profile Picture</label>
|
||||
<div class="col-md-9">
|
||||
<input type="file" #fileInput formControlName="profile_picture">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div [ngSwitch]="accountType">
|
||||
<div *ngSwitchCase="'organisation'">
|
||||
<form class="form-horizontal" [formGroup]="settingOrganisationForm" (ngSubmit)="onSubmitOrganisation()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Business Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="name">
|
||||
<span class="help-block">Change this if your business name has changed.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Street Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="street_name">
|
||||
<span class="help-block">Change this if your located street has changed.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>City/Town Location</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="town">
|
||||
<span class="help-block">Change this if the city or town your business is located at has changed.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div [ngSwitch]="submitStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Account Update Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'validation_failed'" class="alert alert-danger" role="alert">
|
||||
Form validation failed, please ensure the form is filled correctly.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Failed to send to server, please try again later.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngSwitchCase="'customer'">
|
||||
<form class="form-horizontal" [formGroup]="settingCustomerForm" (ngSubmit)="onSubmitCustomer()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Full Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="full_name">
|
||||
<span class="help-block">Change this if your full name has changed.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Display Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="display_name">
|
||||
<span class="help-block">Change this if wish to alter your user display name.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div [ngSwitch]="submitStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Account Update Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'validation_failed'" class="alert alert-danger" role="alert">
|
||||
Form validation failed, please ensure the form is filled correctly.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Failed to send to server, please try again later.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.row-->
|
||||
</div>
|
168
src/app/dashboard/account-edit.component.ts
Normal file
168
src/app/dashboard/account-edit.component.ts
Normal file
|
@ -0,0 +1,168 @@
|
|||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'account-edit.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
export class AccountEditComponent implements OnInit {
|
||||
settingForm: FormGroup;
|
||||
settingOrganisationForm: FormGroup;
|
||||
settingCustomerForm: FormGroup;
|
||||
accountType: any;
|
||||
@ViewChild('fileInput') fileInput;
|
||||
submitStatus: any;
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private formBuilder: FormBuilder,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.settingForm = this.formBuilder.group({
|
||||
email : ['', [Validators.required]],
|
||||
postcode : ['', [Validators.required]],
|
||||
password : ['', [Validators.required]],
|
||||
new_password : [''],
|
||||
profile_picture : [''],
|
||||
});
|
||||
this.settingOrganisationForm = this.formBuilder.group({
|
||||
name : ['', [Validators.required]],
|
||||
street_name : ['', [Validators.required]],
|
||||
town : ['', [Validators.required]],
|
||||
});
|
||||
this.settingCustomerForm = this.formBuilder.group({
|
||||
full_name : ['', [Validators.required]],
|
||||
display_name : ['', [Validators.required]],
|
||||
});
|
||||
this.accountType = localStorage.getItem('usertype');
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.api.accountFullLoad().subscribe(
|
||||
result => {
|
||||
console.log(result);
|
||||
this.settingForm.patchValue({
|
||||
email: result.email,
|
||||
postcode: result.postcode,
|
||||
password: '',
|
||||
new_password: '',
|
||||
});
|
||||
this.settingOrganisationForm.patchValue({
|
||||
name: result.name,
|
||||
street_name: result.street_name,
|
||||
town: result.town,
|
||||
});
|
||||
this.settingCustomerForm.patchValue({
|
||||
full_name: result.full_name,
|
||||
display_name: result.display_name,
|
||||
});
|
||||
this.api.setUserInfo( result.email, result.display_name );
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onSubmitOrganisation() {
|
||||
console.log(this.settingForm.valid);
|
||||
if (!this.settingForm.valid && !this.settingOrganisationForm.valid) {
|
||||
console.log('Not Valid!');
|
||||
this.submitStatus = "validation_failed";
|
||||
console.log(this.submitStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
const settingForm = this.settingForm.value;
|
||||
const settingOrganisationForm = this.settingOrganisationForm.value;
|
||||
|
||||
// image upload code
|
||||
const fi = this.fileInput.nativeElement;
|
||||
const data = new FormData();
|
||||
|
||||
if (fi.files && fi.files[0]) {
|
||||
const fileToUpload = fi.files[0];
|
||||
data.append('file', fileToUpload);
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
email: settingForm.email,
|
||||
postcode: settingForm.postcode,
|
||||
password: settingForm.password,
|
||||
new_password: settingForm.new_password,
|
||||
name: settingOrganisationForm.name,
|
||||
street_name: settingOrganisationForm.street_name,
|
||||
town: settingOrganisationForm.town,
|
||||
};
|
||||
|
||||
data.append('form', JSON.stringify(submitData));
|
||||
|
||||
console.log(data);
|
||||
this.api
|
||||
.accountEditUpdate(data)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('data submitted!');
|
||||
this.submitStatus = "success";
|
||||
console.log(this.submitStatus);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.submitStatus = "send_failed";
|
||||
console.log(this.submitStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onSubmitCustomer() {
|
||||
console.log(this.settingForm.valid);
|
||||
if (!this.settingForm.valid && !this.settingCustomerForm.valid) {
|
||||
console.log('Not Valid!');
|
||||
this.submitStatus = "validation_failed";
|
||||
console.log(this.submitStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
const settingForm = this.settingForm.value;
|
||||
const settingCustomerForm = this.settingCustomerForm.value;
|
||||
|
||||
// image upload code
|
||||
const fi = this.fileInput.nativeElement;
|
||||
const data = new FormData();
|
||||
|
||||
if (fi.files && fi.files[0]) {
|
||||
const fileToUpload = fi.files[0];
|
||||
data.append('file', fileToUpload);
|
||||
}
|
||||
|
||||
const submitData = {
|
||||
email: settingForm.email,
|
||||
postcode: settingForm.postcode,
|
||||
password: settingForm.password,
|
||||
new_password: settingForm.new_password,
|
||||
full_name: settingCustomerForm.full_name,
|
||||
display_name: settingCustomerForm.display_name,
|
||||
};
|
||||
|
||||
data.append('form', JSON.stringify(submitData));
|
||||
|
||||
this.api
|
||||
.accountEditUpdate(data)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('data submitted!');
|
||||
this.submitStatus = "success";
|
||||
console.log(this.submitStatus);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.submitStatus = "send_failed";
|
||||
console.log(this.submitStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
328
src/app/dashboard/add-data.component.html
Normal file
328
src/app/dashboard/add-data.component.html
Normal file
|
@ -0,0 +1,328 @@
|
|||
<div class="animated fadeIn">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Submit Transaction</strong>
|
||||
<small>Required Data marked in <strong>bold</strong>.</small>
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Time of Transaction</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="datetime-local" class="form-control" [min]="minDate" [(ngModel)]="myDate" (ngModelChange)="transactionFormValidate()">
|
||||
<span class="help-block">Enter the date and time the transaction occurred.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Amount</strong></label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" placeholder="0.00" [(ngModel)]="amount" (ngModelChange)="transactionFormValidate()">
|
||||
</div>
|
||||
<span class="help-block">Enter the amount spent, such as 5.35 for £5.35.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Organisation Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" placeholder="Organisation Name" [(ngModel)]="submitOrg.name" (input)="organisationSearch($event)" (ngModelChange)="transactionFormValidate()">
|
||||
<span class="help-block">Enter the name of the organisation money was spent. Choose existing ones from below or if not found, enter the details below.</span>
|
||||
</div>
|
||||
</div>
|
||||
<org-table *ngIf="storeList != null" [orgList]="storeList" (onClick)="addStore($event)"></org-table>
|
||||
<div *ngIf="showAddStore">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Organisation Street Name</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" placeholder="Which Street?" [(ngModel)]="submitOrg.street_name" (ngModelChange)="transactionFormValidate()">
|
||||
<span class="help-block">Enter the street name where the organisation is located at.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Organisation Town</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" placeholder="Which Town?" [(ngModel)]="submitOrg.town" (ngModelChange)="transactionFormValidate()">
|
||||
<span class="help-block">Enter the name of the town where the organisation is located at.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Organisation Postcode</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" placeholder="Postcode if known" [(ngModel)]="submitOrg.postcode" (ngModelChange)="transactionFormValidate()">
|
||||
<span class="help-block">Enter the postcode where the organisation is located at.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<div [ngSwitch]="transactionFormStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Submit Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
{{transactionFormStatusError}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" (click)="postTransaction()" [disabled]="TransactionFormInvalid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="accountType == 'organisation'" class="card">
|
||||
<div class="card-header">
|
||||
<strong>Profile & Payroll Data</strong>
|
||||
<small>Required Data marked in <strong>bold</strong>.</small>
|
||||
</div>
|
||||
<form class="form-horizontal" [formGroup]="payrollForm" (ngSubmit)="onSubmitPayroll()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Period of entry month</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="month" class="form-control" formControlName="entryperiod">
|
||||
<span class="help-block">Enter the month and year for this information.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total amount of Employees</label>
|
||||
<div class="col-md-9">
|
||||
<input type="number" class="form-control" formControlName="employeeamount" placeholder="0">
|
||||
<span class="help-block">Enter the amount of employees the organisation has for the entry month.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total amount of local Employees</label>
|
||||
<div class="col-md-9">
|
||||
<input type="number" class="form-control" formControlName="localemployeeamount" placeholder="0">
|
||||
<span class="help-block">Enter the amount of employees that live locally to the organisation for the entry month.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Gross Payroll</strong></label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="grosspayroll" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Enter the Gross Payroll for the organisation for the entry month.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Income Tax</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="payrollincometax" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Enter the organisation's total income tax for the entry month.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Employees Total NI</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="payrollemployeeni" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Total of Employees National Insurance contributions for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Employers Total NI</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="payrollemployerni" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Employers National Insurance contributions for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Pensions</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="payrolltotalpension" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Total spent on employee pensions by the organisation for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Other Benefits</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="payrollotherbenefit" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">A total of other payments such as refunded fuel etc. for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<div [ngSwitch]="payrollFormStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Submit Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Error received, please try again.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" [disabled]="!payrollForm.valid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngIf="accountType == 'organisation'" class="card">
|
||||
<div class="card-header">
|
||||
<strong>Individual Supplier Data</strong>
|
||||
<small>Optional but recommended.</small>
|
||||
</div>
|
||||
<form class="form-horizontal" [formGroup]="singleSupplierForm" (ngSubmit)="onSubmitSingleSupplier()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Period of entry month</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="month" class="form-control" formControlName="entryperiod">
|
||||
<span class="help-block">Enter the month and year for this information.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Supplier Business Name</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="supplierbusinessname">
|
||||
<span class="help-block">Enter the business name of the supplier.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Postcode</label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" formControlName="postcode">
|
||||
<span class="help-block">Enter the postcode where the supplier is located.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Monthly Spend</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="monthlyspend" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Enter the monthly spend paid towards the supplier.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<div [ngSwitch]="singleSupplierFormStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Submit Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Error received, please try again.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" [disabled]="!singleSupplierForm.valid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div *ngIf="accountType == 'organisation'" class="card">
|
||||
<div class="card-header">
|
||||
<strong>Individual Employee Data</strong>
|
||||
<small>Optional but recommended.</small>
|
||||
</div>
|
||||
<form class="form-horizontal" [formGroup]="employeeForm" (ngSubmit)="onSubmitEmployee()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Period of entry month</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="month" class="form-control" formControlName="entryperiod">
|
||||
<span class="help-block">Enter the month and year for this information.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Employee number</label>
|
||||
<div class="col-md-9">
|
||||
<input type="number" class="form-control" formControlName="employeeno" placeholder="0">
|
||||
<span class="help-block">Used to identify employee anonymously</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Gross Wage</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="employeegrosswage" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Enter the gross wage of the employee for the entry month.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Income Tax</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="employeeincometax" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Enter the total income tax of the employee for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Employee NI</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="employeeni" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Individual Employees National Insurance Contributions for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Employee's Pension</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="employeepension" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">Individual Employees Pension contributions for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input">Total Employee Other Benefits</label>
|
||||
<div class="col-md-9">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon"><i class="fa fa-gbp"></i></span>
|
||||
<input type="number" min="0.00" step="0.01" class="form-control" formControlName="employeeotherbenefit" placeholder="0.00">
|
||||
</div>
|
||||
<span class="help-block">A total of other payments such as refunded fuel etc. for the entry month</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<div [ngSwitch]="employeeFormStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Submit Succeeded.
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
Error received, please try again.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" [disabled]="!employeeForm.valid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.row-->
|
||||
</div>
|
308
src/app/dashboard/add-data.component.ts
Normal file
308
src/app/dashboard/add-data.component.ts
Normal file
|
@ -0,0 +1,308 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import { OrgTableComponent } from '../shared/org-table.component';
|
||||
import * as moment from 'moment';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'add-data.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
export class AddDataComponent {
|
||||
payrollForm: FormGroup;
|
||||
singleSupplierForm: FormGroup;
|
||||
employeeForm: FormGroup;
|
||||
transactionForm: FormGroup;
|
||||
payrollFormStatus: any;
|
||||
singleSupplierFormStatus: any;
|
||||
employeeFormStatus: any;
|
||||
transactionFormStatus: any;
|
||||
transactionFormStatusError: string = 'Error received, please try again.';
|
||||
accountType: any;
|
||||
|
||||
submitOrg = {
|
||||
name: '',
|
||||
street_name: '',
|
||||
town: '',
|
||||
postcode: '',
|
||||
};
|
||||
organisationId: number;
|
||||
organisationTown: string;
|
||||
organisationPostcode: string;
|
||||
amount: number;
|
||||
transactionAdditionType = 1;
|
||||
storeList;
|
||||
showAddStore = false;
|
||||
submitReceipt = false;
|
||||
transactionFormInvalid = true;
|
||||
myDate: any;
|
||||
minDate: any;
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private formBuilder: FormBuilder,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.payrollForm = this.formBuilder.group({
|
||||
entryperiod: ['', [Validators.required]],
|
||||
employeeamount: ['', [Validators.required]],
|
||||
localemployeeamount: ['', [Validators.required]],
|
||||
grosspayroll: ['', [Validators.required]],
|
||||
payrollincometax: [''],
|
||||
payrollemployeeni: [''],
|
||||
payrollemployerni: [''],
|
||||
payrolltotalpension: [''],
|
||||
payrollotherbenefit: [''],
|
||||
});
|
||||
this.singleSupplierForm = this.formBuilder.group({
|
||||
entryperiod: ['', [Validators.required]],
|
||||
supplierbusinessname: [''],
|
||||
postcode: [''],
|
||||
monthlyspend: [''],
|
||||
});
|
||||
this.employeeForm = this.formBuilder.group({
|
||||
entryperiod: ['', [Validators.required]],
|
||||
employeeno: [''],
|
||||
employeeincometax: [''],
|
||||
employeegrosswage: [''],
|
||||
employeeni: [''],
|
||||
employeepension: [''],
|
||||
employeeotherbenefit: [''],
|
||||
});
|
||||
this.myDate = moment().format('YYYY-MM-DD[T]HH:mm');
|
||||
// this.myDate = new Date().toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getMinDate();
|
||||
this.accountType = localStorage.getItem('usertype');
|
||||
}
|
||||
|
||||
getMinDate(){
|
||||
// gets the April 1st date of the current year
|
||||
let aprilDate = moment().month(3).date(1);
|
||||
let now = moment();
|
||||
// Checks if current time is before April 1st, if so returns true
|
||||
let beforeApril = now.isBefore(aprilDate);
|
||||
if ( beforeApril == true ) {
|
||||
this.minDate = aprilDate.subtract(2, 'years').format('YYYY-MM-DD');
|
||||
} else {
|
||||
this.minDate = aprilDate.subtract(1, 'years').format('YYYY-MM-DD');
|
||||
}
|
||||
}
|
||||
|
||||
initializeItems() {
|
||||
// Dont bother searching for an empty or undefined string
|
||||
if ( this.submitOrg.name == '' ) {
|
||||
return;
|
||||
}
|
||||
var searchData = {
|
||||
search_name: this.submitOrg.name,
|
||||
};
|
||||
|
||||
this.api.search(searchData).subscribe(
|
||||
data => {
|
||||
if(data.validated.length > 0) {
|
||||
this.storeList = data.validated;
|
||||
this.showAddStore = false;
|
||||
this.transactionAdditionType = 1;
|
||||
} else {
|
||||
this.storeList = data.unvalidated;
|
||||
this.showAddStore = false;
|
||||
this.transactionAdditionType = 2;
|
||||
}
|
||||
// handle the case when the storelist is empty
|
||||
if(this.storeList.length < 1 ) {
|
||||
this.storeList = null;
|
||||
this.showAddStore = true;
|
||||
this.transactionAdditionType = 3;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// if user select a item from the list
|
||||
addStore(store){
|
||||
this.submitOrg = store;
|
||||
this.transactionFormValidate();
|
||||
this.organisationId = store.id;
|
||||
}
|
||||
|
||||
// search for store
|
||||
organisationSearch(ev) {
|
||||
// Reset items back to all of the items
|
||||
this.initializeItems();
|
||||
|
||||
// set val to the value of the searchbar
|
||||
let val = ev.target.value;
|
||||
|
||||
// Filter the store list so search seems quicker
|
||||
if (val && val.trim() != '' && this.storeList != null) {
|
||||
this.storeList = this.storeList.filter(
|
||||
(item) => {
|
||||
return ( item.name.toLowerCase().indexOf( val.toLowerCase() ) > -1 );
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// if nothing is found
|
||||
if(!this.storeList === null){
|
||||
// display add new store button
|
||||
this.showAddStore = true;
|
||||
}
|
||||
}
|
||||
|
||||
transactionFormValidate() {
|
||||
if( this.submitOrg.name.length == 0 ||
|
||||
this.amount == 0 ) {
|
||||
this.transactionFormInvalid = true;
|
||||
}else{
|
||||
this.transactionFormInvalid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public postTransaction() {
|
||||
|
||||
var myParams: any;
|
||||
let purchaseTime: string;
|
||||
purchaseTime = moment(this.myDate, 'YYYY-MM-DD[T]HH:mm').local().format('YYYY-MM-DD[T]HH:mm:ss.SSSZ');
|
||||
switch(this.transactionAdditionType){
|
||||
case 1:
|
||||
myParams = {
|
||||
transaction_type : this.transactionAdditionType,
|
||||
transaction_value : this.amount,
|
||||
purchase_time : purchaseTime,
|
||||
organisation_id : this.organisationId,
|
||||
};
|
||||
break;
|
||||
case 2:
|
||||
myParams = {
|
||||
transaction_type : this.transactionAdditionType,
|
||||
transaction_value : this.amount,
|
||||
purchase_time : purchaseTime,
|
||||
organisation_id : this.organisationId,
|
||||
};
|
||||
break;
|
||||
case 3:
|
||||
myParams = {
|
||||
transaction_type : this.transactionAdditionType,
|
||||
transaction_value : this.amount,
|
||||
purchase_time : purchaseTime,
|
||||
organisation_name : this.submitOrg.name,
|
||||
street_name : this.submitOrg.street_name,
|
||||
town : this.submitOrg.town,
|
||||
postcode : this.submitOrg.postcode,
|
||||
};
|
||||
break;
|
||||
}
|
||||
/******************************/
|
||||
|
||||
this.api
|
||||
.upload(myParams)
|
||||
.subscribe(
|
||||
result => {
|
||||
if ( result.success == true ) {
|
||||
console.log('Successful Upload');
|
||||
console.log(result);
|
||||
this.transactionFormStatus = "success";
|
||||
console.log(this.transactionFormStatus);
|
||||
this.resetForm();
|
||||
} else {
|
||||
console.log('Upload Error');
|
||||
this.transactionFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message);
|
||||
this.transactionFormStatus = "send_failed";
|
||||
console.log(this.transactionFormStatus);
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('Upload Error');
|
||||
console.log(error);
|
||||
try {
|
||||
console.log(error.error);
|
||||
let jsonError = error.json();
|
||||
console.log("boop");
|
||||
this.transactionFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
|
||||
} catch(e) {
|
||||
this.transactionFormStatusError = 'There was a server error, please try again later.';
|
||||
}
|
||||
this.transactionFormStatus = "send_failed";
|
||||
console.log(this.transactionFormStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private resetForm() {
|
||||
this.submitOrg = {
|
||||
name: '',
|
||||
street_name: '',
|
||||
town: '',
|
||||
postcode: '',
|
||||
};
|
||||
this.storeList = null;
|
||||
this.amount = null;
|
||||
this.transactionFormInvalid = true;
|
||||
}
|
||||
|
||||
onSubmitPayroll() {
|
||||
console.log(this.payrollForm.value);
|
||||
|
||||
this.api
|
||||
.login(this.payrollForm.value)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('data submitted!');
|
||||
this.payrollFormStatus = "success";
|
||||
console.log(this.payrollFormStatus);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.payrollFormStatus = "send_failed";
|
||||
console.log(this.payrollFormStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onSubmitSingleSupplier() {
|
||||
console.log(this.singleSupplierForm.value);
|
||||
|
||||
this.api
|
||||
.login(this.singleSupplierForm.value)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('data submitted!');
|
||||
this.singleSupplierFormStatus = "success";
|
||||
console.log(this.singleSupplierFormStatus);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.singleSupplierFormStatus = "send_failed";
|
||||
console.log(this.singleSupplierFormStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onSubmitEmployee() {
|
||||
console.log(this.employeeForm.value);
|
||||
|
||||
this.api
|
||||
.login(this.employeeForm.value)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('data submitted!');
|
||||
this.employeeFormStatus = "success";
|
||||
console.log(this.employeeFormStatus);
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.employeeFormStatus = "send_failed";
|
||||
console.log(this.employeeFormStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
131
src/app/dashboard/dashboard-customer.component.html
Normal file
131
src/app/dashboard/dashboard-customer.component.html
Normal file
|
@ -0,0 +1,131 @@
|
|||
<div class="animated fadeIn">
|
||||
<div class="card">
|
||||
<div class="card-footer">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="text-muted">My Points</div>
|
||||
<strong>{{ basicStats.user_sum / 10 | number:'1.0-0' }}</strong>
|
||||
</li>
|
||||
<li>
|
||||
<div class="text-muted">My Rank</div>
|
||||
<div *ngIf="basicStats.user_position == 0" class="statuscontent">
|
||||
<strong>Unranked</strong>
|
||||
</div>
|
||||
<div *ngIf="basicStats.user_position != 0" class="statuscontent">
|
||||
<strong>{{ basicStats.user_position }}</strong>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="text-muted">My Total Spend</div>
|
||||
<strong>{{ basicStats.user_sum | currency:'GBP':true:'1.2-2' }}</strong>
|
||||
</li>
|
||||
<li>
|
||||
<div class="text-muted">Value to Local Economy</div>
|
||||
<strong>{{ basicStats.user_sum * 2.3 | currency:'GBP':true:'1.2-2' }}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.today_sum | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Total Today</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.today_sum / (basicStats.today_count ? basicStats.today_count : 1) | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Avg. Spend Today</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.week_sum | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Last Week Total</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.week_sum / (basicStats.week_count ? basicStats.week_count : 1) | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Last Week Avg. Spend</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.month_sum | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Last Month Total</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.month_sum / (basicStats.month_count ? basicStats.month_count : 1) | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>Last Month Avg. Spend</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.user_sum | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>User Total</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{ basicStats.user_sum / (basicStats.user_count ? basicStats.user_count : 1) | currency:'GBP':true:'1.2-2' }}</div>
|
||||
<div>User Avg. Spend</div>
|
||||
<!-- <div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
</div><!--/.row-->
|
||||
</div>
|
55
src/app/dashboard/dashboard-customer.component.ts
Normal file
55
src/app/dashboard/dashboard-customer.component.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { Directive, Component, OnInit } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import { Router } from '@angular/router';
|
||||
import { GraphWidget } from '../widgets/graph-widget.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dashboard-customer.component.html'
|
||||
})
|
||||
export class DashboardCustomerComponent implements OnInit {
|
||||
customersThisMonth: any;
|
||||
moneySpentThisMonth: any;
|
||||
pointsTotal: any;
|
||||
averageTransactionToday: any;
|
||||
|
||||
/* Setting up dashboard's main variables*/
|
||||
name: any;
|
||||
email:any;
|
||||
myPearPoints: any;
|
||||
trends: any;
|
||||
myRank: any;
|
||||
username: any;
|
||||
|
||||
basicStats = {
|
||||
today_sum: 0,
|
||||
today_count: 0,
|
||||
week_sum: 0,
|
||||
week_count: 0,
|
||||
month_sum: 0,
|
||||
month_count: 0,
|
||||
user_sum: 0,
|
||||
user_count: 0,
|
||||
global_sum: 0,
|
||||
global_count: 0,
|
||||
user_position: 0,
|
||||
};
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.api.basicStats().subscribe(
|
||||
result => {
|
||||
this.basicStats = result;
|
||||
},
|
||||
error => {
|
||||
console.log('Retrieval Error');
|
||||
console.log( error._body );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
}
|
297
src/app/dashboard/dashboard.component.html
Normal file
297
src/app/dashboard/dashboard.component.html
Normal file
|
@ -0,0 +1,297 @@
|
|||
<div class="animated fadeIn">
|
||||
<div class="card">
|
||||
<div class="card-footer">
|
||||
<ul>
|
||||
<li *ngIf="showSnippet.customersthismonth" class="hidden-sm-down">
|
||||
<div class="text-muted">Customers This Month</div>
|
||||
<strong>{{customersThisMonth}}</strong>
|
||||
</li>
|
||||
<li *ngIf="showSnippet.moneyspentthismonth" class="hidden-sm-down">
|
||||
<div class="text-muted">Money Spent This Month</div>
|
||||
<strong>{{moneySpentThisMonth | currency:'GBP':true:'1.2-2'}}</strong>
|
||||
</li>
|
||||
<li *ngIf="showSnippet.pointstotal" class="hidden-sm-down">
|
||||
<div class="text-muted">Points Total</div>
|
||||
<strong>{{pointsTotal}}</strong>
|
||||
</li>
|
||||
<li *ngIf="showSnippet.averagetransactiontoday" class="hidden-sm-down">
|
||||
<div class="text-muted">Average Transaction Today</div>
|
||||
<strong>{{averageTransactionToday | currency:'GBP':true:'1.2-2'}}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div *ngFor="let widget of widgetList" class="col-sm-6 col-lg-3">
|
||||
<widget-graph *ngIf="widget.type == 'graph'" [graphName]="widget.name" [graphTitle]="widget.title" [graphIcon]="widget.icon"></widget-graph>
|
||||
</div>
|
||||
<div *ngIf="showGraph.noofcustomerssector" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{noOfCustomersSector}}</div>
|
||||
<div>No. of Customers in your Sector</div>
|
||||
<div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" [style.width]="percentOfCustomersSector + '%'" attr.aria-valuenow="{{percentOfCustomersSector}}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.percentofcustomerssector" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div class="h4 mb-0">{{percentOfCustomersSector}}%</div>
|
||||
<div>Customers in your Sector</div>
|
||||
<div class="progress progress-white progress-xs mt-3">
|
||||
<div class="progress-bar" role="progressbar" [style.width]="percentOfCustomersSector + '%'" attr.aria-valuenow="{{percentOfCustomersSector}}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.customerslastyear" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-info">
|
||||
<div class="card-block pb-0">
|
||||
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||
<i class="icon-location-pin"></i>
|
||||
</button>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Customers last year</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="lineChart4Data"
|
||||
[labels]="lineChart4Labels"
|
||||
[options]="lineChart4Options"
|
||||
[colors]="lineChart4Colours"
|
||||
[legend]="lineChart4Legend"
|
||||
[chartType]="lineChart4Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.returningcustomerslastweek" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-info">
|
||||
<div class="card-block pb-0">
|
||||
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||
<i class="icon-location-pin"></i>
|
||||
</button>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Returning Customers last week</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="lineChart6Data"
|
||||
[labels]="lineChart6Labels"
|
||||
[options]="lineChart6Options"
|
||||
[colors]="lineChart6Colours"
|
||||
[legend]="lineChart6Legend"
|
||||
[chartType]="lineChart6Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.returningcustomerslastmonth" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-info">
|
||||
<div class="card-block pb-0">
|
||||
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||
<i class="icon-location-pin"></i>
|
||||
</button>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Returning Customers last month</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="lineChart7Data"
|
||||
[labels]="lineChart7Labels"
|
||||
[options]="lineChart7Options"
|
||||
[colors]="lineChart7Colours"
|
||||
[legend]="lineChart7Legend"
|
||||
[chartType]="lineChart7Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.returningcustomerslastyear" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-info">
|
||||
<div class="card-block pb-0">
|
||||
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||
<i class="icon-location-pin"></i>
|
||||
</button>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Returning Customers last year</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="lineChart8Data"
|
||||
[labels]="lineChart8Labels"
|
||||
[options]="lineChart8Options"
|
||||
[colors]="lineChart8Colours"
|
||||
[legend]="lineChart8Legend"
|
||||
[chartType]="lineChart8Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.pointsthisweek" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-warning">
|
||||
<div class="card-block pb-0">
|
||||
<div class="btn-group float-right">
|
||||
<button type="button" class="btn btn-transparent dropdown-toggle p-0" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="icon-settings"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Points earned this week</p>
|
||||
</div>
|
||||
<div class="chart-wrapper" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="lineChart5Data"
|
||||
[labels]="lineChart5Labels"
|
||||
[options]="lineChart5Options"
|
||||
[colors]="lineChart5Colours"
|
||||
[legend]="lineChart5Legend"
|
||||
[chartType]="lineChart5Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.pointslastweek" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-danger">
|
||||
<div class="card-block pb-0">
|
||||
<div class="btn-group float-right" dropdown>
|
||||
<button type="button" class="btn btn-transparent dropdown-toggle p-0" dropdownToggle>
|
||||
<i class="icon-settings"></i>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-right" *dropdownMenu>
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="mb-0">9.823</h4>
|
||||
<p>Points earned last week</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="barChart1Data"
|
||||
[labels]="barChart1Labels"
|
||||
[options]="barChart1Options"
|
||||
[colors]="barChart1Colours"
|
||||
[legend]="barChart1Legend"
|
||||
[chartType]="barChart1Type"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
<div *ngIf="showGraph.percentlocalsuppliersvscompetitor" class="col-sm-6 col-lg-3">
|
||||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block">
|
||||
<div>Your suppliers that are local vs a local competitor</div>
|
||||
<ul class="horizontal-bars type-3">
|
||||
<li>
|
||||
<i class="icon-pie-chart"></i>
|
||||
<span class="title">Yours</span>
|
||||
<span class="value">{{percentOfLocalSuppliers}}%</span>
|
||||
<div class="bars">
|
||||
<div class="progress progress-xs">
|
||||
<div class="progress-bar bg-warning" role="progressbar" [style.width]="percentOfLocalSuppliers + '%'" attr.aria-valuenow="{{percentOfLocalSuppliers}}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<i class="icon-pie-chart"></i>
|
||||
<span class="title">A competitor</span>
|
||||
<span class="value">{{percentOfSingleCompetitorLocalSuppliers}}%</span>
|
||||
<div class="bars">
|
||||
<div class="progress progress-xs">
|
||||
<div class="progress-bar bg-warning" role="progressbar" [style.width]="percentOfSingleCompetitorLocalSuppliers + '%'" attr.aria-valuenow="{{percentOfSingleCompetitorLocalSuppliers}}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
</div><!--/.row-->
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
<h4 class="card-title mb-0">Customers</h4>
|
||||
<div class="small text-muted">November 2015</div>
|
||||
</div><!--/.col-->
|
||||
<div class="col-sm-7 hidden-sm-down">
|
||||
<button type="button" class="btn btn-primary float-right"><i class="icon-cloud-download"></i></button>
|
||||
<div class="btn-toolbar float-right" role="toolbar" aria-label="Toolbar with button groups">
|
||||
<div class="btn-group mr-3" data-toggle="buttons" aria-label="First group">
|
||||
<label class="btn btn-outline-secondary">
|
||||
<input type="radio" name="options" id="option1"> Day
|
||||
</label>
|
||||
<label class="btn btn-outline-secondary active">
|
||||
<input type="radio" name="options" id="option2" checked> Month
|
||||
</label>
|
||||
<label class="btn btn-outline-secondary">
|
||||
<input type="radio" name="options" id="option3"> Year
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.col-->
|
||||
</div><!--/.row-->
|
||||
<div class="chart-wrapper" style="height:300px;margin-top:40px;">
|
||||
<canvas baseChart class="chart"
|
||||
[datasets]="mainChartData"
|
||||
[labels]="mainChartLabels"
|
||||
[options]="mainChartOptions"
|
||||
[colors]="mainChartColours"
|
||||
[legend]="mainChartLegend"
|
||||
[chartType]="mainChartType"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<ul>
|
||||
<li class="hidden-sm-down">
|
||||
<div class="text-muted">Customers</div>
|
||||
<strong>24.093 Users (20%)</strong>
|
||||
<div class="progress progress-xs mt-2">
|
||||
<div class="progress-bar bg-info" role="progressbar" style="width: 20%" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="text-muted">Pageviews</div>
|
||||
<strong>78.706 Views (60%)</strong>
|
||||
<div class="progress progress-xs mt-2">
|
||||
<div class="progress-bar bg-warning" role="progressbar" style="width: 60%" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="hidden-sm-down">
|
||||
<div class="text-muted">New Users</div>
|
||||
<strong>22.123 Users (80%)</strong>
|
||||
<div class="progress progress-xs mt-2">
|
||||
<div class="progress-bar bg-danger" role="progressbar" style="width: 80%" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="hidden-sm-down">
|
||||
<div class="text-muted">Bounce Rate</div>
|
||||
<strong>40.15%</strong>
|
||||
<div class="progress progress-xs mt-2">
|
||||
<div class="progress-bar" role="progressbar" style="width: 40%" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
732
src/app/dashboard/dashboard.component.ts
Normal file
732
src/app/dashboard/dashboard.component.ts
Normal file
|
@ -0,0 +1,732 @@
|
|||
import { Directive, Component, OnInit } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import { Router } from '@angular/router';
|
||||
import { GraphWidget } from '../widgets/graph-widget.component';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'dashboard.component.html'
|
||||
})
|
||||
export class DashboardComponent implements OnInit {
|
||||
shuffledArray: any;
|
||||
showGraph: any;
|
||||
showSnippet: any;
|
||||
customersThisMonth: any;
|
||||
moneySpentThisMonth: any;
|
||||
pointsTotal: any;
|
||||
averageTransactionToday: any;
|
||||
customersThisWeek: any;
|
||||
customersLastWeek: any;
|
||||
customersLastMonth: any;
|
||||
customersLastYear: any;
|
||||
pointsThisWeek: any;
|
||||
pointsLastWeek: any;
|
||||
percentOfCustomersSector: any;
|
||||
noOfCustomersSector: any;
|
||||
percentOfLocalSuppliers: any;
|
||||
percentOfSingleCompetitorLocalSuppliers: any;
|
||||
|
||||
public widgetList = [
|
||||
{
|
||||
type: 'graph',
|
||||
name: 'customers_last_7_days',
|
||||
icon: 'icon-people',
|
||||
title: 'Customers Last 7 Days',
|
||||
},
|
||||
{
|
||||
type: 'graph',
|
||||
name: 'customers_last_30_days',
|
||||
icon: 'icon-people',
|
||||
title: 'Customers Last 30 Days',
|
||||
},
|
||||
];
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.shuffle = this.shuffledArray;
|
||||
this.api.graph_data(undefined)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log(result);
|
||||
// Return what data to show 4 of
|
||||
this.showGraph = result.elementstoshow.graphs;
|
||||
this.showSnippet = result.elementstoshow.snippets;
|
||||
// Percentage Chart
|
||||
this.percentOfLocalSuppliers = result.data.localsuppliers.percentownlocal;
|
||||
this.percentOfSingleCompetitorLocalSuppliers = result.data.localsuppliers.percentsinglecompetitorlocal;
|
||||
// Percentage Chart 2
|
||||
this.percentOfCustomersSector = result.data.customersinsector.percent;
|
||||
this.noOfCustomersSector = result.data.customersinsector.customerno;
|
||||
// Chart 1
|
||||
this.customersThisWeek = result.data.customersthisweek;
|
||||
this.lineChart1Data[0].data = this.customersThisWeek.customerno;
|
||||
this.lineChart1Labels = this.customersThisWeek.day;
|
||||
// Chart 4
|
||||
this.customersLastYear = result.data.customerslastyear;
|
||||
this.lineChart4Data[0].data = this.customersLastYear.customerno;
|
||||
this.lineChart4Labels = this.customersLastYear.month;
|
||||
// Chart 5
|
||||
this.pointsThisWeek = result.data.pointsthisweek;
|
||||
this.lineChart5Data[0].data = this.pointsThisWeek.points;
|
||||
this.lineChart5Labels = this.pointsThisWeek.day;
|
||||
// Chart 6
|
||||
this.pointsLastWeek = result.data.pointslastweek;
|
||||
this.barChart1Data[0].data = this.pointsLastWeek.points;
|
||||
this.barChart1Labels = this.pointsLastWeek.day;
|
||||
// Chart 7
|
||||
this.customersLastWeek = result.data.customerslastweek;
|
||||
this.lineChart6Data[0].data = this.customersLastWeek.returningcustomerno;
|
||||
this.lineChart6Labels = this.customersLastWeek.day;
|
||||
// Chart 8
|
||||
this.customersLastMonth = result.data.customerslastmonth;
|
||||
this.lineChart7Data[0].data = this.customersLastMonth.returningcustomerno;
|
||||
this.lineChart7Labels = this.customersLastMonth.day;
|
||||
// Chart 9
|
||||
this.customersLastYear = result.data.customerslastyear;
|
||||
this.lineChart8Data[0].data = this.customersLastYear.returningcustomerno;
|
||||
this.lineChart8Labels = this.customersLastYear.month;
|
||||
}
|
||||
),
|
||||
this.api.breadcrumb_data(undefined)
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log(result);
|
||||
this.customersThisMonth = result.customersthismonth;
|
||||
this.moneySpentThisMonth = result.moneyspentthismonth;
|
||||
this.pointsTotal = result.pointstotal;
|
||||
this.averageTransactionToday = result.averagetransactiontoday;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle function
|
||||
public shuffle(array) {
|
||||
return new Promise(resolve => {
|
||||
let counter = array.length;
|
||||
|
||||
// While there are elements in the array
|
||||
while (counter > 0) {
|
||||
// Pick a random index
|
||||
const index = Math.floor(Math.random() * counter);
|
||||
|
||||
// Decrease counter by 1
|
||||
counter--;
|
||||
|
||||
// And swap the last element with it
|
||||
const temp = array[counter];
|
||||
array[counter] = array[index];
|
||||
array[index] = temp;
|
||||
}
|
||||
|
||||
this.shuffledArray = array;
|
||||
resolve(true);
|
||||
});
|
||||
}
|
||||
|
||||
public brandPrimary = '#20a8d8';
|
||||
public brandSuccess = '#4dbd74';
|
||||
public brandInfo = '#63c2de';
|
||||
public brandWarning = '#f8cb00';
|
||||
public brandDanger = '#f86c6b';
|
||||
|
||||
// dropdown buttons
|
||||
public status: { isopen } = { isopen: false };
|
||||
public toggleDropdown($event: MouseEvent): void {
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
this.status.isopen = !this.status.isopen;
|
||||
}
|
||||
|
||||
// convert Hex to RGBA
|
||||
public convertHex(hex: string, opacity: number) {
|
||||
hex = hex.replace('#', '');
|
||||
const r = parseInt(hex.substring(0, 2), 16);
|
||||
const g = parseInt(hex.substring(2, 4), 16);
|
||||
const b = parseInt(hex.substring(4, 6), 16);
|
||||
|
||||
const rgba = 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacity / 100 + ')';
|
||||
return rgba;
|
||||
}
|
||||
|
||||
// events
|
||||
public chartClicked(e: any): void {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
public chartHovered(e: any): void {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
// lineChart1
|
||||
public lineChart1Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series A'
|
||||
}
|
||||
];
|
||||
public lineChart1Labels: Array<any> = [];
|
||||
public lineChart1Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'transparent'
|
||||
},
|
||||
ticks: {
|
||||
fontSize: 2,
|
||||
fontColor: 'transparent',
|
||||
}
|
||||
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
display: false,
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 1
|
||||
},
|
||||
point: {
|
||||
radius: 4,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart1Colours: Array<any> = [
|
||||
{ // grey
|
||||
backgroundColor: this.brandPrimary,
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChart1Legend = false;
|
||||
public lineChart1Type = 'line';
|
||||
|
||||
// lineChart4
|
||||
public lineChart4Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series B'
|
||||
}
|
||||
];
|
||||
public lineChart4Labels: Array<any> = [];
|
||||
public lineChart4Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'transparent'
|
||||
},
|
||||
ticks: {
|
||||
fontSize: 2,
|
||||
fontColor: 'transparent',
|
||||
}
|
||||
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
display: false,
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
tension: 0.00001,
|
||||
borderWidth: 1
|
||||
},
|
||||
point: {
|
||||
radius: 4,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart4Colours: Array<any> = [
|
||||
{ // grey
|
||||
backgroundColor: this.brandInfo,
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChart4Legend = false;
|
||||
public lineChart4Type = 'line';
|
||||
|
||||
// lineChart6
|
||||
public lineChart6Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series B'
|
||||
}
|
||||
];
|
||||
public lineChart6Labels: Array<any> = [];
|
||||
public lineChart6Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'transparent'
|
||||
},
|
||||
ticks: {
|
||||
fontSize: 2,
|
||||
fontColor: 'transparent',
|
||||
}
|
||||
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
display: false,
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
tension: 0.00001,
|
||||
borderWidth: 1
|
||||
},
|
||||
point: {
|
||||
radius: 4,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart6Colours: Array<any> = [
|
||||
{ // grey
|
||||
backgroundColor: this.brandInfo,
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChart6Legend = false;
|
||||
public lineChart6Type = 'line';
|
||||
|
||||
// lineChart7
|
||||
public lineChart7Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series B'
|
||||
}
|
||||
];
|
||||
public lineChart7Labels: Array<any> = [];
|
||||
public lineChart7Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 2
|
||||
},
|
||||
point: {
|
||||
radius: 2,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart7Colours: Array<any> = [
|
||||
{ // grey
|
||||
backgroundColor: this.brandInfo,
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChart7Legend = false;
|
||||
public lineChart7Type = 'line';
|
||||
|
||||
// lineChart8
|
||||
public lineChart8Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series B'
|
||||
}
|
||||
];
|
||||
public lineChart8Labels: Array<any> = [];
|
||||
public lineChart8Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'transparent'
|
||||
},
|
||||
ticks: {
|
||||
fontSize: 2,
|
||||
fontColor: 'transparent',
|
||||
}
|
||||
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
display: false,
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
tension: 0.00001,
|
||||
borderWidth: 1
|
||||
},
|
||||
point: {
|
||||
radius: 4,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart8Colours: Array<any> = [
|
||||
{ // grey
|
||||
backgroundColor: this.brandInfo,
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChart8Legend = false;
|
||||
public lineChart8Type = 'line';
|
||||
|
||||
// lineChart5
|
||||
public lineChart5Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series A'
|
||||
}
|
||||
];
|
||||
public lineChart5Labels: Array<any> = [];
|
||||
public lineChart5Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 2
|
||||
},
|
||||
point: {
|
||||
radius: 0,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChart5Colours: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'rgba(255,255,255,.2)',
|
||||
borderColor: 'rgba(255,255,255,.55)',
|
||||
}
|
||||
];
|
||||
public lineChart5Legend = false;
|
||||
public lineChart5Type = 'line';
|
||||
|
||||
|
||||
// barChart1
|
||||
public barChart1Data: Array<any> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series A'
|
||||
}
|
||||
];
|
||||
public barChart1Labels: Array<any> = [];
|
||||
public barChart1Options: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false,
|
||||
barPercentage: 0.6,
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false
|
||||
}]
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public barChart1Colours: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'rgba(255,255,255,.3)',
|
||||
borderWidth: 0
|
||||
}
|
||||
];
|
||||
public barChart1Legend = false;
|
||||
public barChart1Type = 'bar';
|
||||
|
||||
// mainChart
|
||||
|
||||
public random(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||||
}
|
||||
|
||||
public mainChartElements = 27;
|
||||
public mainChartData1: Array<number> = [];
|
||||
public mainChartData2: Array<number> = [];
|
||||
public mainChartData3: Array<number> = [];
|
||||
|
||||
public mainChartData: Array<any> = [
|
||||
{
|
||||
data: this.mainChartData1,
|
||||
label: 'Current'
|
||||
},
|
||||
{
|
||||
data: this.mainChartData2,
|
||||
label: 'Previous'
|
||||
},
|
||||
{
|
||||
data: this.mainChartData3,
|
||||
label: 'BEP'
|
||||
}
|
||||
];
|
||||
/* tslint:disable:max-line-length */
|
||||
public mainChartLabels: Array<any> = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'Monday', 'Thursday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
|
||||
/* tslint:enable:max-line-length */
|
||||
public mainChartOptions: any = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
ticks: {
|
||||
callback: function(value: any) {
|
||||
return value.charAt(0);
|
||||
}
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true,
|
||||
maxTicksLimit: 5,
|
||||
stepSize: Math.ceil(250 / 5),
|
||||
max: 250
|
||||
}
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 2
|
||||
},
|
||||
point: {
|
||||
radius: 0,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 3,
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public mainChartColours: Array<any> = [
|
||||
{ // brandInfo
|
||||
backgroundColor: this.convertHex(this.brandInfo, 10),
|
||||
borderColor: this.brandInfo,
|
||||
pointHoverBackgroundColor: '#fff'
|
||||
},
|
||||
{ // brandSuccess
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandSuccess,
|
||||
pointHoverBackgroundColor: '#fff'
|
||||
},
|
||||
{ // brandDanger
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandDanger,
|
||||
pointHoverBackgroundColor: '#fff',
|
||||
borderWidth: 1,
|
||||
borderDash: [8, 5]
|
||||
}
|
||||
];
|
||||
public mainChartLegend = false;
|
||||
public mainChartType = 'line';
|
||||
|
||||
// social box charts
|
||||
|
||||
public socialChartData1: Array<any> = [
|
||||
{
|
||||
data: [65, 59, 84, 84, 51, 55, 40],
|
||||
label: 'Facebook'
|
||||
}
|
||||
];
|
||||
public socialChartData2: Array<any> = [
|
||||
{
|
||||
data: [1, 13, 9, 17, 34, 41, 38],
|
||||
label: 'Twitter'
|
||||
}
|
||||
];
|
||||
public socialChartData3: Array<any> = [
|
||||
{
|
||||
data: [78, 81, 80, 45, 34, 12, 40],
|
||||
label: 'LinkedIn'
|
||||
}
|
||||
];
|
||||
public socialChartData4: Array<any> = [
|
||||
{
|
||||
data: [35, 23, 56, 22, 97, 23, 64],
|
||||
label: 'Google+'
|
||||
}
|
||||
];
|
||||
|
||||
public socialChartLabels: Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
||||
public socialChartOptions: any = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false,
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 2
|
||||
},
|
||||
point: {
|
||||
radius: 0,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 3,
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public socialChartColours: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'rgba(255,255,255,.1)',
|
||||
borderColor: 'rgba(255,255,255,.55)',
|
||||
pointHoverBackgroundColor: '#fff'
|
||||
}
|
||||
];
|
||||
public socialChartLegend = false;
|
||||
public socialChartType = 'line';
|
||||
|
||||
// sparkline charts
|
||||
|
||||
public sparklineChartData1: Array<any> = [
|
||||
{
|
||||
data: [35, 23, 56, 22, 97, 23, 64],
|
||||
label: 'Clients'
|
||||
}
|
||||
];
|
||||
public sparklineChartData2: Array<any> = [
|
||||
{
|
||||
data: [65, 59, 84, 84, 51, 55, 40],
|
||||
label: 'Clients'
|
||||
}
|
||||
];
|
||||
|
||||
public sparklineChartLabels: Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
||||
public sparklineChartOptions: any = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
display: false,
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 2
|
||||
},
|
||||
point: {
|
||||
radius: 0,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 3,
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public sparklineChartDefault: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: '#d1d4d7',
|
||||
}
|
||||
];
|
||||
public sparklineChartPrimary: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandPrimary,
|
||||
}
|
||||
];
|
||||
public sparklineChartInfo: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandInfo,
|
||||
}
|
||||
];
|
||||
public sparklineChartDanger: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandDanger,
|
||||
}
|
||||
];
|
||||
public sparklineChartWarning: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandWarning,
|
||||
}
|
||||
];
|
||||
public sparklineChartSuccess: Array<any> = [
|
||||
{
|
||||
backgroundColor: 'transparent',
|
||||
borderColor: this.brandSuccess,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
public sparklineChartLegend = false;
|
||||
public sparklineChartType = 'line';
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
// generate random values for mainChart
|
||||
for (let i = 0; i <= this.mainChartElements; i++) {
|
||||
this.mainChartData1.push(this.random(50, 200));
|
||||
this.mainChartData2.push(this.random(80, 100));
|
||||
this.mainChartData3.push(this.random(50, 200));
|
||||
}
|
||||
}
|
||||
}
|
40
src/app/dashboard/dashboard.module.ts
Normal file
40
src/app/dashboard/dashboard.module.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { ChartsModule } from 'ng2-charts/ng2-charts';
|
||||
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
|
||||
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
import { DashboardCustomerComponent } from './dashboard-customer.component';
|
||||
import { AccountEditComponent } from './account-edit.component';
|
||||
import { AddDataComponent } from './add-data.component';
|
||||
import { FeedbackComponent } from './feedback.component';
|
||||
|
||||
import { GraphWidget } from '../widgets/graph-widget.component';
|
||||
|
||||
import { DashboardRoutingModule } from './dashboard.routing';
|
||||
import { OrgResultComponent } from '../shared/org-result.component';
|
||||
import { OrgTableComponent } from '../shared/org-table.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
// Angular imports
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ChartsModule,
|
||||
BsDropdownModule,
|
||||
DashboardRoutingModule,
|
||||
],
|
||||
declarations: [
|
||||
DashboardComponent,
|
||||
DashboardCustomerComponent,
|
||||
AccountEditComponent,
|
||||
AddDataComponent,
|
||||
OrgResultComponent,
|
||||
OrgTableComponent,
|
||||
FeedbackComponent,
|
||||
GraphWidget,
|
||||
]
|
||||
})
|
||||
export class DashboardModule { }
|
58
src/app/dashboard/dashboard.routing.ts
Normal file
58
src/app/dashboard/dashboard.routing.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { AuthGuard } from '../_guards/auth.guard';
|
||||
import { OrgGuard } from '../_guards/org.guard';
|
||||
import { CustomerGuard } from '../_guards/customer.guard';
|
||||
|
||||
import { DashboardComponent } from './dashboard.component';
|
||||
import { DashboardCustomerComponent } from './dashboard-customer.component';
|
||||
import { FullLayoutComponent } from '../layouts/full-layout.component';
|
||||
import { AccountEditComponent } from './account-edit.component';
|
||||
import { AddDataComponent } from './add-data.component';
|
||||
import { FeedbackComponent } from './feedback.component';
|
||||
|
||||
// Using child path to allow for FullLayout theming
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
|
||||
{
|
||||
path: '',
|
||||
component: FullLayoutComponent,
|
||||
canActivate: [AuthGuard],
|
||||
children: [
|
||||
{
|
||||
path: 'dashboard',
|
||||
component: DashboardComponent,
|
||||
data: { title: 'Dashboard' },
|
||||
canActivate: [OrgGuard],
|
||||
},
|
||||
{
|
||||
path: 'dashboard-customer',
|
||||
component: DashboardCustomerComponent,
|
||||
data: { title: 'Customer Dashboard' },
|
||||
canActivate: [CustomerGuard],
|
||||
},
|
||||
{
|
||||
path: 'account-edit',
|
||||
component: AccountEditComponent,
|
||||
data: { title: 'Leaderboards' },
|
||||
},
|
||||
{
|
||||
path: 'add-data',
|
||||
component: AddDataComponent,
|
||||
data: { title: 'Add Transaction' },
|
||||
},
|
||||
{
|
||||
path: 'feedback',
|
||||
component: FeedbackComponent,
|
||||
data: { title: 'Give Feedback' },
|
||||
}
|
||||
],
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class DashboardRoutingModule {}
|
45
src/app/dashboard/feedback.component.html
Normal file
45
src/app/dashboard/feedback.component.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
<div class="animated fadeIn">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<strong>Submit Transaction</strong>
|
||||
<small>Required Data marked in <strong>bold</strong>.</small>
|
||||
</div>
|
||||
<form class="form-horizontal" [formGroup]="feedbackForm" (ngSubmit)="onSubmit()">
|
||||
<div class="card-block">
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Email</strong></label>
|
||||
<div class="col-md-9">
|
||||
<input type="text" class="form-control" name="email" formControlName="email" placeholder="Enter Account Email Here" [(ngModel)]="loggedInEmail" [disabled]="noEmail">
|
||||
<span class="help-block">Enter your email here if it doesn't show.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Enter Feedback Here</strong></label>
|
||||
<div class="col-md-9">
|
||||
<textarea rows="7" class="form-control" formControlName="feedbacktext"></textarea>
|
||||
<span class="help-block">Please enter your feedback in this textbox.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9">
|
||||
<div [ngSwitch]="feedbackFormStatus">
|
||||
<div *ngSwitchCase="'success'" class="alert alert-success" role="alert">
|
||||
Thank you for submitting feedback!
|
||||
</div>
|
||||
<div *ngSwitchCase="'send_failed'" class="alert alert-danger" role="alert">
|
||||
{{feedbackFormStatusError}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button type="submit" [disabled]="!feedbackForm.valid" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--/.row-->
|
||||
</div>
|
91
src/app/dashboard/feedback.component.ts
Normal file
91
src/app/dashboard/feedback.component.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'feedback.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
export class FeedbackComponent {
|
||||
feedbackForm: FormGroup;
|
||||
loggedInEmail: string;
|
||||
noEmail: boolean = false;
|
||||
username: any;
|
||||
feedbackFormStatus: any;
|
||||
feedbackFormStatusError: string = 'Error received, please try again.';
|
||||
|
||||
constructor(
|
||||
private http: Http,
|
||||
private formBuilder: FormBuilder,
|
||||
private api: ApiService,
|
||||
) {
|
||||
this.feedbackForm = this.formBuilder.group({
|
||||
email: ['', [Validators.required]],
|
||||
feedbacktext: ['', [Validators.required]],
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
if(localStorage.getItem('email')) {
|
||||
this.loggedInEmail = localStorage.getItem('email');
|
||||
}
|
||||
console.log('loggedInEmail: ' + this.loggedInEmail);
|
||||
if (this.loggedInEmail) {
|
||||
console.log('email not found in storage');
|
||||
this.api.accountFullLoad().subscribe(
|
||||
result => {
|
||||
console.log(result);
|
||||
this.feedbackForm.patchValue({
|
||||
email: result.email,
|
||||
});
|
||||
this.api.setUserInfo( result.email, result.display_name );
|
||||
},
|
||||
error => {
|
||||
console.log( error._body );
|
||||
this.noEmail = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.api
|
||||
.feedback(this.feedbackForm.value)
|
||||
.subscribe(
|
||||
result => {
|
||||
if ( result.success == true ) {
|
||||
console.log('Successful Upload');
|
||||
console.log(result);
|
||||
this.feedbackFormStatus = "success";
|
||||
console.log(this.feedbackFormStatus);
|
||||
this.feedbackForm.patchValue({
|
||||
feedbacktext: '',
|
||||
});
|
||||
} else {
|
||||
console.log('Upload Error');
|
||||
this.feedbackFormStatusError = JSON.stringify(result.status) + 'Error, ' + JSON.stringify(result.message);
|
||||
this.feedbackFormStatus = "send_failed";
|
||||
console.log(this.feedbackFormStatus);
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('Upload Error');
|
||||
console.log(error);
|
||||
try {
|
||||
console.log(error.error);
|
||||
let jsonError = error.json();
|
||||
console.log("boop");
|
||||
this.feedbackFormStatusError = '"' + jsonError.error + '" Error, ' + jsonError.message;
|
||||
} catch(e) {
|
||||
this.feedbackFormStatusError = 'There was a server error, please try again later.';
|
||||
}
|
||||
this.feedbackFormStatus = "send_failed";
|
||||
console.log(this.feedbackFormStatus);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
66
src/app/layouts/full-layout.component.html
Normal file
66
src/app/layouts/full-layout.component.html
Normal file
|
@ -0,0 +1,66 @@
|
|||
<header class="app-header navbar">
|
||||
<button class="navbar-toggler d-lg-none" type="button" appMobileSidebarToggler>☰</button>
|
||||
<a class="navbar-brand" href="#"></a>
|
||||
<ul class="nav navbar navbar-nav">
|
||||
<li class="nav-item dropdown" dropdown (onToggle)="toggled($event)">
|
||||
<a href class="nav-link dropdown-toggle" dropdownToggle (click)="false">
|
||||
<img src="assets/img/avatars/default.png" class="img-avatar" alt="avatar-image">
|
||||
<span class="d-md-down-none">{{displayName}}</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" *dropdownMenu aria-labelledby="simple-dropdown">
|
||||
|
||||
<div class="dropdown-header text-center"><strong>Settings</strong></div>
|
||||
|
||||
<a class="dropdown-item" routerLinkActive="active" [routerLink]="['/account-edit']">
|
||||
<i class="fa fa-user"></i> Account Settings
|
||||
</a>
|
||||
<div class="divider"></div>
|
||||
<a class="dropdown-item" (click)="userLogout()" href="#"><i class="fa fa-lock"></i> Logout</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</header>
|
||||
|
||||
<div class="app-body">
|
||||
<div class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
<ul class="nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLinkActive="active" [routerLink]="['/dashboard']">
|
||||
<i class="icon-speedometer"></i> Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLinkActive="active" [routerLink]="['/feedback']">
|
||||
<i class="icon-envelope-letter"></i> Enter Feedback
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLinkActive="active" [routerLink]="['/add-data']">
|
||||
<i class="icon-basket"></i> Add Transaction
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Main content -->
|
||||
<main class="main">
|
||||
|
||||
<!-- Breadcrumb -->
|
||||
<ol class="breadcrumb">
|
||||
<app-breadcrumbs></app-breadcrumbs>
|
||||
<!-- Breadcrumb Menu-->
|
||||
</ol>
|
||||
|
||||
<div class="container-fluid">
|
||||
<router-outlet></router-outlet>
|
||||
</div><!-- /.conainer-fluid -->
|
||||
</main>
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="app-footer">
|
||||
<a href="http://coreui.io">CoreUI</a> © 2017 creativeLabs.
|
||||
<span class="float-right">Powered by <a href="http://coreui.io">CoreUI</a></span>
|
||||
</footer>
|
48
src/app/layouts/full-layout.component.ts
Normal file
48
src/app/layouts/full-layout.component.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../providers/api-service';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
templateUrl: './full-layout.component.html',
|
||||
providers: [ApiService]
|
||||
})
|
||||
export class FullLayoutComponent implements OnInit {
|
||||
displayName: any;
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
private router: Router,
|
||||
) {}
|
||||
|
||||
public disabled = false;
|
||||
public status: {isopen: boolean} = {isopen: false};
|
||||
|
||||
public toggled(open: boolean): void {
|
||||
console.log('Dropdown is now: ', open);
|
||||
}
|
||||
|
||||
public toggleDropdown($event: MouseEvent): void {
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
this.status.isopen = !this.status.isopen;
|
||||
}
|
||||
|
||||
// getDisplayName function from api didnt work
|
||||
ngOnInit(): void {
|
||||
this.displayName = localStorage.getItem('displayname') || 'User';
|
||||
}
|
||||
|
||||
userLogout() {
|
||||
console.log('logout clicked');
|
||||
this.api
|
||||
.logout()
|
||||
.subscribe(
|
||||
result => {
|
||||
console.log('Logged out!');
|
||||
localStorage.clear();
|
||||
this.router.navigate(['/login']);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
12
src/app/layouts/simple-layout.component.ts
Normal file
12
src/app/layouts/simple-layout.component.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
template: '<router-outlet></router-outlet>',
|
||||
})
|
||||
export class SimpleLayoutComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void { }
|
||||
}
|
16
src/app/pages/404.component.html
Normal file
16
src/app/pages/404.component.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div class="app flex-row align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="clearfix">
|
||||
<h1 class="float-left display-3 mr-4">404</h1>
|
||||
<h4 class="pt-3">Oops! You're lost.</h4>
|
||||
<p class="text-muted">The page you are looking for was not found.</p>
|
||||
</div>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
17
src/app/pages/404.component.ts
Normal file
17
src/app/pages/404.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
templateUrl: '404.component.html'
|
||||
})
|
||||
export class P404Component {
|
||||
|
||||
constructor(
|
||||
private location: Location
|
||||
) {
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.location.back();
|
||||
}
|
||||
}
|
16
src/app/pages/500.component.html
Normal file
16
src/app/pages/500.component.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div class="app flex-row align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="clearfix">
|
||||
<h1 class="float-left display-3 mr-4">500</h1>
|
||||
<h4 class="pt-3">Houston, we have a problem!</h4>
|
||||
<p class="text-muted">The page you are looking for is temporarily unavailable.</p>
|
||||
</div>
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-primary btn-lg" type="button"(click)="goBack()">Go Back</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
17
src/app/pages/500.component.ts
Normal file
17
src/app/pages/500.component.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
templateUrl: '500.component.html'
|
||||
})
|
||||
export class P500Component {
|
||||
|
||||
constructor(
|
||||
private location: Location
|
||||
) {
|
||||
}
|
||||
|
||||
goBack(): void {
|
||||
this.location.back();
|
||||
}
|
||||
}
|
320
src/app/providers/api-service.ts
Normal file
320
src/app/providers/api-service.ts
Normal file
|
@ -0,0 +1,320 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Http } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { environment } from '../../environments/environment';
|
||||
import 'rxjs/add/operator/map';
|
||||
|
||||
/* this provider handles the interaction between server and client */
|
||||
|
||||
@Injectable()
|
||||
export class ApiService {
|
||||
private apiUrl = environment.apiUrl;
|
||||
private sessionKey: string = null;
|
||||
constructor(
|
||||
private http: Http,
|
||||
) {
|
||||
if (localStorage.getItem('sessionKey') ) {
|
||||
this.sessionKey = localStorage.getItem('sessionKey');
|
||||
}
|
||||
}
|
||||
|
||||
public post(url, data) {
|
||||
if ( this.sessionKey != null ) {
|
||||
data.session_key = this.sessionKey;
|
||||
}
|
||||
return this.http.post(
|
||||
this.apiUrl + url,
|
||||
data
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Login API
|
||||
|
||||
public getSessionKey() {
|
||||
console.log('get key');
|
||||
return this.sessionKey;
|
||||
}
|
||||
|
||||
public setSessionKey(key) {
|
||||
console.log('set key');
|
||||
this.sessionKey = key;
|
||||
localStorage.setItem('sessionKey', this.sessionKey);
|
||||
}
|
||||
|
||||
public removeSessionKey() {
|
||||
console.log('remove key');
|
||||
this.sessionKey = null;
|
||||
localStorage.removeItem('sessionKey');
|
||||
}
|
||||
|
||||
public register(data) {
|
||||
return this.http.post(
|
||||
this.apiUrl + '/register',
|
||||
data
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
public login(data) {
|
||||
let login_event = this.http.post(
|
||||
this.apiUrl + '/login',
|
||||
data
|
||||
).map( response => response.json() );
|
||||
login_event.subscribe(
|
||||
result => {
|
||||
this.setSessionKey(result.session_key);
|
||||
this.setUserInfo(
|
||||
result.email,
|
||||
result.display_name
|
||||
);
|
||||
this.setUserType(result.user_type)
|
||||
}
|
||||
);
|
||||
return login_event;
|
||||
}
|
||||
|
||||
public logout() {
|
||||
console.log(this.sessionKey);
|
||||
let key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/logout',
|
||||
{
|
||||
session_key : key,
|
||||
}
|
||||
).map( response => { this.removeSessionKey(); return response.json() } );
|
||||
}
|
||||
|
||||
// Submits feedback
|
||||
|
||||
public feedback(data) {
|
||||
data.app_name = 'Foodloop Web';
|
||||
data.package_name = 'Foodloop Web';
|
||||
data.version_code = 'dev';
|
||||
data.version_number = 'dev';
|
||||
console.log(data);
|
||||
return this.http.post(
|
||||
this.apiUrl + '/feedback',
|
||||
data
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Searches organisations used for transaction submission
|
||||
|
||||
public search(data) {
|
||||
data.session_key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/search',
|
||||
data
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Uploads a transaction
|
||||
|
||||
public upload(data) {
|
||||
data.session_key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/upload',
|
||||
data
|
||||
).map( response => response.json() )
|
||||
}
|
||||
|
||||
// Handles user data interaction
|
||||
|
||||
// Checks for login status
|
||||
|
||||
public hasLoggedIn() {
|
||||
return this.getSessionKey() ? true : false;
|
||||
}
|
||||
|
||||
// Pulls user info to store locally on login
|
||||
|
||||
public setUserInfo(
|
||||
email: string,
|
||||
display_name: string) {
|
||||
console.log("set UserInfo");
|
||||
localStorage.setItem('email',email);
|
||||
localStorage.setItem('displayname',display_name);
|
||||
}
|
||||
|
||||
// Sets usertype
|
||||
|
||||
public setUserType(user_type: string) {
|
||||
console.log("set UserType");
|
||||
localStorage.setItem('usertype',user_type);
|
||||
}
|
||||
|
||||
// Used for getting account details and updating
|
||||
|
||||
public accountFullLoad() {
|
||||
let key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/user',
|
||||
{ session_key : key },
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
public accountEditUpdate(data) {
|
||||
data.session_key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/user/account',
|
||||
data
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Deletes account details on logout
|
||||
|
||||
public removeUserInfo() {
|
||||
console.log("remove UserInfo");
|
||||
localStorage.removeItem('email');
|
||||
localStorage.removeItem('displayname');
|
||||
}
|
||||
|
||||
public getFullName() {
|
||||
console.log("get Full Name");
|
||||
localStorage.getItem('fullname');
|
||||
}
|
||||
|
||||
public getDisplayName() {
|
||||
console.log("get Display Name");
|
||||
localStorage.getItem('displayname');
|
||||
}
|
||||
|
||||
public getPostcode() {
|
||||
console.log("get Postcode");
|
||||
localStorage.getItem('postcode');
|
||||
}
|
||||
|
||||
public getYearOfBirth() {
|
||||
console.log("get Year of Birth");
|
||||
localStorage.getItem('yearofbirth');
|
||||
}
|
||||
|
||||
public getEmail() {
|
||||
console.log("get email");
|
||||
localStorage.getItem('email');
|
||||
}
|
||||
|
||||
// Leaderboard Api
|
||||
|
||||
public leaderboard_fetch(data) {
|
||||
let key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/stats/leaderboard',
|
||||
{
|
||||
session_key : key,
|
||||
type : data
|
||||
}
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Basic Customer User stats API
|
||||
public basicStats() {
|
||||
let key = this.sessionKey;
|
||||
return this.http.post(
|
||||
this.apiUrl + '/stats',
|
||||
{
|
||||
session_key : key,
|
||||
}
|
||||
).map( response => response.json() );
|
||||
}
|
||||
|
||||
// Fake Breadcrumb data
|
||||
|
||||
public breadcrumb_data(data) {
|
||||
return Observable.of(
|
||||
{
|
||||
"customersthismonth" : 196,
|
||||
"moneyspentthismonth" : 156.02,
|
||||
"pointstotal" : 506,
|
||||
"averagetransactiontoday" : 3.69
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Fake chart data to mimic
|
||||
|
||||
public graph_data(data) {
|
||||
return Observable.of(
|
||||
{
|
||||
// graphstoshow is on server and changes every hour, listing what snippets & graphs to display
|
||||
"elementstoshow" :
|
||||
{
|
||||
"graphs" :
|
||||
{
|
||||
customersthisweek : true,
|
||||
customerslastweek : true,
|
||||
customerslastmonth : true,
|
||||
customerslastyear : true,
|
||||
returningcustomerslastweek : true,
|
||||
returningcustomerslastmonth : true,
|
||||
returningcustomerslastyear : true,
|
||||
noofcustomerssector : true,
|
||||
percentofcustomerssector : true,
|
||||
pointsthisweek : true,
|
||||
percentlocalsuppliersvscompetitor : true,
|
||||
},
|
||||
"snippets" :
|
||||
{
|
||||
customersthismonth: true,
|
||||
moneyspentthismonth: true,
|
||||
pointstotal: true,
|
||||
averagetransactiontoday: true,
|
||||
percentownlocalsupplier : false,
|
||||
percentsinglecompetitorlocalsupplier : false,
|
||||
},
|
||||
},
|
||||
"data" :
|
||||
{
|
||||
"customersthisweek" :
|
||||
{
|
||||
day : ['Monday', 'tuesday','wednesday','thursday','friday','saturday','sunday'],
|
||||
customerno : [1,2,3,4,5,6,7],
|
||||
returningcustomerno : [1,1,2,3,4,5,4],
|
||||
},
|
||||
"customerslastweek" :
|
||||
{
|
||||
day : ['Monday', 'tuesday','wednesday','thursday','friday','saturday','sunday'],
|
||||
customerno : [7,6,5,4,3,2,1],
|
||||
returningcustomerno : [3,4,5,4,3,2,1],
|
||||
},
|
||||
// can take differing size arrays, so any month works. Example here is for April
|
||||
"customerslastmonth" :
|
||||
{
|
||||
day : ['April 1','April 2','April 3','April 4','April 5','April 6','April 7','April 8',
|
||||
'April 9','April 10','April 11','April 12','April 13','April 14','April 15','April 16',
|
||||
'April 17','April 18','April 19','April 20','April 21','April 22','April 23','April 24',
|
||||
'April 25','April 26','April 27','April 28','April 29','April 30'],
|
||||
customerno : [7,6,5,4,3,2,1,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],
|
||||
returningcustomerno : [4,5,4,3,2,1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
|
||||
},
|
||||
"customerslastyear" :
|
||||
{
|
||||
month : ['January','February','March','April','May','June','July','August','September','October','November','December'],
|
||||
customerno : [7,6,5,4,3,2,1,8,9,10,11,12],
|
||||
returningcustomerno : [3,2,4,2,1,1,1,6,4,8,5,12],
|
||||
},
|
||||
// If the number is potential or actual customers in their sector has yet to be determined
|
||||
"customersinsector" :
|
||||
{
|
||||
percent : 76,
|
||||
customerno : 34000,
|
||||
},
|
||||
"pointsthisweek" :
|
||||
{
|
||||
day : ['Monday', 'tuesday','wednesday','thursday','friday','saturday','sunday'],
|
||||
points : [1,2,3,4,5,6,7],
|
||||
},
|
||||
"pointslastweek" :
|
||||
{
|
||||
day : ['Monday', 'tuesday','wednesday','thursday','friday','saturday','sunday'],
|
||||
points : [1,2,3,4,5,6,7],
|
||||
},
|
||||
"localsuppliers" :
|
||||
{
|
||||
percentownlocal : 50,
|
||||
percentsinglecompetitorlocal : 65,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
13
src/app/providers/org-graphs.service.ts
Normal file
13
src/app/providers/org-graphs.service.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { ApiService } from './api-service';
|
||||
|
||||
@Injectable()
|
||||
export class OrgGraphsService {
|
||||
private orgGraphUrl = '/v1/organisation/graphs';
|
||||
|
||||
constructor(private api: ApiService) { }
|
||||
|
||||
public getGraph(name: string) {
|
||||
return this.api.post(this.orgGraphUrl, { graph: name });
|
||||
}
|
||||
}
|
17
src/app/shared/aside.directive.ts
Normal file
17
src/app/shared/aside.directive.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Directive, HostListener } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Allows the aside to be toggled via click.
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[appAsideMenuToggler]',
|
||||
})
|
||||
export class AsideToggleDirective {
|
||||
constructor() { }
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
document.querySelector('body').classList.toggle('aside-menu-hidden');
|
||||
}
|
||||
}
|
42
src/app/shared/breadcrumb.component.ts
Normal file
42
src/app/shared/breadcrumb.component.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
|
||||
import 'rxjs/add/operator/filter';
|
||||
|
||||
@Component({
|
||||
selector: 'app-breadcrumbs',
|
||||
template: `
|
||||
<ng-template ngFor let-breadcrumb [ngForOf]="breadcrumbs" let-last = last>
|
||||
<li class="breadcrumb-item"
|
||||
*ngIf="breadcrumb.label.title&&breadcrumb.url.substring(breadcrumb.url.length-1) == '/'||breadcrumb.label.title&&last"
|
||||
[ngClass]="{active: last}">
|
||||
<a *ngIf="!last" [routerLink]="breadcrumb.url">{{breadcrumb.label.title}}</a>
|
||||
<span *ngIf="last" [routerLink]="breadcrumb.url">{{breadcrumb.label.title}}</span>
|
||||
</li>
|
||||
</ng-template>`
|
||||
})
|
||||
export class BreadcrumbsComponent implements OnInit {
|
||||
breadcrumbs: Array<Object>;
|
||||
constructor(private router: Router, private route: ActivatedRoute) {}
|
||||
ngOnInit(): void {
|
||||
this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
|
||||
this.breadcrumbs = [];
|
||||
let currentRoute = this.route.root,
|
||||
url = '';
|
||||
do {
|
||||
const childrenRoutes = currentRoute.children;
|
||||
currentRoute = null;
|
||||
childrenRoutes.forEach(route => {
|
||||
if (route.outlet === 'primary') {
|
||||
const routeSnapshot = route.snapshot;
|
||||
url += '/' + routeSnapshot.url.map(segment => segment.path).join('/');
|
||||
this.breadcrumbs.push({
|
||||
label: route.snapshot.data,
|
||||
url: url
|
||||
});
|
||||
currentRoute = route;
|
||||
}
|
||||
});
|
||||
} while (currentRoute);
|
||||
});
|
||||
}
|
||||
}
|
31
src/app/shared/nav-dropdown.directive.ts
Normal file
31
src/app/shared/nav-dropdown.directive.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { Directive, HostListener, ElementRef } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[appNavDropdown]'
|
||||
})
|
||||
export class NavDropdownDirective {
|
||||
|
||||
constructor(private el: ElementRef) { }
|
||||
|
||||
toggle() {
|
||||
this.el.nativeElement.classList.toggle('open');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the dropdown to be toggled via click.
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[appNavDropdownToggle]'
|
||||
})
|
||||
export class NavDropdownToggleDirective {
|
||||
constructor(private dropdown: NavDropdownDirective) {}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
this.dropdown.toggle();
|
||||
}
|
||||
}
|
||||
|
||||
export const NAV_DROPDOWN_DIRECTIVES = [NavDropdownDirective, NavDropdownToggleDirective];
|
4
src/app/shared/org-result.component.html
Normal file
4
src/app/shared/org-result.component.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<td (click)="orgClick()">{{org.name}}</td>
|
||||
<td (click)="orgClick()">{{org.street_name}}</td>
|
||||
<td (click)="orgClick()">{{org.town}}</td>
|
||||
<td (click)="orgClick()">{{org.postcode}}</td>
|
24
src/app/shared/org-result.component.ts
Normal file
24
src/app/shared/org-result.component.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
interface OrgData {
|
||||
id: number;
|
||||
name: string;
|
||||
street_name: string;
|
||||
town: string;
|
||||
postcode: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: '[org-result]',
|
||||
templateUrl: 'org-result.component.html',
|
||||
})
|
||||
export class OrgResultComponent {
|
||||
@Input() public org: OrgData;
|
||||
@Output() public onClick = new EventEmitter();
|
||||
|
||||
public orgClick(): void {
|
||||
this.onClick.emit(
|
||||
this.org
|
||||
)
|
||||
}
|
||||
}
|
19
src/app/shared/org-table.component.html
Normal file
19
src/app/shared/org-table.component.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
<div class="form-group row">
|
||||
<label class="col-md-3 form-control-label" for="text-input"><strong>Organisation Search Results</strong></label>
|
||||
<div class="col-md-9">
|
||||
<span class="help-block"><strong>Select an Organisation from the table below</strong></span>
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Organisation Name</th>
|
||||
<th>Street Name</th>
|
||||
<th>Town</th>
|
||||
<th>Postcode</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr org-result *ngFor="let org of orgList" [org]="org" (onClick)="orgClick($event)"></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
23
src/app/shared/org-table.component.ts
Normal file
23
src/app/shared/org-table.component.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { OrgResultComponent } from '../shared/org-result.component';
|
||||
|
||||
interface OrgData {
|
||||
id: number;
|
||||
name: string;
|
||||
street_name: string;
|
||||
town: string;
|
||||
postcode: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'org-table',
|
||||
templateUrl: 'org-table.component.html',
|
||||
})
|
||||
export class OrgTableComponent {
|
||||
@Input() public orgList: Array<OrgData>;
|
||||
@Output() public onClick = new EventEmitter();
|
||||
|
||||
public orgClick(event: any): void {
|
||||
this.onClick.emit( event );
|
||||
}
|
||||
}
|
92
src/app/shared/sidebar.directive.ts
Normal file
92
src/app/shared/sidebar.directive.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
import { Directive, HostListener } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Allows the sidebar to be toggled via click.
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[appSidebarToggler]'
|
||||
})
|
||||
export class SidebarToggleDirective {
|
||||
constructor() { }
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
document.querySelector('body').classList.toggle('sidebar-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[appSidebarMinimizer]'
|
||||
})
|
||||
export class SidebarMinimizeDirective {
|
||||
constructor() { }
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
document.querySelector('body').classList.toggle('sidebar-minimized');
|
||||
}
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[appMobileSidebarToggler]'
|
||||
})
|
||||
export class MobileSidebarToggleDirective {
|
||||
constructor() { }
|
||||
|
||||
// Check if element has class
|
||||
private hasClass(target: any, elementClassName: string) {
|
||||
return new RegExp('(\\s|^)' + elementClassName + '(\\s|$)').test(target.className);
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
document.querySelector('body').classList.toggle('sidebar-mobile-show');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the off-canvas sidebar to be closed via click.
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[appSidebarClose]'
|
||||
})
|
||||
export class SidebarOffCanvasCloseDirective {
|
||||
constructor() { }
|
||||
|
||||
// Check if element has class
|
||||
private hasClass(target: any, elementClassName: string) {
|
||||
return new RegExp('(\\s|^)' + elementClassName + '(\\s|$)').test(target.className);
|
||||
}
|
||||
|
||||
// Toggle element class
|
||||
private toggleClass(elem: any, elementClassName: string) {
|
||||
let newClass = ' ' + elem.className.replace( /[\t\r\n]/g, ' ' ) + ' ';
|
||||
if (this.hasClass(elem, elementClassName)) {
|
||||
while (newClass.indexOf(' ' + elementClassName + ' ') >= 0 ) {
|
||||
newClass = newClass.replace( ' ' + elementClassName + ' ' , ' ' );
|
||||
}
|
||||
elem.className = newClass.replace(/^\s+|\s+$/g, '');
|
||||
} else {
|
||||
elem.className += ' ' + elementClassName;
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
toggleOpen($event: any) {
|
||||
$event.preventDefault();
|
||||
|
||||
if (this.hasClass(document.querySelector('body'), 'sidebar-off-canvas')) {
|
||||
this.toggleClass(document.querySelector('body'), 'sidebar-opened');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const SIDEBAR_TOGGLE_DIRECTIVES = [
|
||||
SidebarToggleDirective,
|
||||
SidebarMinimizeDirective,
|
||||
SidebarOffCanvasCloseDirective,
|
||||
MobileSidebarToggleDirective
|
||||
];
|
21
src/app/widgets/graph-widget.component.html
Normal file
21
src/app/widgets/graph-widget.component.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<div class="card card-inverse card-primary">
|
||||
<div class="card-block pb-0">
|
||||
<button type="button" class="btn btn-transparent p-0 float-right">
|
||||
<i [ngClass]="graphIcon"></i>
|
||||
</button>
|
||||
<h4 class="mb-0">{{ graphSum }}</h4>
|
||||
<p>{{ graphTitle }}</p>
|
||||
</div>
|
||||
<div class="chart-wrapper px-3" style="height:70px;">
|
||||
<canvas baseChart
|
||||
class="chart"
|
||||
[datasets]="lineChartData"
|
||||
[labels]="lineChartLabels"
|
||||
[options]="lineChartOptions"
|
||||
[colors]="lineChartColours"
|
||||
[legend]="lineChartLegend"
|
||||
[chartType]="lineChartType"
|
||||
(chartHover)="chartHovered($event)"
|
||||
(chartClick)="chartClicked($event)"></canvas>
|
||||
</div>
|
||||
</div>
|
115
src/app/widgets/graph-widget.component.ts
Normal file
115
src/app/widgets/graph-widget.component.ts
Normal file
|
@ -0,0 +1,115 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { OrgGraphsService } from '../providers/org-graphs.service';
|
||||
|
||||
interface ChartData {
|
||||
data: Array<number>;
|
||||
label: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'widget-graph',
|
||||
templateUrl: 'graph-widget.component.html',
|
||||
})
|
||||
export class GraphWidget implements OnInit {
|
||||
@Input() public graphName: string;
|
||||
@Input() public graphTitle = 'Graph';
|
||||
@Input() public graphIcon = 'icon-graph';
|
||||
|
||||
@Output() public graphHover = new EventEmitter();
|
||||
@Output() public graphClick = new EventEmitter();
|
||||
|
||||
public graphSum: Number = 0;
|
||||
|
||||
public lineChartData: Array<ChartData> = [
|
||||
{
|
||||
data: [],
|
||||
label: 'Series A'
|
||||
}
|
||||
];
|
||||
public lineChartLabels: Array<string>;
|
||||
public lineChartOptions: any = {
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'transparent'
|
||||
},
|
||||
ticks: {
|
||||
fontSize: 2,
|
||||
fontColor: 'transparent',
|
||||
}
|
||||
|
||||
}],
|
||||
yAxes: [{
|
||||
display: false,
|
||||
ticks: {
|
||||
display: false,
|
||||
}
|
||||
}],
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
borderWidth: 1
|
||||
},
|
||||
point: {
|
||||
radius: 4,
|
||||
hitRadius: 10,
|
||||
hoverRadius: 4,
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
};
|
||||
public lineChartColours: Array<any> = [
|
||||
{
|
||||
backgroundColor: '#20a8d8',
|
||||
borderColor: 'rgba(255,255,255,.55)'
|
||||
}
|
||||
];
|
||||
public lineChartLegend = false;
|
||||
public lineChartType = 'line';
|
||||
|
||||
|
||||
constructor(private graphService: OrgGraphsService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
if ( this.graphName == null ) {
|
||||
throw new Error('Attribute \'graphName\' is required on component \'widget-graph\'');
|
||||
}
|
||||
this.graphService.getGraph(this.graphName)
|
||||
.subscribe( result => this.setData(result.graph) );
|
||||
}
|
||||
|
||||
private setData(data: any) {
|
||||
this.setChartData(data.count);
|
||||
this.setChartLabels(data.day);
|
||||
}
|
||||
|
||||
private setChartData(data: Array<number>) {
|
||||
this.lineChartData[0].data = data;
|
||||
this.graphSum = data.reduce((a, b) => a + b, 0);
|
||||
// Set point size based on data
|
||||
if ( data.length < 15 ) {
|
||||
this.lineChartOptions.elements.point.radius = 4;
|
||||
this.lineChartOptions.elements.line.borderWidth = 1;
|
||||
} else {
|
||||
this.lineChartOptions.elements.point.radius = 2;
|
||||
this.lineChartOptions.elements.line.borderWidth = 2;
|
||||
}
|
||||
}
|
||||
|
||||
private setChartLabels(data: Array<string>) {
|
||||
this.lineChartLabels = data;
|
||||
}
|
||||
|
||||
// events
|
||||
public chartClicked(e: any): void {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
public chartHovered(e: any): void {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
0
src/assets/.gitkeep
Normal file
0
src/assets/.gitkeep
Normal file
0
src/assets/.npmignore
Normal file
0
src/assets/.npmignore
Normal file
2199
src/assets/css/font-awesome.css
vendored
Normal file
2199
src/assets/css/font-awesome.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
7
src/assets/css/font-awesome.css.map
Normal file
7
src/assets/css/font-awesome.css.map
Normal file
File diff suppressed because one or more lines are too long
4
src/assets/css/font-awesome.min.css
vendored
Normal file
4
src/assets/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
778
src/assets/css/simple-line-icons.css
Normal file
778
src/assets/css/simple-line-icons.css
Normal file
|
@ -0,0 +1,778 @@
|
|||
@font-face {
|
||||
font-family: 'simple-line-icons';
|
||||
src: url('../fonts/Simple-Line-Icons.eot?v=2.4.0');
|
||||
src: url('../fonts/Simple-Line-Icons.eot?v=2.4.0#iefix') format('embedded-opentype'), url('../fonts/Simple-Line-Icons.woff2?v=2.4.0') format('woff2'), url('../fonts/Simple-Line-Icons.ttf?v=2.4.0') format('truetype'), url('../fonts/Simple-Line-Icons.woff?v=2.4.0') format('woff'), url('../fonts/Simple-Line-Icons.svg?v=2.4.0#simple-line-icons') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/*
|
||||
Use the following CSS code if you want to have a class per icon.
|
||||
Instead of a list of all class selectors, you can use the generic [class*="icon-"] selector, but it's slower:
|
||||
*/
|
||||
.icon-user,
|
||||
.icon-people,
|
||||
.icon-user-female,
|
||||
.icon-user-follow,
|
||||
.icon-user-following,
|
||||
.icon-user-unfollow,
|
||||
.icon-login,
|
||||
.icon-logout,
|
||||
.icon-emotsmile,
|
||||
.icon-phone,
|
||||
.icon-call-end,
|
||||
.icon-call-in,
|
||||
.icon-call-out,
|
||||
.icon-map,
|
||||
.icon-location-pin,
|
||||
.icon-direction,
|
||||
.icon-directions,
|
||||
.icon-compass,
|
||||
.icon-layers,
|
||||
.icon-menu,
|
||||
.icon-list,
|
||||
.icon-options-vertical,
|
||||
.icon-options,
|
||||
.icon-arrow-down,
|
||||
.icon-arrow-left,
|
||||
.icon-arrow-right,
|
||||
.icon-arrow-up,
|
||||
.icon-arrow-up-circle,
|
||||
.icon-arrow-left-circle,
|
||||
.icon-arrow-right-circle,
|
||||
.icon-arrow-down-circle,
|
||||
.icon-check,
|
||||
.icon-clock,
|
||||
.icon-plus,
|
||||
.icon-minus,
|
||||
.icon-close,
|
||||
.icon-event,
|
||||
.icon-exclamation,
|
||||
.icon-organization,
|
||||
.icon-trophy,
|
||||
.icon-screen-smartphone,
|
||||
.icon-screen-desktop,
|
||||
.icon-plane,
|
||||
.icon-notebook,
|
||||
.icon-mustache,
|
||||
.icon-mouse,
|
||||
.icon-magnet,
|
||||
.icon-energy,
|
||||
.icon-disc,
|
||||
.icon-cursor,
|
||||
.icon-cursor-move,
|
||||
.icon-crop,
|
||||
.icon-chemistry,
|
||||
.icon-speedometer,
|
||||
.icon-shield,
|
||||
.icon-screen-tablet,
|
||||
.icon-magic-wand,
|
||||
.icon-hourglass,
|
||||
.icon-graduation,
|
||||
.icon-ghost,
|
||||
.icon-game-controller,
|
||||
.icon-fire,
|
||||
.icon-eyeglass,
|
||||
.icon-envelope-open,
|
||||
.icon-envelope-letter,
|
||||
.icon-bell,
|
||||
.icon-badge,
|
||||
.icon-anchor,
|
||||
.icon-wallet,
|
||||
.icon-vector,
|
||||
.icon-speech,
|
||||
.icon-puzzle,
|
||||
.icon-printer,
|
||||
.icon-present,
|
||||
.icon-playlist,
|
||||
.icon-pin,
|
||||
.icon-picture,
|
||||
.icon-handbag,
|
||||
.icon-globe-alt,
|
||||
.icon-globe,
|
||||
.icon-folder-alt,
|
||||
.icon-folder,
|
||||
.icon-film,
|
||||
.icon-feed,
|
||||
.icon-drop,
|
||||
.icon-drawer,
|
||||
.icon-docs,
|
||||
.icon-doc,
|
||||
.icon-diamond,
|
||||
.icon-cup,
|
||||
.icon-calculator,
|
||||
.icon-bubbles,
|
||||
.icon-briefcase,
|
||||
.icon-book-open,
|
||||
.icon-basket-loaded,
|
||||
.icon-basket,
|
||||
.icon-bag,
|
||||
.icon-action-undo,
|
||||
.icon-action-redo,
|
||||
.icon-wrench,
|
||||
.icon-umbrella,
|
||||
.icon-trash,
|
||||
.icon-tag,
|
||||
.icon-support,
|
||||
.icon-frame,
|
||||
.icon-size-fullscreen,
|
||||
.icon-size-actual,
|
||||
.icon-shuffle,
|
||||
.icon-share-alt,
|
||||
.icon-share,
|
||||
.icon-rocket,
|
||||
.icon-question,
|
||||
.icon-pie-chart,
|
||||
.icon-pencil,
|
||||
.icon-note,
|
||||
.icon-loop,
|
||||
.icon-home,
|
||||
.icon-grid,
|
||||
.icon-graph,
|
||||
.icon-microphone,
|
||||
.icon-music-tone-alt,
|
||||
.icon-music-tone,
|
||||
.icon-earphones-alt,
|
||||
.icon-earphones,
|
||||
.icon-equalizer,
|
||||
.icon-like,
|
||||
.icon-dislike,
|
||||
.icon-control-start,
|
||||
.icon-control-rewind,
|
||||
.icon-control-play,
|
||||
.icon-control-pause,
|
||||
.icon-control-forward,
|
||||
.icon-control-end,
|
||||
.icon-volume-1,
|
||||
.icon-volume-2,
|
||||
.icon-volume-off,
|
||||
.icon-calendar,
|
||||
.icon-bulb,
|
||||
.icon-chart,
|
||||
.icon-ban,
|
||||
.icon-bubble,
|
||||
.icon-camrecorder,
|
||||
.icon-camera,
|
||||
.icon-cloud-download,
|
||||
.icon-cloud-upload,
|
||||
.icon-envelope,
|
||||
.icon-eye,
|
||||
.icon-flag,
|
||||
.icon-heart,
|
||||
.icon-info,
|
||||
.icon-key,
|
||||
.icon-link,
|
||||
.icon-lock,
|
||||
.icon-lock-open,
|
||||
.icon-magnifier,
|
||||
.icon-magnifier-add,
|
||||
.icon-magnifier-remove,
|
||||
.icon-paper-clip,
|
||||
.icon-paper-plane,
|
||||
.icon-power,
|
||||
.icon-refresh,
|
||||
.icon-reload,
|
||||
.icon-settings,
|
||||
.icon-star,
|
||||
.icon-symbol-female,
|
||||
.icon-symbol-male,
|
||||
.icon-target,
|
||||
.icon-credit-card,
|
||||
.icon-paypal,
|
||||
.icon-social-tumblr,
|
||||
.icon-social-twitter,
|
||||
.icon-social-facebook,
|
||||
.icon-social-instagram,
|
||||
.icon-social-linkedin,
|
||||
.icon-social-pinterest,
|
||||
.icon-social-github,
|
||||
.icon-social-google,
|
||||
.icon-social-reddit,
|
||||
.icon-social-skype,
|
||||
.icon-social-dribbble,
|
||||
.icon-social-behance,
|
||||
.icon-social-foursqare,
|
||||
.icon-social-soundcloud,
|
||||
.icon-social-spotify,
|
||||
.icon-social-stumbleupon,
|
||||
.icon-social-youtube,
|
||||
.icon-social-dropbox,
|
||||
.icon-social-vkontakte,
|
||||
.icon-social-steam {
|
||||
font-family: 'simple-line-icons';
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
.icon-user:before {
|
||||
content: "\e005";
|
||||
}
|
||||
.icon-people:before {
|
||||
content: "\e001";
|
||||
}
|
||||
.icon-user-female:before {
|
||||
content: "\e000";
|
||||
}
|
||||
.icon-user-follow:before {
|
||||
content: "\e002";
|
||||
}
|
||||
.icon-user-following:before {
|
||||
content: "\e003";
|
||||
}
|
||||
.icon-user-unfollow:before {
|
||||
content: "\e004";
|
||||
}
|
||||
.icon-login:before {
|
||||
content: "\e066";
|
||||
}
|
||||
.icon-logout:before {
|
||||
content: "\e065";
|
||||
}
|
||||
.icon-emotsmile:before {
|
||||
content: "\e021";
|
||||
}
|
||||
.icon-phone:before {
|
||||
content: "\e600";
|
||||
}
|
||||
.icon-call-end:before {
|
||||
content: "\e048";
|
||||
}
|
||||
.icon-call-in:before {
|
||||
content: "\e047";
|
||||
}
|
||||
.icon-call-out:before {
|
||||
content: "\e046";
|
||||
}
|
||||
.icon-map:before {
|
||||
content: "\e033";
|
||||
}
|
||||
.icon-location-pin:before {
|
||||
content: "\e096";
|
||||
}
|
||||
.icon-direction:before {
|
||||
content: "\e042";
|
||||
}
|
||||
.icon-directions:before {
|
||||
content: "\e041";
|
||||
}
|
||||
.icon-compass:before {
|
||||
content: "\e045";
|
||||
}
|
||||
.icon-layers:before {
|
||||
content: "\e034";
|
||||
}
|
||||
.icon-menu:before {
|
||||
content: "\e601";
|
||||
}
|
||||
.icon-list:before {
|
||||
content: "\e067";
|
||||
}
|
||||
.icon-options-vertical:before {
|
||||
content: "\e602";
|
||||
}
|
||||
.icon-options:before {
|
||||
content: "\e603";
|
||||
}
|
||||
.icon-arrow-down:before {
|
||||
content: "\e604";
|
||||
}
|
||||
.icon-arrow-left:before {
|
||||
content: "\e605";
|
||||
}
|
||||
.icon-arrow-right:before {
|
||||
content: "\e606";
|
||||
}
|
||||
.icon-arrow-up:before {
|
||||
content: "\e607";
|
||||
}
|
||||
.icon-arrow-up-circle:before {
|
||||
content: "\e078";
|
||||
}
|
||||
.icon-arrow-left-circle:before {
|
||||
content: "\e07a";
|
||||
}
|
||||
.icon-arrow-right-circle:before {
|
||||
content: "\e079";
|
||||
}
|
||||
.icon-arrow-down-circle:before {
|
||||
content: "\e07b";
|
||||
}
|
||||
.icon-check:before {
|
||||
content: "\e080";
|
||||
}
|
||||
.icon-clock:before {
|
||||
content: "\e081";
|
||||
}
|
||||
.icon-plus:before {
|
||||
content: "\e095";
|
||||
}
|
||||
.icon-minus:before {
|
||||
content: "\e615";
|
||||
}
|
||||
.icon-close:before {
|
||||
content: "\e082";
|
||||
}
|
||||
.icon-event:before {
|
||||
content: "\e619";
|
||||
}
|
||||
.icon-exclamation:before {
|
||||
content: "\e617";
|
||||
}
|
||||
.icon-organization:before {
|
||||
content: "\e616";
|
||||
}
|
||||
.icon-trophy:before {
|
||||
content: "\e006";
|
||||
}
|
||||
.icon-screen-smartphone:before {
|
||||
content: "\e010";
|
||||
}
|
||||
.icon-screen-desktop:before {
|
||||
content: "\e011";
|
||||
}
|
||||
.icon-plane:before {
|
||||
content: "\e012";
|
||||
}
|
||||
.icon-notebook:before {
|
||||
content: "\e013";
|
||||
}
|
||||
.icon-mustache:before {
|
||||
content: "\e014";
|
||||
}
|
||||
.icon-mouse:before {
|
||||
content: "\e015";
|
||||
}
|
||||
.icon-magnet:before {
|
||||
content: "\e016";
|
||||
}
|
||||
.icon-energy:before {
|
||||
content: "\e020";
|
||||
}
|
||||
.icon-disc:before {
|
||||
content: "\e022";
|
||||
}
|
||||
.icon-cursor:before {
|
||||
content: "\e06e";
|
||||
}
|
||||
.icon-cursor-move:before {
|
||||
content: "\e023";
|
||||
}
|
||||
.icon-crop:before {
|
||||
content: "\e024";
|
||||
}
|
||||
.icon-chemistry:before {
|
||||
content: "\e026";
|
||||
}
|
||||
.icon-speedometer:before {
|
||||
content: "\e007";
|
||||
}
|
||||
.icon-shield:before {
|
||||
content: "\e00e";
|
||||
}
|
||||
.icon-screen-tablet:before {
|
||||
content: "\e00f";
|
||||
}
|
||||
.icon-magic-wand:before {
|
||||
content: "\e017";
|
||||
}
|
||||
.icon-hourglass:before {
|
||||
content: "\e018";
|
||||
}
|
||||
.icon-graduation:before {
|
||||
content: "\e019";
|
||||
}
|
||||
.icon-ghost:before {
|
||||
content: "\e01a";
|
||||
}
|
||||
.icon-game-controller:before {
|
||||
content: "\e01b";
|
||||
}
|
||||
.icon-fire:before {
|
||||
content: "\e01c";
|
||||
}
|
||||
.icon-eyeglass:before {
|
||||
content: "\e01d";
|
||||
}
|
||||
.icon-envelope-open:before {
|
||||
content: "\e01e";
|
||||
}
|
||||
.icon-envelope-letter:before {
|
||||
content: "\e01f";
|
||||
}
|
||||
.icon-bell:before {
|
||||
content: "\e027";
|
||||
}
|
||||
.icon-badge:before {
|
||||
content: "\e028";
|
||||
}
|
||||
.icon-anchor:before {
|
||||
content: "\e029";
|
||||
}
|
||||
.icon-wallet:before {
|
||||
content: "\e02a";
|
||||
}
|
||||
.icon-vector:before {
|
||||
content: "\e02b";
|
||||
}
|
||||
.icon-speech:before {
|
||||
content: "\e02c";
|
||||
}
|
||||
.icon-puzzle:before {
|
||||
content: "\e02d";
|
||||
}
|
||||
.icon-printer:before {
|
||||
content: "\e02e";
|
||||
}
|
||||
.icon-present:before {
|
||||
content: "\e02f";
|
||||
}
|
||||
.icon-playlist:before {
|
||||
content: "\e030";
|
||||
}
|
||||
.icon-pin:before {
|
||||
content: "\e031";
|
||||
}
|
||||
.icon-picture:before {
|
||||
content: "\e032";
|
||||
}
|
||||
.icon-handbag:before {
|
||||
content: "\e035";
|
||||
}
|
||||
.icon-globe-alt:before {
|
||||
content: "\e036";
|
||||
}
|
||||
.icon-globe:before {
|
||||
content: "\e037";
|
||||
}
|
||||
.icon-folder-alt:before {
|
||||
content: "\e039";
|
||||
}
|
||||
.icon-folder:before {
|
||||
content: "\e089";
|
||||
}
|
||||
.icon-film:before {
|
||||
content: "\e03a";
|
||||
}
|
||||
.icon-feed:before {
|
||||
content: "\e03b";
|
||||
}
|
||||
.icon-drop:before {
|
||||
content: "\e03e";
|
||||
}
|
||||
.icon-drawer:before {
|
||||
content: "\e03f";
|
||||
}
|
||||
.icon-docs:before {
|
||||
content: "\e040";
|
||||
}
|
||||
.icon-doc:before {
|
||||
content: "\e085";
|
||||
}
|
||||
.icon-diamond:before {
|
||||
content: "\e043";
|
||||
}
|
||||
.icon-cup:before {
|
||||
content: "\e044";
|
||||
}
|
||||
.icon-calculator:before {
|
||||
content: "\e049";
|
||||
}
|
||||
.icon-bubbles:before {
|
||||
content: "\e04a";
|
||||
}
|
||||
.icon-briefcase:before {
|
||||
content: "\e04b";
|
||||
}
|
||||
.icon-book-open:before {
|
||||
content: "\e04c";
|
||||
}
|
||||
.icon-basket-loaded:before {
|
||||
content: "\e04d";
|
||||
}
|
||||
.icon-basket:before {
|
||||
content: "\e04e";
|
||||
}
|
||||
.icon-bag:before {
|
||||
content: "\e04f";
|
||||
}
|
||||
.icon-action-undo:before {
|
||||
content: "\e050";
|
||||
}
|
||||
.icon-action-redo:before {
|
||||
content: "\e051";
|
||||
}
|
||||
.icon-wrench:before {
|
||||
content: "\e052";
|
||||
}
|
||||
.icon-umbrella:before {
|
||||
content: "\e053";
|
||||
}
|
||||
.icon-trash:before {
|
||||
content: "\e054";
|
||||
}
|
||||
.icon-tag:before {
|
||||
content: "\e055";
|
||||
}
|
||||
.icon-support:before {
|
||||
content: "\e056";
|
||||
}
|
||||
.icon-frame:before {
|
||||
content: "\e038";
|
||||
}
|
||||
.icon-size-fullscreen:before {
|
||||
content: "\e057";
|
||||
}
|
||||
.icon-size-actual:before {
|
||||
content: "\e058";
|
||||
}
|
||||
.icon-shuffle:before {
|
||||
content: "\e059";
|
||||
}
|
||||
.icon-share-alt:before {
|
||||
content: "\e05a";
|
||||
}
|
||||
.icon-share:before {
|
||||
content: "\e05b";
|
||||
}
|
||||
.icon-rocket:before {
|
||||
content: "\e05c";
|
||||
}
|
||||
.icon-question:before {
|
||||
content: "\e05d";
|
||||
}
|
||||
.icon-pie-chart:before {
|
||||
content: "\e05e";
|
||||
}
|
||||
.icon-pencil:before {
|
||||
content: "\e05f";
|
||||
}
|
||||
.icon-note:before {
|
||||
content: "\e060";
|
||||
}
|
||||
.icon-loop:before {
|
||||
content: "\e064";
|
||||
}
|
||||
.icon-home:before {
|
||||
content: "\e069";
|
||||
}
|
||||
.icon-grid:before {
|
||||
content: "\e06a";
|
||||
}
|
||||
.icon-graph:before {
|
||||
content: "\e06b";
|
||||
}
|
||||
.icon-microphone:before {
|
||||
content: "\e063";
|
||||
}
|
||||
.icon-music-tone-alt:before {
|
||||
content: "\e061";
|
||||
}
|
||||
.icon-music-tone:before {
|
||||
content: "\e062";
|
||||
}
|
||||
.icon-earphones-alt:before {
|
||||
content: "\e03c";
|
||||
}
|
||||
.icon-earphones:before {
|
||||
content: "\e03d";
|
||||
}
|
||||
.icon-equalizer:before {
|
||||
content: "\e06c";
|
||||
}
|
||||
.icon-like:before {
|
||||
content: "\e068";
|
||||
}
|
||||
.icon-dislike:before {
|
||||
content: "\e06d";
|
||||
}
|
||||
.icon-control-start:before {
|
||||
content: "\e06f";
|
||||
}
|
||||
.icon-control-rewind:before {
|
||||
content: "\e070";
|
||||
}
|
||||
.icon-control-play:before {
|
||||
content: "\e071";
|
||||
}
|
||||
.icon-control-pause:before {
|
||||
content: "\e072";
|
||||
}
|
||||
.icon-control-forward:before {
|
||||
content: "\e073";
|
||||
}
|
||||
.icon-control-end:before {
|
||||
content: "\e074";
|
||||
}
|
||||
.icon-volume-1:before {
|
||||
content: "\e09f";
|
||||
}
|
||||
.icon-volume-2:before {
|
||||
content: "\e0a0";
|
||||
}
|
||||
.icon-volume-off:before {
|
||||
content: "\e0a1";
|
||||
}
|
||||
.icon-calendar:before {
|
||||
content: "\e075";
|
||||
}
|
||||
.icon-bulb:before {
|
||||
content: "\e076";
|
||||
}
|
||||
.icon-chart:before {
|
||||
content: "\e077";
|
||||
}
|
||||
.icon-ban:before {
|
||||
content: "\e07c";
|
||||
}
|
||||
.icon-bubble:before {
|
||||
content: "\e07d";
|
||||
}
|
||||
.icon-camrecorder:before {
|
||||
content: "\e07e";
|
||||
}
|
||||
.icon-camera:before {
|
||||
content: "\e07f";
|
||||
}
|
||||
.icon-cloud-download:before {
|
||||
content: "\e083";
|
||||
}
|
||||
.icon-cloud-upload:before {
|
||||
content: "\e084";
|
||||
}
|
||||
.icon-envelope:before {
|
||||
content: "\e086";
|
||||
}
|
||||
.icon-eye:before {
|
||||
content: "\e087";
|
||||
}
|
||||
.icon-flag:before {
|
||||
content: "\e088";
|
||||
}
|
||||
.icon-heart:before {
|
||||
content: "\e08a";
|
||||
}
|
||||
.icon-info:before {
|
||||
content: "\e08b";
|
||||
}
|
||||
.icon-key:before {
|
||||
content: "\e08c";
|
||||
}
|
||||
.icon-link:before {
|
||||
content: "\e08d";
|
||||
}
|
||||
.icon-lock:before {
|
||||
content: "\e08e";
|
||||
}
|
||||
.icon-lock-open:before {
|
||||
content: "\e08f";
|
||||
}
|
||||
.icon-magnifier:before {
|
||||
content: "\e090";
|
||||
}
|
||||
.icon-magnifier-add:before {
|
||||
content: "\e091";
|
||||
}
|
||||
.icon-magnifier-remove:before {
|
||||
content: "\e092";
|
||||
}
|
||||
.icon-paper-clip:before {
|
||||
content: "\e093";
|
||||
}
|
||||
.icon-paper-plane:before {
|
||||
content: "\e094";
|
||||
}
|
||||
.icon-power:before {
|
||||
content: "\e097";
|
||||
}
|
||||
.icon-refresh:before {
|
||||
content: "\e098";
|
||||
}
|
||||
.icon-reload:before {
|
||||
content: "\e099";
|
||||
}
|
||||
.icon-settings:before {
|
||||
content: "\e09a";
|
||||
}
|
||||
.icon-star:before {
|
||||
content: "\e09b";
|
||||
}
|
||||
.icon-symbol-female:before {
|
||||
content: "\e09c";
|
||||
}
|
||||
.icon-symbol-male:before {
|
||||
content: "\e09d";
|
||||
}
|
||||
.icon-target:before {
|
||||
content: "\e09e";
|
||||
}
|
||||
.icon-credit-card:before {
|
||||
content: "\e025";
|
||||
}
|
||||
.icon-paypal:before {
|
||||
content: "\e608";
|
||||
}
|
||||
.icon-social-tumblr:before {
|
||||
content: "\e00a";
|
||||
}
|
||||
.icon-social-twitter:before {
|
||||
content: "\e009";
|
||||
}
|
||||
.icon-social-facebook:before {
|
||||
content: "\e00b";
|
||||
}
|
||||
.icon-social-instagram:before {
|
||||
content: "\e609";
|
||||
}
|
||||
.icon-social-linkedin:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
.icon-social-pinterest:before {
|
||||
content: "\e60b";
|
||||
}
|
||||
.icon-social-github:before {
|
||||
content: "\e60c";
|
||||
}
|
||||
.icon-social-google:before {
|
||||
content: "\e60d";
|
||||
}
|
||||
.icon-social-reddit:before {
|
||||
content: "\e60e";
|
||||
}
|
||||
.icon-social-skype:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
.icon-social-dribbble:before {
|
||||
content: "\e00d";
|
||||
}
|
||||
.icon-social-behance:before {
|
||||
content: "\e610";
|
||||
}
|
||||
.icon-social-foursqare:before {
|
||||
content: "\e611";
|
||||
}
|
||||
.icon-social-soundcloud:before {
|
||||
content: "\e612";
|
||||
}
|
||||
.icon-social-spotify:before {
|
||||
content: "\e613";
|
||||
}
|
||||
.icon-social-stumbleupon:before {
|
||||
content: "\e614";
|
||||
}
|
||||
.icon-social-youtube:before {
|
||||
content: "\e008";
|
||||
}
|
||||
.icon-social-dropbox:before {
|
||||
content: "\e00c";
|
||||
}
|
||||
.icon-social-vkontakte:before {
|
||||
content: "\e618";
|
||||
}
|
||||
.icon-social-steam:before {
|
||||
content: "\e620";
|
||||
}
|
BIN
src/assets/fonts/FontAwesome.otf
Normal file
BIN
src/assets/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
src/assets/fonts/Simple-Line-Icons.eot
Normal file
BIN
src/assets/fonts/Simple-Line-Icons.eot
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue