Add external dashboard to homepage.
This commit is contained in:
parent
b3586e460b
commit
63f0fe3070
@ -16,95 +16,8 @@
|
|||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<mat-card-title class="card-header">
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
CICADA DASHBOARD
|
<iframe class="embed-responsive-item" [src]="url | safe" allowfullscreen></iframe>
|
||||||
</mat-card-title>
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="card-body">
|
|
||||||
<mat-form-field appearance="outline">
|
|
||||||
<mat-label>Filter by location : </mat-label>
|
|
||||||
<mat-select class="ml-2" id="filterUser">
|
|
||||||
<div *ngFor="let county of locations; trackBy: trackByName">
|
|
||||||
<div *ngFor="let district of county.districts; trackBy: trackByName">
|
|
||||||
<mat-optgroup *ngFor="let location of district.locations; trackBy: trackByName" [label]="county.name + ' / ' + district.name + ' / ' + location.name">
|
|
||||||
<mat-option *ngFor="let village of location.villages; trackBy: trackByName" [value]="village">
|
|
||||||
{{village}}
|
|
||||||
</mat-option>
|
|
||||||
</mat-optgroup>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="card col-md-8">
|
|
||||||
<div class="card-body">
|
|
||||||
<div style="display: block">
|
|
||||||
<canvas baseChart
|
|
||||||
[datasets]="lineChartData"
|
|
||||||
[labels]="lineChartLabels"
|
|
||||||
[options]="lineChartOptions"
|
|
||||||
[colors]="lineChartColors"
|
|
||||||
[legend]="lineChartLegend"
|
|
||||||
[chartType]="lineChartType"
|
|
||||||
(chartHover)="chartHovered($event)"
|
|
||||||
(chartClick)="chartClicked($event)">
|
|
||||||
</canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="card-body row">
|
|
||||||
<div class="col-md-3 text-center">
|
|
||||||
<h4>MASTER WALLET BALANCE</h4>
|
|
||||||
<p>{{10000000 | number}} RCU</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 text-center">
|
|
||||||
<h4>TOTAL DISTRIBUTED</h4>
|
|
||||||
<p>{{disbursements * 1000 | number}} RCU</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 text-center">
|
|
||||||
<h4>TOTAL SPENT</h4>
|
|
||||||
<p>{{transactions * 100000 | number}} RCU</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 text-center">
|
|
||||||
<h4>TOTAL USERS</h4>
|
|
||||||
<p>{{users * 10 | number}} users</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="card-body">
|
|
||||||
<div style="display: block">
|
|
||||||
<canvas baseChart
|
|
||||||
[datasets]="barChartData"
|
|
||||||
[labels]="barChartLabels"
|
|
||||||
[options]="barChartOptions"
|
|
||||||
[legend]="barChartLegend"
|
|
||||||
[chartType]="barChartType">
|
|
||||||
</canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card col-md-4">
|
|
||||||
<div class="card-body text-center">
|
|
||||||
<h4>TRANSFER USAGES</h4>
|
|
||||||
<div style="display: block">
|
|
||||||
<canvas baseChart
|
|
||||||
[data]="transferUsagesChartData"
|
|
||||||
[labels]="transferUsagesChartLabels"
|
|
||||||
[options]="transferUsagesChartOptions"
|
|
||||||
[colors]="transferUsagesChartColors"
|
|
||||||
[legend]="transferUsagesChartLegend"
|
|
||||||
[chartType]="transferUsagesChartType">
|
|
||||||
</canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="card-body">
|
|
||||||
<h4 class="text-center">PARTNER LIVE FEED</h4>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core';
|
import {ChangeDetectionStrategy, Component} from '@angular/core';
|
||||||
import {Color, Label} from 'ng2-charts';
|
|
||||||
import {ChartDataSets, ChartOptions, ChartType} from 'chart.js';
|
|
||||||
import {LocationService, LoggingService} from '@app/_services';
|
|
||||||
import {ArraySum} from '@app/_helpers';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pages',
|
selector: 'app-pages',
|
||||||
@ -10,181 +6,8 @@ import {ArraySum} from '@app/_helpers';
|
|||||||
styleUrls: ['./pages.component.scss'],
|
styleUrls: ['./pages.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class PagesComponent implements OnInit {
|
export class PagesComponent {
|
||||||
disbursements: number = 0;
|
url: string = 'https://dashboard.sarafu.network/';
|
||||||
users: any;
|
|
||||||
locations: any;
|
|
||||||
transactions: number = 0;
|
|
||||||
public lineChartData: ChartDataSets[] = [
|
|
||||||
{ data: [65, 59, 80, 81, 56, 55, 40], label: 'User Registration'},
|
|
||||||
{ data: [28, 48, 40, 19, 86, 27, 90], label: 'Transaction Volumes'},
|
|
||||||
{ data: [180, 480, 770, 90, 1000, 270, 400], label: 'Token Disbursements', yAxisID: 'y-axis-1'}
|
|
||||||
];
|
|
||||||
|
|
||||||
public lineChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
constructor() { }
|
||||||
|
|
||||||
public lineChartOptions: (ChartOptions & { annotation: any }) = {
|
|
||||||
responsive: true,
|
|
||||||
scales: {
|
|
||||||
// We use this empty structure as a placeholder for dynamic theming.
|
|
||||||
xAxes: [{}],
|
|
||||||
yAxes: [
|
|
||||||
{
|
|
||||||
id: 'y-axis-0',
|
|
||||||
position: 'left',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'y-axis-1',
|
|
||||||
position: 'right',
|
|
||||||
gridLines: {
|
|
||||||
color: 'rgba(255,0,0,0.3)',
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
fontColor: 'red',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
annotation: {
|
|
||||||
annotations: [
|
|
||||||
{
|
|
||||||
type: 'line',
|
|
||||||
mode: 'vertical',
|
|
||||||
scaleID: 'x-axis-0',
|
|
||||||
value: 'March',
|
|
||||||
borderColor: 'orange',
|
|
||||||
borderWidth: 2,
|
|
||||||
label: {
|
|
||||||
enabled: true,
|
|
||||||
fontColor: 'orange',
|
|
||||||
content: 'LineAnno'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
public lineChartColors: Color[] = [
|
|
||||||
{ // grey
|
|
||||||
backgroundColor: 'rgba(148,159,177,0.2)',
|
|
||||||
borderColor: 'rgba(148,159,177,1)',
|
|
||||||
pointBackgroundColor: 'rgba(148,159,177,1)',
|
|
||||||
pointBorderColor: '#fff',
|
|
||||||
pointHoverBackgroundColor: '#fff',
|
|
||||||
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
|
|
||||||
},
|
|
||||||
{ // dark grey
|
|
||||||
backgroundColor: 'rgba(77,83,96,0.2)',
|
|
||||||
borderColor: 'rgba(77,83,96,1)',
|
|
||||||
pointBackgroundColor: 'rgba(77,83,96,1)',
|
|
||||||
pointBorderColor: '#fff',
|
|
||||||
pointHoverBackgroundColor: '#fff',
|
|
||||||
pointHoverBorderColor: 'rgba(77,83,96,1)'
|
|
||||||
},
|
|
||||||
{ // red
|
|
||||||
backgroundColor: 'rgba(255,0,0,0.3)',
|
|
||||||
borderColor: 'red',
|
|
||||||
pointBackgroundColor: 'rgba(148,159,177,1)',
|
|
||||||
pointBorderColor: '#fff',
|
|
||||||
pointHoverBackgroundColor: '#fff',
|
|
||||||
pointHoverBorderColor: 'rgba(148,159,177,0.8)'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
public lineChartLegend = true;
|
|
||||||
public lineChartType = 'line';
|
|
||||||
|
|
||||||
public barChartOptions: ChartOptions = {
|
|
||||||
responsive: true,
|
|
||||||
// We use these empty structures as placeholders for dynamic theming.
|
|
||||||
scales: { xAxes: [{}], yAxes: [{}] },
|
|
||||||
plugins: {
|
|
||||||
datalabels: {
|
|
||||||
anchor: 'end',
|
|
||||||
align: 'end',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public barChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
|
|
||||||
public barChartType: ChartType = 'horizontalBar';
|
|
||||||
public barChartLegend = true;
|
|
||||||
public barChartData: ChartDataSets[] = [
|
|
||||||
{ data: [65, 59, 80, 81, 56, 55, 40], label: 'New Users'},
|
|
||||||
{ data: [28, 48, 40, 19, 86, 27, 90], label: 'Recurrent Users'}
|
|
||||||
];
|
|
||||||
|
|
||||||
public transferUsagesChartLabels: Label[] = ['Food/Water', 'Fuel/Energy', 'Education', 'Health', 'Shop', 'Environment', 'Transport',
|
|
||||||
'Farming/Labour', 'Savings Group', 'Savings Group'];
|
|
||||||
public transferUsagesChartData: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
||||||
public transferUsagesChartType: ChartType = 'pie';
|
|
||||||
public transferUsagesChartOptions: ChartOptions = {
|
|
||||||
responsive: true,
|
|
||||||
legend: {
|
|
||||||
position: 'top',
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
datalabels: {
|
|
||||||
formatter: (value, ctx) => {
|
|
||||||
const label = ctx.chart.data.labels[ctx.dataIndex];
|
|
||||||
return label;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public transferUsagesChartLegend = true;
|
|
||||||
public transferUsagesChartColors = [
|
|
||||||
{
|
|
||||||
backgroundColor: [
|
|
||||||
'rgba(0,0,255,0.3)',
|
|
||||||
'rgba(255,0,0,0.3)',
|
|
||||||
'rgba(0,255,0,0.3)',
|
|
||||||
'rgba(255,0,255,0.3)',
|
|
||||||
'rgba(255,255,0,0.3)',
|
|
||||||
'rgba(0,255,255,0.3)',
|
|
||||||
'rgba(255,255,255,0.3)',
|
|
||||||
'rgba(255,100,0,0.3)',
|
|
||||||
'rgba(0,255,100,0.3)',
|
|
||||||
'rgba(100,0,255,0.3)'],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private locationService: LocationService,
|
|
||||||
private loggingService: LoggingService
|
|
||||||
) {
|
|
||||||
this.locationService.getLocations();
|
|
||||||
this.locationService.locationsSubject.subscribe(locations => {
|
|
||||||
this.locations = locations;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.newDataPoint([50, 80], 'August');
|
|
||||||
this.transferUsagesChartData = [18, 12, 10, 8, 6, 5, 5, 3, 2, 1];
|
|
||||||
this.disbursements = ArraySum.arraySum(this.lineChartData.find(data => data.label === 'Token Disbursements').data);
|
|
||||||
this.users = ArraySum.arraySum(this.barChartData.find(data => data.label === 'New Users').data);
|
|
||||||
this.transactions = ArraySum.arraySum(this.lineChartData.find(data => data.label === 'Transaction Volumes').data);
|
|
||||||
}
|
|
||||||
|
|
||||||
newDataPoint(dataArr: any[], label: string): void {
|
|
||||||
this.barChartData.forEach((dataset, index) => {
|
|
||||||
this.barChartData[index] = Object.assign({}, this.barChartData[index], {
|
|
||||||
data: [...this.barChartData[index].data, dataArr[index]]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
this.barChartLabels = [...this.barChartLabels, label];
|
|
||||||
}
|
|
||||||
|
|
||||||
public chartClicked({ event, active}: { event: MouseEvent, active: {}[] }): void {
|
|
||||||
this.loggingService.sendInfoLevelMessage(`Event: ${event}, ${active}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public chartHovered({ event, active }: { event: MouseEvent, active: {}[] }): void {
|
|
||||||
this.loggingService.sendInfoLevelMessage(`Event: ${event}, ${active}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
public trackByName(index, item): string {
|
|
||||||
return item.name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
8
src/app/shared/_pipes/safe.pipe.spec.ts
Normal file
8
src/app/shared/_pipes/safe.pipe.spec.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { SafePipe } from './safe.pipe';
|
||||||
|
|
||||||
|
describe('SafePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new SafePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
15
src/app/shared/_pipes/safe.pipe.ts
Normal file
15
src/app/shared/_pipes/safe.pipe.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import {DomSanitizer} from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'safe'
|
||||||
|
})
|
||||||
|
export class SafePipe implements PipeTransform {
|
||||||
|
|
||||||
|
constructor(private sanitizer: DomSanitizer) {}
|
||||||
|
|
||||||
|
transform(url: string, ...args: unknown[]): unknown {
|
||||||
|
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,8 +8,9 @@ import { MenuToggleDirective } from '@app/shared/_directives/menu-toggle.directi
|
|||||||
import {RouterModule} from '@angular/router';
|
import {RouterModule} from '@angular/router';
|
||||||
import {MatIconModule} from '@angular/material/icon';
|
import {MatIconModule} from '@angular/material/icon';
|
||||||
import {TokenRatioPipe} from '@app/shared/_pipes/token-ratio.pipe';
|
import {TokenRatioPipe} from '@app/shared/_pipes/token-ratio.pipe';
|
||||||
import { ErrorDialogComponent } from './error-dialog/error-dialog.component';
|
import { ErrorDialogComponent } from '@app/shared/error-dialog/error-dialog.component';
|
||||||
import {MatDialogModule} from '@angular/material/dialog';
|
import {MatDialogModule} from '@angular/material/dialog';
|
||||||
|
import { SafePipe } from '@app/shared/_pipes/safe.pipe';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -21,14 +22,16 @@ import {MatDialogModule} from '@angular/material/dialog';
|
|||||||
MenuSelectionDirective,
|
MenuSelectionDirective,
|
||||||
MenuToggleDirective,
|
MenuToggleDirective,
|
||||||
TokenRatioPipe,
|
TokenRatioPipe,
|
||||||
ErrorDialogComponent
|
ErrorDialogComponent,
|
||||||
|
SafePipe
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
TopbarComponent,
|
TopbarComponent,
|
||||||
FooterComponent,
|
FooterComponent,
|
||||||
SidebarComponent,
|
SidebarComponent,
|
||||||
MenuSelectionDirective,
|
MenuSelectionDirective,
|
||||||
TokenRatioPipe
|
TokenRatioPipe,
|
||||||
|
SafePipe
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
Loading…
Reference in New Issue
Block a user