Add accounts listings and details.
This commit is contained in:
parent
9836476c3a
commit
b38ca7cc46
@ -0,0 +1,262 @@
|
||||
<!-- Begin page -->
|
||||
<div class="wrapper">
|
||||
<app-sidebar></app-sidebar>
|
||||
|
||||
<!-- ============================================================== -->
|
||||
<!-- Start Page Content here -->
|
||||
<!-- ============================================================== -->
|
||||
|
||||
<div id="content">
|
||||
<app-topbar></app-topbar>
|
||||
<!-- Start Content-->
|
||||
<div class="container-fluid" appMenuSelection>
|
||||
<div class="card mb-3">
|
||||
<div class="row card-body">
|
||||
<h3>
|
||||
<mat-icon matPrefix>portrait</mat-icon>
|
||||
<strong> {{account?.name}} </strong>
|
||||
</h3>
|
||||
<p class="ml-auto">Balance: {{account?.balance}} RCU</p>
|
||||
<p class="ml-2">Created: {{account?.created}}</p>
|
||||
<p class="ml-2">Address: {{account?.address}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<app-disbursement *ngIf="isDisbursing"></app-disbursement>
|
||||
<div class="card mt-3 mb-3">
|
||||
<mat-card-title class="card-header">
|
||||
<div class="row">
|
||||
DETAILS
|
||||
<button mat-raised-button type="button" class="btn btn-outline-secondary ml-auto" (click)="addTransfer()"> NEW TRANSFER </button>
|
||||
<button mat-raised-button type="button" class="btn btn-outline-secondary ml-2"> SAVE </button>
|
||||
</div>
|
||||
</mat-card-title>
|
||||
<div class="card-body">
|
||||
<form>
|
||||
<div class="row form-inline">
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> STATUS </mat-label>
|
||||
<mat-select id="status" [(value)]="account.status">
|
||||
<mat-option value="false">Unapproved</mat-option>
|
||||
<mat-option value="true">Approved</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label class="mr-3">Payment Cycle Start Date : </mat-label>
|
||||
<input matInput type="text" id="startDate" placeholder="{{date}}" value="{{date}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> PAYMENT CYCLE </mat-label>
|
||||
<mat-select id="paymentCycle">
|
||||
<mat-option value="weekly">Weekly</mat-option>
|
||||
<mat-option value="daily">Daily</mat-option>
|
||||
<mat-option value="monthly">Monthly</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Name(s): *</mat-label>
|
||||
<input matInput type="text" id="givenNames" placeholder="{{account?.name}}" value="{{account?.name}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Phone Number: </mat-label>
|
||||
<input matInput type="text" id="phoneNumber" placeholder="{{account?.phone}}" value="{{account?.phone}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> ACCOUNT TYPE: </mat-label>
|
||||
<mat-select id="accountType" [(value)]="account.type">
|
||||
<mat-option value="user"> USER </mat-option>
|
||||
<mat-option value="cashier"> CASHIER </mat-option>
|
||||
<mat-option value="vendor"> VENDOR </mat-option>
|
||||
<mat-option value="tokenAgent"> TOKENAGENT </mat-option>
|
||||
<mat-option value="group"> GROUPACCOUNT </mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Failed Pin Attempts: </mat-label>
|
||||
<input matInput type="text" id="failedPinAttempts" placeholder="{{account?.failedPinAttempts}}" value="{{account?.failedPinAttempts}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Bio: </mat-label>
|
||||
<input matInput type="text" id="bio" placeholder="{{account?.bio}}" value="{{account?.bio}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> GENDER: </mat-label>
|
||||
<mat-select id="gender" [(value)]="account.gender">
|
||||
<mat-option value="male"> MALE </mat-option>
|
||||
<mat-option value="female"> FEMALE </mat-option>
|
||||
<mat-option value="other"> OTHER </mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> BUSINESS CATEGORY: </mat-label>
|
||||
<mat-select id="businessCategory">
|
||||
<mat-option value="food/water">Food/Water</mat-option>
|
||||
<mat-option value="fuel/energy">Fuel/Energy</mat-option>
|
||||
<mat-option value="education">Education</mat-option>
|
||||
<mat-option value="health">Health</mat-option>
|
||||
<mat-option value="shop">Shop</mat-option>
|
||||
<mat-option value="environment">Environment</mat-option>
|
||||
<mat-option value="transport">Transport</mat-option>
|
||||
<mat-option value="farming/labour">Farming/Labour</mat-option>
|
||||
<mat-option value="savings">Savings Group</mat-option>
|
||||
<mat-option value="other">Other</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<button mat-raised-button type="button" class="btn btn btn-outline-primary mb-3"> Add User KYC </button>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<button mat-raised-button type="button" class="btn btn btn-outline-success mb-3"> Reset Pin </button>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<button mat-raised-button type="button" class="btn btn-outline-danger"> Delete User </button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<mat-card-title class="card-header">
|
||||
USER
|
||||
</mat-card-title>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<caption> 1 user </caption>
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th scope="col">NAME</th>
|
||||
<th scope="col">ACCOUNT TYPE</th>
|
||||
<th scope="col">CREATED</th>
|
||||
<th scope="col">STATUS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr routerLink='/users/{{account.address}}'>
|
||||
<td>{{account.name}}</td>
|
||||
<td>{{account.type}}</td>
|
||||
<td>{{account.created}}</td>
|
||||
<td><span class="badge badge-primary badge-pill">{{account.status}}</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-transaction-details [transaction]="transaction"></app-transaction-details>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> TRANSACTION TYPE </mat-label>
|
||||
<mat-select id="transferSelect">
|
||||
<mat-option value="all" selected>ALL TRANSFERS</mat-option>
|
||||
<mat-option value="payments">PAYMENTS</mat-option>
|
||||
<mat-option value="exchange">EXCHANGE</mat-option>
|
||||
<mat-option value="disbursement">DISBURSEMENT</mat-option>
|
||||
<mat-option value="reclamation">RECLAMATION</mat-option>>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<p *ngIf="selection.selected.length > 0" class="ml-auto mr-3"><strong> {{selection.selected.length}} selected </strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> Filter </mat-label>
|
||||
<input matInput type="text" (keyup)="doFilter($event.target.value)" placeholder="Filter">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-table class="mat-elevation-z10" [dataSource]="dataSource" matSort matSortActive="sender"
|
||||
matSortDirection="asc" matSortDisableClear>
|
||||
<ng-container matColumnDef="sender">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Sender </mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction"> {{transaction.sender?.vcard.fn}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="recipient">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Recipient </mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction"> {{transaction.recipient?.vcard.fn}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="token">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Token </mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction"> {{transaction.token.name}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="value">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Value </mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction"> {{transaction.token.symbol + ' ' + transaction.value}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="view">
|
||||
<mat-header-cell *matHeaderCellDef> View Transaction </mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction">
|
||||
<button mat-raised-button type="button" class="btn btn-outline-primary" (click)="viewTransaction(transaction)">
|
||||
<i class="fa fa-eye"> VIEW </i>
|
||||
</button>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="select">
|
||||
<mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
||||
</mat-checkbox>
|
||||
</mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction">
|
||||
<mat-checkbox (click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(transaction) : null"
|
||||
[checked]="selection.isSelected(transaction)">
|
||||
</mat-checkbox>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let transaction; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-footer appMenuSelection></app-footer>
|
||||
</div>
|
||||
<!-- ============================================================== -->
|
||||
<!-- End Page content -->
|
||||
<!-- ============================================================== -->
|
||||
</div>
|
@ -0,0 +1,62 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AccountDetailsComponent } from './account-details.component';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {AccountsModule} from '../accounts.module';
|
||||
import {UserService} from '../../../_services';
|
||||
import {AppModule} from '../../../app.module';
|
||||
import {ActivatedRouteStub, FooterStubComponent, SidebarStubComponent, TopbarStubComponent} from '../../../../testing';
|
||||
import {UserServiceStub} from '../../../../testing';
|
||||
|
||||
describe('AccountDetailsComponent', () => {
|
||||
let component: AccountDetailsComponent;
|
||||
let fixture: ComponentFixture<AccountDetailsComponent>;
|
||||
let httpClient: HttpClient;
|
||||
let httpTestingController: HttpTestingController;
|
||||
let route: ActivatedRouteStub;
|
||||
|
||||
beforeEach(async () => {
|
||||
route = new ActivatedRouteStub();
|
||||
route.setParamMap({ id: 'test' });
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AccountDetailsComponent,
|
||||
FooterStubComponent,
|
||||
SidebarStubComponent,
|
||||
TopbarStubComponent
|
||||
],
|
||||
imports: [
|
||||
AccountsModule,
|
||||
AppModule,
|
||||
HttpClientTestingModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: ActivatedRoute, useValue: route },
|
||||
{ provide: UserService, useClass: UserServiceStub }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
httpClient = TestBed.inject(HttpClient);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AccountDetailsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('#addTransfer() should toggle #isDisbursing', () => {
|
||||
expect(component.isDisbursing).toBe(false, 'off at first');
|
||||
component.addTransfer();
|
||||
expect(component.isDisbursing).toBe(true, 'on after click');
|
||||
component.addTransfer();
|
||||
expect(component.isDisbursing).toBe(false, 'off after second click');
|
||||
});
|
||||
});
|
@ -0,0 +1,78 @@
|
||||
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {MatTableDataSource} from '@angular/material/table';
|
||||
import {Transaction} from '../../../_models';
|
||||
import {SelectionModel} from '@angular/cdk/collections';
|
||||
import {MatPaginator} from '@angular/material/paginator';
|
||||
import {MatSort} from '@angular/material/sort';
|
||||
import {TransactionService, UserService} from '../../../_services';
|
||||
import {ActivatedRoute, Params} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-details',
|
||||
templateUrl: './account-details.component.html',
|
||||
styleUrls: ['./account-details.component.scss']
|
||||
})
|
||||
export class AccountDetailsComponent implements OnInit, AfterViewInit {
|
||||
dataSource: MatTableDataSource<Transaction>;
|
||||
displayedColumns = ['sender', 'recipient', 'token', 'value', 'view', 'select'];
|
||||
initialSelection = [];
|
||||
allowMultiSelect = true;
|
||||
selection: SelectionModel<any>;
|
||||
date: string;
|
||||
time: number;
|
||||
isDisbursing = false;
|
||||
transaction: Transaction;
|
||||
account: any;
|
||||
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
constructor(
|
||||
private transactionService: TransactionService,
|
||||
private userService: UserService,
|
||||
private route: ActivatedRoute
|
||||
) {
|
||||
this.route.paramMap.subscribe((params: Params) => {
|
||||
this.account = this.userService.getUserById(params.get('id'));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.transactionService.transactionsSubject.subscribe(transactions => {
|
||||
this.dataSource = new MatTableDataSource<Transaction>(transactions);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
});
|
||||
this.selection = new SelectionModel<any>(this.allowMultiSelect, this.initialSelection);
|
||||
|
||||
const d = new Date();
|
||||
this.date = `${d.getDate()}/${d.getMonth()}/${d.getFullYear()}`;
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
addTransfer(): void {
|
||||
this.isDisbursing = !this.isDisbursing;
|
||||
}
|
||||
|
||||
isAllSelected(): boolean {
|
||||
const numSelected = this.selection.selected.length;
|
||||
const numRows = this.dataSource.data.length;
|
||||
return numSelected === numRows;
|
||||
}
|
||||
|
||||
masterToggle(): void {
|
||||
this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row));
|
||||
}
|
||||
|
||||
doFilter(value: string): void {
|
||||
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
||||
}
|
||||
|
||||
viewTransaction(transaction): void {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
}
|
21
src/app/pages/accounts/accounts-routing.module.ts
Normal file
21
src/app/pages/accounts/accounts-routing.module.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { AccountsComponent } from './accounts.component';
|
||||
import {CreateAccountComponent} from './create-account/create-account.component';
|
||||
import {ExportAccountsComponent} from './export-accounts/export-accounts.component';
|
||||
import {AccountDetailsComponent} from './account-details/account-details.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: AccountsComponent },
|
||||
{ path: 'create', component: CreateAccountComponent },
|
||||
{ path: 'export', component: ExportAccountsComponent },
|
||||
{ path: ':id', component: AccountDetailsComponent },
|
||||
{ path: '**', redirectTo: '', pathMatch: 'full' }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AccountsRoutingModule { }
|
113
src/app/pages/accounts/accounts.component.html
Normal file
113
src/app/pages/accounts/accounts.component.html
Normal file
@ -0,0 +1,113 @@
|
||||
<!-- Begin page -->
|
||||
<div class="wrapper">
|
||||
<app-sidebar></app-sidebar>
|
||||
|
||||
<!-- ============================================================== -->
|
||||
<!-- Start Page Content here -->
|
||||
<!-- ============================================================== -->
|
||||
|
||||
<div id="content">
|
||||
<app-topbar></app-topbar>
|
||||
<!-- Start Content-->
|
||||
<div class="container-fluid" appMenuSelection>
|
||||
<app-disbursement *ngIf="isDisbursing"></app-disbursement>
|
||||
<div class="card">
|
||||
<mat-card-title class="card-header">
|
||||
Accounts
|
||||
</mat-card-title>
|
||||
<div class="card-body">
|
||||
<div *ngIf="selection.selected.length <= 0" class="row card-header">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> ACCOUNT TYPE </mat-label>
|
||||
<mat-select id="typeSelect">
|
||||
<mat-option value="all" selected>ALL</mat-option>
|
||||
<mat-option value="user">USER</mat-option>
|
||||
<mat-option value="cashier">CASHIER</mat-option>
|
||||
<mat-option value="vendor">VENDOR</mat-option>
|
||||
<mat-option value="tokenagent">TOKENAGENT</mat-option>
|
||||
<mat-option value="groupaccount">GROUPACCOUNT</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button routerLink="/accounts/create" type="button" class="btn btn-outline-secondary ml-auto">
|
||||
<mat-icon>add</mat-icon>
|
||||
ADD NEW </button>
|
||||
<button mat-raised-button routerLink="/accounts/export" type="button" class="btn btn-outline-secondary ml-2"> EXPORT </button>
|
||||
</div>
|
||||
<div *ngIf="selection.selected.length > 0 && !isDisbursing" class="row card-header">
|
||||
<p><strong> {{selection.selected.length}} selected </strong></p>
|
||||
<button mat-raised-button type="button" class="btn btn-outline-secondary ml-auto" (click)="addTransfer()"> NEW TRANSFER </button>
|
||||
<button mat-raised-button type="button" class="btn btn-outline-secondary ml-2"> APPROVE </button>
|
||||
<button mat-raised-button routerLink="/accounts/export" type="button" class="btn btn-outline-secondary ml-2"> EXPORT </button>
|
||||
</div>
|
||||
<div *ngIf="selection.selected.length > 0 && isDisbursing" class="row card-header">
|
||||
<p><strong> {{selection.selected.length}} selected </strong></p>
|
||||
<button mat-raised-button routerLink="/accounts/export" type="button" class="btn btn-outline-secondary ml-auto"> EXPORT </button>
|
||||
</div>
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> Filter </mat-label>
|
||||
<input matInput type="text" (keyup)="doFilter($event.target.value)" placeholder="Filter">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-table class="mat-elevation-z10" [dataSource]="dataSource" matSort matSortActive="created"
|
||||
matSortDirection="desc" matSortDisableClear>
|
||||
<ng-container matColumnDef="name">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> NAME </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="phone">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> PHONE NUMBER </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"> {{user.phone}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="created">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> CREATED </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"> {{user.created}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="balance">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> BALANCE </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"> {{user.balance}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> STATUS </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"><span class="badge badge-primary badge-pill"> {{user.status}} </span></mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="failedPinAttempts">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> FAILED PIN ATTEMPTS </mat-header-cell>
|
||||
<mat-cell *matCellDef="let user"> {{user.failedPinAttempts}} </mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="select">
|
||||
<mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox (change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected">
|
||||
</mat-checkbox>
|
||||
</mat-header-cell>
|
||||
<mat-cell *matCellDef="let transaction">
|
||||
<mat-checkbox (click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(transaction) : null"
|
||||
[checked]="selection.isSelected(transaction)">
|
||||
</mat-checkbox>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let account; columns: displayedColumns" (click)="viewAccount(account)"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator [pageSize]="10" [pageSizeOptions]="[10, 20, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-footer appMenuSelection></app-footer>
|
||||
</div>
|
||||
<!-- ============================================================== -->
|
||||
<!-- End Page content -->
|
||||
<!-- ============================================================== -->
|
||||
</div>
|
0
src/app/pages/accounts/accounts.component.scss
Normal file
0
src/app/pages/accounts/accounts.component.scss
Normal file
48
src/app/pages/accounts/accounts.component.spec.ts
Normal file
48
src/app/pages/accounts/accounts.component.spec.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AccountsComponent } from './accounts.component';
|
||||
import {FooterStubComponent, SidebarStubComponent, TopbarStubComponent, UserServiceStub} from '../../../testing';
|
||||
import {AccountsModule} from './accounts.module';
|
||||
import {AppModule} from '../../app.module';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';
|
||||
import {UserService} from '../../_services';
|
||||
|
||||
describe('AccountsComponent', () => {
|
||||
let component: AccountsComponent;
|
||||
let fixture: ComponentFixture<AccountsComponent>;
|
||||
let httpClient: HttpClient;
|
||||
let httpTestingController: HttpTestingController;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AccountsComponent,
|
||||
FooterStubComponent,
|
||||
SidebarStubComponent,
|
||||
TopbarStubComponent
|
||||
],
|
||||
imports: [
|
||||
AccountsModule,
|
||||
AppModule,
|
||||
HttpClientTestingModule,
|
||||
],
|
||||
providers: [
|
||||
{ provide: UserService, useClass: UserServiceStub }
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
httpClient = TestBed.inject(HttpClient);
|
||||
httpTestingController = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AccountsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
61
src/app/pages/accounts/accounts.component.ts
Normal file
61
src/app/pages/accounts/accounts.component.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {MatTableDataSource} from '@angular/material/table';
|
||||
import {SelectionModel} from '@angular/cdk/collections';
|
||||
import {MatPaginator} from '@angular/material/paginator';
|
||||
import {MatSort} from '@angular/material/sort';
|
||||
import {UserService} from '../../_services';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-accounts',
|
||||
templateUrl: './accounts.component.html',
|
||||
styleUrls: ['./accounts.component.scss']
|
||||
})
|
||||
export class AccountsComponent implements OnInit, AfterViewInit{
|
||||
dataSource: MatTableDataSource<any>;
|
||||
displayedColumns = ['name', 'phone', 'created', 'balance', 'status', 'failedPinAttempts', 'select'];
|
||||
initialSelection = [];
|
||||
allowMultiSelect = true;
|
||||
selection: SelectionModel<any>;
|
||||
isDisbursing = false;
|
||||
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private router: Router
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.dataSource = new MatTableDataSource<any>(this.userService.users);
|
||||
this.selection = new SelectionModel<any>(this.allowMultiSelect, this.initialSelection);
|
||||
}
|
||||
|
||||
addTransfer(): void {
|
||||
this.isDisbursing = true;
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
isAllSelected(): boolean {
|
||||
const numSelected = this.selection.selected.length;
|
||||
const numRows = this.dataSource.data.length;
|
||||
return numSelected === numRows;
|
||||
}
|
||||
|
||||
masterToggle(): void {
|
||||
this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row));
|
||||
}
|
||||
|
||||
doFilter(value: string): void {
|
||||
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
||||
}
|
||||
|
||||
viewAccount(account): void {
|
||||
this.router.navigateByUrl(`/accounts/${account.id}`);
|
||||
}
|
||||
}
|
45
src/app/pages/accounts/accounts.module.ts
Normal file
45
src/app/pages/accounts/accounts.module.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { AccountsRoutingModule } from './accounts-routing.module';
|
||||
import { AccountsComponent } from './accounts.component';
|
||||
import {SharedModule} from '../../shared/shared.module';
|
||||
import { AccountDetailsComponent } from './account-details/account-details.component';
|
||||
import {DataTablesModule} from 'angular-datatables';
|
||||
import { CreateAccountComponent } from './create-account/create-account.component';
|
||||
import { DisbursementComponent } from './disbursement/disbursement.component';
|
||||
import { ExportAccountsComponent } from './export-accounts/export-accounts.component';
|
||||
import {MatTableModule} from '@angular/material/table';
|
||||
import {MatSortModule} from '@angular/material/sort';
|
||||
import {MatCheckboxModule} from '@angular/material/checkbox';
|
||||
import {MatPaginatorModule} from '@angular/material/paginator';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatFormFieldModule} from '@angular/material/form-field';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatCardModule} from '@angular/material/card';
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {TransactionsModule} from '../transactions/transactions.module';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [AccountsComponent, AccountDetailsComponent, CreateAccountComponent, DisbursementComponent, ExportAccountsComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
AccountsRoutingModule,
|
||||
SharedModule,
|
||||
DataTablesModule,
|
||||
MatTableModule,
|
||||
MatSortModule,
|
||||
MatCheckboxModule,
|
||||
MatPaginatorModule,
|
||||
MatInputModule,
|
||||
MatFormFieldModule,
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatIconModule,
|
||||
MatSelectModule,
|
||||
TransactionsModule
|
||||
]
|
||||
})
|
||||
export class AccountsModule { }
|
@ -0,0 +1,120 @@
|
||||
<!-- Begin page -->
|
||||
<div class="wrapper">
|
||||
<app-sidebar></app-sidebar>
|
||||
|
||||
<!-- ============================================================== -->
|
||||
<!-- Start Page Content here -->
|
||||
<!-- ============================================================== -->
|
||||
|
||||
<div id="content">
|
||||
<app-topbar></app-topbar>
|
||||
<!-- Start Content-->
|
||||
<div class="container-fluid" appMenuSelection>
|
||||
<div class="card">
|
||||
<mat-card-title class="card-header text-center">
|
||||
CREATE A USER ACCOUNT
|
||||
</mat-card-title>
|
||||
<div class="card-body">
|
||||
<form class="row form-inline">
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Account Type: </mat-label>
|
||||
<mat-select id="accountType">
|
||||
<mat-option value="user">USER</mat-option>
|
||||
<mat-option value="cashier">CASHIER</mat-option>
|
||||
<mat-option value="vendor">VENDOR</mat-option>
|
||||
<mat-option value="tokenagent">TOKENAGENT</mat-option>
|
||||
<mat-option value="groupaccount">GROUPACCOUNT</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>ID Number: </mat-label>
|
||||
<input matInput type="text" id="idNumber" placeholder="ID Number">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Phone Number: </mat-label>
|
||||
<input matInput type="text" id="phoneNumber" placeholder="Phone Number">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Given Name(s):* </mat-label>
|
||||
<input matInput type="text" id="givenNames" placeholder="Given Names">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Family/Surname: </mat-label>
|
||||
<input matInput type="text" id="surname" placeholder="Surname">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Directory Entry: </mat-label>
|
||||
<input matInput type="text" id="directoryEntry" placeholder="Directory Entry">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Location: </mat-label>
|
||||
<input matInput type="text" id="location" placeholder="Location">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Gender: </mat-label>
|
||||
<mat-select id="gender">
|
||||
<mat-option value="female">FEMALE</mat-option>
|
||||
<mat-option value="male">MALE</mat-option>
|
||||
<mat-option value="other">OTHER</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Referrer Phone Number: </mat-label>
|
||||
<input matInput type="text" id="referredBy" placeholder="Reffered By">
|
||||
</mat-form-field><br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-lg-4">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Business Category: </mat-label>
|
||||
<mat-select id="businessCategory">
|
||||
<mat-option value="food/water">Food/Water</mat-option>
|
||||
<mat-option value="fuel/energy">Fuel/Energy</mat-option>
|
||||
<mat-option value="education">Education</mat-option>
|
||||
<mat-option value="health">Health</mat-option>
|
||||
<mat-option value="shop">Shop</mat-option>
|
||||
<mat-option value="environment">Environment</mat-option>
|
||||
<mat-option value="transport">Transport</mat-option>
|
||||
<mat-option value="farming/labour">Farming/Labour</mat-option>
|
||||
<mat-option value="savings">Savings Group</mat-option>
|
||||
<mat-option value="other">Other</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<button mat-raised-button type="submit" class="btn btn-outline-primary ml-3">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-footer appMenuSelection></app-footer>
|
||||
</div>
|
||||
<!-- ============================================================== -->
|
||||
<!-- End Page content -->
|
||||
<!-- ============================================================== -->
|
||||
</div>
|
@ -0,0 +1,38 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CreateAccountComponent } from './create-account.component';
|
||||
import {AccountsModule} from '../accounts.module';
|
||||
import {AppModule} from '../../../app.module';
|
||||
import {FooterStubComponent, SidebarStubComponent, TopbarStubComponent} from '../../../../testing';
|
||||
|
||||
|
||||
describe('CreateAccountComponent', () => {
|
||||
let component: CreateAccountComponent;
|
||||
let fixture: ComponentFixture<CreateAccountComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
CreateAccountComponent,
|
||||
FooterStubComponent,
|
||||
SidebarStubComponent,
|
||||
TopbarStubComponent
|
||||
],
|
||||
imports: [
|
||||
AccountsModule,
|
||||
AppModule
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CreateAccountComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-account',
|
||||
templateUrl: './create-account.component.html',
|
||||
styleUrls: ['./create-account.component.scss']
|
||||
})
|
||||
export class CreateAccountComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
NEW TRANSFER
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form>
|
||||
<div class="row">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label> ACCOUNT TYPE </mat-label>
|
||||
<mat-select id="accountType">
|
||||
<mat-option value="disbursement">DISBURSEMENT</mat-option>
|
||||
<mat-option value="transfer">TRANSFER</mat-option>
|
||||
<mat-option value="deposit">DEPOSIT</mat-option>
|
||||
<mat-option value="reclamation">RECLAMATION</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<button mat-raised-button type="button" class="btn btn-outline-secondary ml-auto mr-2"> CANCEL </button>
|
||||
</div>
|
||||
<div class="row form-inline">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Enter Amount: </mat-label>
|
||||
<input matInput type="text" id="amount" placeholder="Amount">
|
||||
</mat-form-field>
|
||||
<button mat-raised-button type="submit" class="btn btn-outline-primary ml-3" >CREATE TRANSFER </button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,37 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DisbursementComponent } from './disbursement.component';
|
||||
import {AccountsModule} from '../accounts.module';
|
||||
import {AppModule} from '../../../app.module';
|
||||
import {FooterStubComponent, SidebarStubComponent, TopbarStubComponent} from '../../../../testing';
|
||||
|
||||
describe('DisbursementComponent', () => {
|
||||
let component: DisbursementComponent;
|
||||
let fixture: ComponentFixture<DisbursementComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
DisbursementComponent,
|
||||
FooterStubComponent,
|
||||
SidebarStubComponent,
|
||||
TopbarStubComponent
|
||||
],
|
||||
imports: [
|
||||
AccountsModule,
|
||||
AppModule
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DisbursementComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-disbursement',
|
||||
templateUrl: './disbursement.component.html',
|
||||
styleUrls: ['./disbursement.component.scss']
|
||||
})
|
||||
export class DisbursementComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
<!-- Begin page -->
|
||||
<div class="wrapper">
|
||||
<app-sidebar></app-sidebar>
|
||||
|
||||
<!-- ============================================================== -->
|
||||
<!-- Start Page Content here -->
|
||||
<!-- ============================================================== -->
|
||||
|
||||
<div id="content">
|
||||
<app-topbar></app-topbar>
|
||||
<!-- Start Content-->
|
||||
<div class="container-fluid" appMenuSelection>
|
||||
<div class="card">
|
||||
<mat-card-title class="card-header">
|
||||
EXPORT ACCOUNTS
|
||||
</mat-card-title>
|
||||
<div class="card-body">
|
||||
<form>
|
||||
<div class="form-inline mb-2">
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Export : </mat-label>
|
||||
<mat-select id="accountType">
|
||||
<mat-option value="vendors">VENDORS</mat-option>
|
||||
<mat-option value="partners">PARTNERS</mat-option>
|
||||
<mat-option value="selected">SELECTED</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="form-inline mb-3">
|
||||
<div class="form-group form-check">
|
||||
<label class="form-check-label mr-2" for="transfers">Include transfers?</label>
|
||||
<mat-checkbox id="transfers"></mat-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<button mat-raised-button type="submit" class="btn btn-outline-primary"> EXPORT </button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<app-footer appMenuSelection></app-footer>
|
||||
</div>
|
||||
<!-- ============================================================== -->
|
||||
<!-- End Page content -->
|
||||
<!-- ============================================================== -->
|
||||
</div>
|
@ -0,0 +1,37 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ExportAccountsComponent } from './export-accounts.component';
|
||||
import {AccountsModule} from '../accounts.module';
|
||||
import {AppModule} from '../../../app.module';
|
||||
import {FooterStubComponent, SidebarStubComponent, TopbarStubComponent} from '../../../../testing';
|
||||
|
||||
describe('ExportAccountsComponent', () => {
|
||||
let component: ExportAccountsComponent;
|
||||
let fixture: ComponentFixture<ExportAccountsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
ExportAccountsComponent,
|
||||
FooterStubComponent,
|
||||
SidebarStubComponent,
|
||||
TopbarStubComponent
|
||||
],
|
||||
imports: [
|
||||
AccountsModule,
|
||||
AppModule
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ExportAccountsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-export-accounts',
|
||||
templateUrl: './export-accounts.component.html',
|
||||
styleUrls: ['./export-accounts.component.scss']
|
||||
})
|
||||
export class ExportAccountsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user