Merge pull request #48 from Pear-Trading/finn/customerdashboard

revamped customer dashboard
This commit is contained in:
Finn 2017-12-15 18:03:56 +00:00 committed by GitHub
commit 99e0a6c5d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 517 additions and 136 deletions

View file

@ -3,6 +3,10 @@
# Next Release # Next Release
* Changed Story Trail choosing to modals * Changed Story Trail choosing to modals
* Revamped snippets and graph widgets on customer dashboard
* Added local purchase pie chart for customer dashboard
* Added week by week purchase list for customer dashboard
* Added sector purchase amount list for customer dashboard
# v0.0.7 # v0.0.7

View file

@ -21,7 +21,10 @@ import { CustomerGuard } from './_guards/customer.guard';
import { ApiService } from './providers/api-service'; import { ApiService } from './providers/api-service';
import { OrgGraphsService } from './providers/org-graphs.service'; import { OrgGraphsService } from './providers/org-graphs.service';
import { CustGraphsService } from './providers/cust-graphs.service';
import { OrgSnippetsService } from './providers/org-snippets.service'; import { OrgSnippetsService } from './providers/org-snippets.service';
import { CustSnippetsService } from './providers/cust-snippets.service';
import { CustPiesService } from './providers/cust-pies.service';
// Layouts // Layouts
import { FullLayoutComponent } from './layouts/full-layout.component'; import { FullLayoutComponent } from './layouts/full-layout.component';
@ -65,6 +68,9 @@ import { DashboardModule } from './dashboard/dashboard.module';
ApiService, ApiService,
OrgGraphsService, OrgGraphsService,
OrgSnippetsService, OrgSnippetsService,
CustGraphsService,
CustSnippetsService,
CustPiesService,
{ {
provide: LocationStrategy, provide: LocationStrategy,
useClass: HashLocationStrategy useClass: HashLocationStrategy

View file

@ -1,129 +1,200 @@
<div class="animated fadeIn"> <div class="animated fadeIn">
<div class="card"> <snippet-bar-cust></snippet-bar-cust>
<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':'symbol':'1.2-2' }}</strong>
</li>
<li>
<div class="text-muted">Value to Local Economy</div>
<strong>{{ basicStats.user_sum * 2.3 | currency:'GBP':'symbol':'1.2-2' }}</strong>
</li>
</ul>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-sm-6 col-lg-3"> <div *ngFor="let widget of widgetList" class="col-sm-6 col-lg-3">
<div class="card card-inverse card-primary"> <widget-graph *ngIf="widget.type == 'graph'"
[graphName]="widget.name"
[graphTitle]="widget.title"
[graphIcon]="widget.icon"
[dataType]="widget.dataType">
</widget-graph>
</div><!--/.col-->
</div><!--/.row-->
<div class=row>
<div class="col-xl-4 col-md-6">
<panel-pie></panel-pie>
</div><!--/.col-->
<div class="col-xl-4 col-md-6">
<div class="card">
<div class="card-block"> <div class="card-block">
<div class="h4 mb-0">{{ basicStats.today_sum | currency:'GBP':'symbol':'1.2-2' }}</div> <div class="row">
<div>Total Today</div> <div class="col-12">
<!-- <div class="progress progress-white progress-xs mt-3"> <h4 class="card-title float-left mb-0">Purchases Per Week</h4>
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div> </div><!--/.col-->
</div><!--/.row-->
<div class="chart-wrapper">
<ul class="horizontal-bars type-2">
<li>
<span class="title">This Week</span>
<span class="value">{{ (weekPurchaseList.week_0 || 0 ) }} <span
class="text-muted small">({{ (weekPurchaseList.week_0 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_0 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">Last Week</span>
<span class="value">{{ weekPurchaseList.week_1 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_1 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_1 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">2 Weeks Ago</span>
<span class="value">{{ weekPurchaseList.week_2 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_2 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_2 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">3 Weeks Ago</span>
<span class="value">{{ weekPurchaseList.week_3 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_3 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_3 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">4 Weeks Ago</span>
<span class="value">{{ weekPurchaseList.week_4 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_4 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_4 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">5 Weeks Ago</span>
<span class="value">{{ weekPurchaseList.week_5 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_5 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_5 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
<li>
<span class="title">6 Weeks Ago</span>
<span class="value">{{ weekPurchaseList.week_6 || 0 }} <span
class="text-muted small">({{ (weekPurchaseList.week_6 || 0 ) / maxPurchase | percent:'1.0-0' }})</span></span>
<div class="bars">
<div class="progress" style="height: 6px;">
<div class="progress-bar bg-success" role="progressbar"
[style.width]="(weekPurchaseList.week_6 || 0 ) / maxPurchase | percent:'1.0-0'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
</ul>
</div> </div>
<small class="text-muted">Lorem ipsum dolor sit amet enim.</small> -->
</div> </div>
</div> </div>
</div><!--/.col--> </div><!--/.col-->
<div class="col-sm-6 col-lg-3"> <div class="col-xl-4">
<div class="card card-inverse card-primary"> <div class="card">
<div class="card-block"> <div class="card-block">
<div class="h4 mb-0">{{ basicStats.today_sum / (basicStats.today_count ? basicStats.today_count : 1) | currency:'GBP':'symbol':'1.2-2' }}</div> <div class="row">
<div>Avg. Spend Today</div> <div class="col-12">
<!-- <div class="progress progress-white progress-xs mt-3"> <h4 class="card-title float-left mb-0">Sector Purchase Amounts</h4>
<div class="progress-bar" role="progressbar" style="width: 100%" attr.aria-valuenow="100" aria-valuemin="0" aria-valuemax="100"></div> </div><!--/.col-->
</div><!--/.row-->
<div class="chart-wrapper">
<ul class="icons-list">
<li>
<i [ngClass]="sectorIcons [sectorLetters[0]] || 'icon-question'" class="bg-primary"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[0] || 'N/A' }}</div>
<div><small>{{ sectorNames [sectorLetters[0]] }}</small></div>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[0] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[1]] || 'icon-question'" class="bg-info"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[1] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[1]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[1] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[2]] || 'icon-question'" class="bg-warning"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[2] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[2]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[2] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[3]] || 'icon-question'" class="bg-danger"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[3] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[3]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[3] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[4]] || 'icon-question'" class="bg-success"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[4] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[4]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[4] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[5]] || 'icon-question'" class="bg-danger"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[5] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[5]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[5] || 'N/A' }}</strong>
</div>
</li>
<li>
<i [ngClass]="sectorIcons [sectorLetters[6]] || 'icon-question'" class="bg-warning"></i>
<div class="desc">
<div class="title">Sector {{ sectorLetters[6] || 'N/A' }}</div>
<small>{{ sectorNames [sectorLetters[6]] || 'N/A' }}</small>
</div>
<div class="value">
<div class="small text-muted">Bought from Sector</div>
<strong>{{ sectorPurchases[6] || 'N/A' }}</strong>
</div>
</li>
</ul>
</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':'symbol':'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':'symbol':'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':'symbol':'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':'symbol':'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':'symbol':'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':'symbol':'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> </div>
</div><!--/.col--> </div><!--/.col-->

View file

@ -2,15 +2,14 @@ import { Directive, Component, OnInit } from '@angular/core';
import { ApiService } from '../providers/api-service'; import { ApiService } from '../providers/api-service';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { GraphWidget } from '../widgets/graph-widget.component'; import { GraphWidget } from '../widgets/graph-widget.component';
import { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component';
import { PiePanel } from '../panels/pie-panel.component';
import { DataType } from '../shared/data-types.enum';
@Component({ @Component({
templateUrl: 'dashboard-customer.component.html' templateUrl: 'dashboard-customer.component.html'
}) })
export class DashboardCustomerComponent implements OnInit { export class DashboardCustomerComponent implements OnInit {
customersThisMonth: any;
moneySpentThisMonth: any;
pointsTotal: any;
averageTransactionToday: any;
/* Setting up dashboard's main variables*/ /* Setting up dashboard's main variables*/
name: any; name: any;
@ -19,27 +18,106 @@ export class DashboardCustomerComponent implements OnInit {
trends: any; trends: any;
myRank: any; myRank: any;
username: any; username: any;
maxPurchase: number = 0;
basicStats = { weekPurchaseList = {
today_sum: 0, week_0: 0,
today_count: 0, week_1: 0,
week_sum: 0, week_2: 0,
week_count: 0, week_3: 0,
month_sum: 0, week_4: 0,
month_count: 0, week_5: 0,
user_sum: 0, week_6: 0,
user_count: 0,
global_sum: 0,
global_count: 0,
user_position: 0,
}; };
sectorNames = {
A: 'Agriculture, Forestry & Fishing',
B: 'Mining & Quarrying',
C: 'Manufacturing',
D: 'Electricity, Gas, Steam & Air Conditioning',
E: 'Water & Waste Management',
F: 'Construction',
G: 'Wholesale & Retail Trade',
H: 'Transportation & Storage',
I: 'Accomodation & Food Services',
J: 'Information & Communication',
K: 'Financial & Insurance Activities',
L: 'Real Estate',
M: 'Professional, Scientfic & Technical',
N: 'Administrative & Support Services',
O: 'Public Administration, Defence & Social Security',
P: 'Education',
Q: 'Human Health & Social Work',
R: 'Arts, Entertainment & Recreation',
S: 'Other Service Activities',
T: 'Household Domestic Business',
}
sectorIcons = {
A: 'icon-drop',
B: 'icon-diamond',
C: 'icon-settings',
D: 'icon-energy',
E: 'icon-trash',
F: 'icon-wrench',
G: 'icon-tag',
H: 'icon-speedometer',
I: 'icon-cup',
J: 'icon-globe',
K: 'icon-credit-card',
L: 'icon-graph',
M: 'icon-chemistry',
N: 'icon-drawer',
O: 'icon-pie-chart',
P: 'icon-graduation',
Q: 'icon-support',
R: 'icon-film',
S: 'icon-calendar',
T: 'icon-home',
}
sectorLetters: string[] = [];
sectorPurchases: number[] = [];
sectorList: any;
// Graph widgets
public widgetList = [
{
type: 'graph',
name: 'total_last_week',
icon: 'icon-diamond',
title: 'Last Week Total',
dataType: DataType.currency,
},
{
type: 'graph',
name: 'avg_spend_last_week',
icon: 'icon-diamond',
title: 'Last Week Avg. Spend',
dataType: DataType.currency,
},
{
type: 'graph',
name: 'total_last_month',
title: 'Last Month Total',
dataType: DataType.currency,
},
{
type: 'graph',
name: 'avg_spend_last_month',
title: 'Last Month Avg. Spend',
dataType: DataType.currency,
},
];
constructor( constructor(
private api: ApiService, private api: ApiService,
) { ) {
this.api.basicStats().subscribe( this.api.basicStats().subscribe(
result => { result => {
this.basicStats = result; this.setWeekPurchaseList(result.weeks);
this.setSectorList(result.sectors);
}, },
error => { error => {
console.log('Retrieval Error'); console.log('Retrieval Error');
@ -48,6 +126,28 @@ export class DashboardCustomerComponent implements OnInit {
); );
} }
public setWeekPurchaseList (data: any) {
this.weekPurchaseList = {
week_0: data.purchases[0],
week_1: data.purchases[1],
week_2: data.purchases[2],
week_3: data.purchases[3],
week_4: data.purchases[4],
week_5: data.purchases[5],
week_6: data.purchases[6],
};
this.maxPurchase = Object.keys(this.weekPurchaseList).map(key => this.weekPurchaseList[key]).reduce((a,b) => {
if (! a) { a = 0 }
if (! b) { b = 0 }
return Math.max(a,b);
});
}
public setSectorList (data: any) {
this.sectorLetters = Object.keys(data.sectors).map(key => data.sectors[key]);
this.sectorPurchases = Object.keys(data.purchases).map(key => data.purchases[key]);
}
ngOnInit(): void { ngOnInit(): void {
} }
} }

View file

@ -6,7 +6,8 @@
[graphName]="widget.name" [graphName]="widget.name"
[graphTitle]="widget.title" [graphTitle]="widget.title"
[graphIcon]="widget.icon" [graphIcon]="widget.icon"
[dataType]="widget.dataType"></widget-graph> [dataType]="widget.dataType">
</widget-graph>
</div><!--/.col--> </div><!--/.col-->
</div><!--/.row--> </div><!--/.row-->
<panel-graph></panel-graph> <panel-graph></panel-graph>

View file

@ -23,7 +23,9 @@ import { TrailMapComponent } from './trail-map.component';
import { GraphWidget } from '../widgets/graph-widget.component'; import { GraphWidget } from '../widgets/graph-widget.component';
import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component'; import { OrgBarSnippetComponent } from '../snippets/org-snippet-bar.component';
import { CustBarSnippetComponent } from '../snippets/cust-snippet-bar.component';
import { GraphPanel } from '../panels/graph-panel.component'; import { GraphPanel } from '../panels/graph-panel.component';
import { PiePanel } from '../panels/pie-panel.component';
import { DashboardRoutingModule } from './dashboard.routing'; import { DashboardRoutingModule } from './dashboard.routing';
import { OrgResultComponent } from '../shared/org-result.component'; import { OrgResultComponent } from '../shared/org-result.component';
@ -69,7 +71,9 @@ import { environment } from '../../environments/environment';
FeedbackComponent, FeedbackComponent,
GraphWidget, GraphWidget,
OrgBarSnippetComponent, OrgBarSnippetComponent,
CustBarSnippetComponent,
GraphPanel, GraphPanel,
PiePanel,
], ],
providers: [ providers: [
CurrencyPipe, CurrencyPipe,

View file

@ -0,0 +1,27 @@
<div class="card">
<div class="card-block">
<div class="row">
<div class="col-sm-8">
<h4 class="card-title mb-0">Local Purchases</h4>
</div><!--/.col-->
<div class="col-sm-4 hidden-sm-down">
<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 active">
<input type="radio" name="options" id="option2" checked> Week
</label>
</div>
</div>
</div><!--/.col-->
</div><!--/.row-->
<div class="chart-wrapper">
<canvas baseChart class="chart"
[data]="doughnutChartData"
[labels]="doughnutChartLabels"
[legend]="chartLegend"
[chartType]="chartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)"></canvas>
</div>
</div>
</div>

View file

@ -0,0 +1,57 @@
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { CustPiesService } from '../providers/cust-pies.service';
import { DataType } from '../shared/data-types.enum';
import { ChartData } from '../_interfaces/chart-data';
@Component({
selector: 'panel-pie',
templateUrl: 'pie-panel.component.html',
})
export class PiePanel implements OnInit {
public chartType = 'doughnut';
public chartLegend = true;
public doughnutChartLabels: string[] = [];
public doughnutChartData: number[] = [];
//Old
// public mainChartElements = 7;
constructor(
private pieService: CustPiesService,
) { }
public ngOnInit(): void {
this.pieService.getPie()
.subscribe( result => this.setData(result.pie) );
}
private setData(data: any) {
this.doughnutChartData = Object.keys(data).map(key => data[key]);
// setTimeout is currently a workaround for ng2-charts labels
setTimeout(() => this.doughnutChartLabels = Object.keys(data), 0);
}
// 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);
}
}

View file

@ -0,0 +1,14 @@
import { Injectable } from '@angular/core';
import { ApiService } from './api-service';
@Injectable()
export class CustGraphsService {
private custGraphUrl = '/v1/customer/graphs';
constructor(private api: ApiService) { }
public getGraph(name: string, data: any = {}) {
data.graph = name;
return this.api.post(this.custGraphUrl, data);
}
}

View file

@ -0,0 +1,14 @@
import { Injectable } from '@angular/core';
import { ApiService } from './api-service';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class CustPiesService {
private custPieUrl = '/v1/customer/pies';
constructor(private api: ApiService) { }
public getPie(): Observable<any> {
return this.api.post(this.custPieUrl);
}
}

View file

@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
import { ApiService } from './api-service';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class CustSnippetsService {
private custSnippetsUrl = '/v1/customer/snippets';
constructor(private api: ApiService) { }
// This endpoint should mimic basicStats
public getData(): Observable<any> {
return this.api.post(this.custSnippetsUrl);
}
}

View file

@ -3,7 +3,7 @@ import { ApiService } from './api-service';
@Injectable() @Injectable()
export class OrgGraphsService { export class OrgGraphsService {
private orgGraphUrl = '/v1/organisation/graphs'; private orgGraphUrl = '/v1/customer/graphs';
constructor(private api: ApiService) { } constructor(private api: ApiService) { }

View file

@ -0,0 +1,27 @@
<div class="card">
<div class="card-footer">
<ul>
<li class="hidden-sm-down">
<div class="text-muted">My Points</div>
<strong>{{ userSum / 10 | number:'1.0-0' }}</strong>
</li>
<li class="hidden-sm-down">
<div class="text-muted">My Rank</div>
<div *ngIf="userPosition == 0" class="statuscontent">
<strong>Unranked</strong>
</div>
<div *ngIf="userPosition != 0" class="statuscontent">
<strong>{{ userPosition }}</strong>
</div>
</li>
<li class="hidden-sm-down">
<div class="text-muted">My Total Spend</div>
<strong>{{ userSum | currency:'GBP':'symbol':'1.2-2' }}</strong>
</li>
<li class="hidden-sm-down">
<div class="text-muted">Value to Local Economy</div>
<strong>{{ userSum * 2.3 | currency:'GBP':'symbol':'1.2-2' }}</strong>
</li>
</ul>
</div>
</div>

View file

@ -0,0 +1,26 @@
import { Component, OnInit } from '@angular/core';
import { CustSnippetsService } from '../providers/cust-snippets.service';
@Component({
selector: 'snippet-bar-cust',
templateUrl: 'cust-snippet-bar.component.html',
})
export class CustBarSnippetComponent implements OnInit {
public userSum = 0;
public userPosition = 0;
constructor(
private snippetsService: CustSnippetsService,
) { }
public ngOnInit(): void {
this.snippetsService.getData()
.subscribe(
result => {
this.userSum = result.snippets.user_sum;
this.userPosition = result.snippets.user_position;
}
);
}
}

View file

@ -35,12 +35,21 @@ export class GraphWidget implements OnInit {
maintainAspectRatio: false, maintainAspectRatio: false,
scales: { scales: {
xAxes: [{ xAxes: [{
type: 'time',
time: {
unit: 'day',
displayFormats: {
day: 'MMM D',
},
tooltipFormat: 'MMM D',
},
gridLines: { gridLines: {
color: 'transparent', color: 'transparent',
zeroLineColor: 'transparent' zeroLineColor: 'transparent'
}, },
ticks: { ticks: {
fontSize: 2, fontSize: 2,
source: 'data',
fontColor: 'transparent', fontColor: 'transparent',
} }
@ -106,6 +115,12 @@ export class GraphWidget implements OnInit {
private setData(data: any) { private setData(data: any) {
this.setChartData(data.data); this.setChartData(data.data);
this.setChartLabels(data.labels); this.setChartLabels(data.labels);
this.setChartBounds(data.bounds);
}
private setChartBounds(data) {
this.lineChartOptions.scales.xAxes[0].time.max = data.max;
this.lineChartOptions.scales.xAxes[0].time.min = data.min;
} }
private setChartData(data: Array<number>) { private setChartData(data: Array<number>) {