Upload all code
This commit is contained in:
parent
5df9958db6
commit
39f90b1897
36 changed files with 1649 additions and 0 deletions
149
app.js
Normal file
149
app.js
Normal file
|
@ -0,0 +1,149 @@
|
|||
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);
|
||||
|
||||
})
|
||||
|
2
debug.log
Normal file
2
debug.log
Normal file
|
@ -0,0 +1,2 @@
|
|||
[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
|
75
index.html
Normal file
75
index.html
Normal file
|
@ -0,0 +1,75 @@
|
|||
<!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>
|
3
pages/admin/admin.html
Normal file
3
pages/admin/admin.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div ui-view="header"></div>
|
||||
<div ui-view="sidebar"></div>
|
||||
<div ui-view="main"></div>
|
67
pages/admin/adminCtrl.js
Normal file
67
pages/admin/adminCtrl.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* 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);
|
||||
}
|
||||
});
|
||||
|
27
pages/admin/header.admin.html
Normal file
27
pages/admin/header.admin.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<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>
|
50
pages/admin/main.admin.html
Normal file
50
pages/admin/main.admin.html
Normal file
|
@ -0,0 +1,50 @@
|
|||
<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>
|
43
pages/admin/main.receipt.html
Normal file
43
pages/admin/main.receipt.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<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>
|
46
pages/admin/sidebar.admin.html
Normal file
46
pages/admin/sidebar.admin.html
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!-- 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>
|
353
pages/home/home.css
Normal file
353
pages/home/home.css
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
13
pages/home/home.html
Normal file
13
pages/home/home.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!-- 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>
|
18
pages/home/homeCtrl.js
Normal file
18
pages/home/homeCtrl.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
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";
|
||||
});
|
69
pages/login/login.html
Normal file
69
pages/login/login.html
Normal file
|
@ -0,0 +1,69 @@
|
|||
<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-->
|
||||
|
49
pages/login/loginCtrl.js
Normal file
49
pages/login/loginCtrl.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
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");
|
||||
}
|
||||
|
||||
});
|
7
pages/map/circles.json
Normal file
7
pages/map/circles.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{"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]}}
|
||||
]}
|
3
pages/map/map.css
Normal file
3
pages/map/map.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
#mapid { height: 180px; }
|
||||
|
||||
#map { width:600px; height: 600px }
|
15
pages/map/map.html
Normal file
15
pages/map/map.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<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>
|
61
pages/map/mapCtrl.js
Normal file
61
pages/map/mapCtrl.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
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 +")";
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
108
pages/receipt/receipt.html
Normal file
108
pages/receipt/receipt.html
Normal file
|
@ -0,0 +1,108 @@
|
|||
<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>
|
62
pages/receipt/receiptCtrl.js
Normal file
62
pages/receipt/receiptCtrl.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
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
|
||||
|
||||
});
|
27
pages/trader/header.trader.html
Normal file
27
pages/trader/header.trader.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<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>
|
6
pages/trader/main.trader.html
Normal file
6
pages/trader/main.trader.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
<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>
|
44
pages/trader/sidebar.trader.html
Normal file
44
pages/trader/sidebar.trader.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!-- 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>
|
0
pages/trader/trader.html
Normal file
0
pages/trader/trader.html
Normal file
15
pages/trader/traderCtrl.js
Normal file
15
pages/trader/traderCtrl.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
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;
|
||||
|
||||
});
|
24
pages/user/header.user.html
Normal file
24
pages/user/header.user.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<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>
|
BIN
pages/user/icon1.png
Normal file
BIN
pages/user/icon1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
28
pages/user/main.leaderboard.html
Normal file
28
pages/user/main.leaderboard.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<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>
|
21
pages/user/main.settings.html
Normal file
21
pages/user/main.settings.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<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>
|
90
pages/user/main.user.html
Normal file
90
pages/user/main.user.html
Normal file
|
@ -0,0 +1,90 @@
|
|||
<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>
|
30
pages/user/sidebar.user.html
Normal file
30
pages/user/sidebar.user.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!-- 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>
|
3
pages/user/user.html
Normal file
3
pages/user/user.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<user-header> </user-header>
|
||||
<user-sidebar> </user-sidebar>
|
||||
<user-main> </user-main>
|
65
pages/user/userCtrl.js
Normal file
65
pages/user/userCtrl.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
14
services/authService.js
Normal file
14
services/authService.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* 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;
|
||||
}
|
||||
});
|
56
services/chartService.js
Normal file
56
services/chartService.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* 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
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
6
services/uploadReceiptService.js
Normal file
6
services/uploadReceiptService.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* this service handles receipt upload process */
|
||||
app.service('uploadReceiptService', function () {
|
||||
this.uploadReceipt = function(){
|
||||
console.log("Upload successful");
|
||||
}
|
||||
});
|
Reference in a new issue