diff --git a/src/app/pages/accounts/account-details/account-details.component.html b/src/app/pages/accounts/account-details/account-details.component.html new file mode 100644 index 0000000..6bfcf15 --- /dev/null +++ b/src/app/pages/accounts/account-details/account-details.component.html @@ -0,0 +1,262 @@ + +
+ + + + + + +
+ + +
+
+
+

+ portrait + {{account?.name}} +

+

Balance: {{account?.balance}} RCU

+

Created: {{account?.created}}

+

Address: {{account?.address}}

+
+
+ +
+ +
+ DETAILS + + +
+
+
+
+
+
+ + STATUS + + Unapproved + Approved + + +
+ +
+ + Payment Cycle Start Date : + + +
+ +
+ + PAYMENT CYCLE + + Weekly + Daily + Monthly + + +
+ +
+ + Name(s): * + + +
+ +
+ + Phone Number: + + +
+ +
+ + ACCOUNT TYPE: + + USER + CASHIER + VENDOR + TOKENAGENT + GROUPACCOUNT + + +
+ +
+ + Failed Pin Attempts: + + +
+ +
+ + Bio: + + +
+ +
+ + GENDER: + + MALE + FEMALE + OTHER + + +
+ +
+ + BUSINESS CATEGORY: + + Food/Water + Fuel/Energy + Education + Health + Shop + Environment + Transport + Farming/Labour + Savings Group + Other + + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+ + USER + +
+
+ + + + + + + + + + + + + + + + + + +
1 user
NAMEACCOUNT TYPECREATEDSTATUS
{{account.name}}{{account.type}}{{account.created}}{{account.status}}
+
+
+
+ +
+
+
+ + TRANSACTION TYPE + + ALL TRANSFERS + PAYMENTS + EXCHANGE + DISBURSEMENT + RECLAMATION> + + +

{{selection.selected.length}} selected

+
+
+ +
+ + Filter + + search + + + + + Sender + {{transaction.sender?.vcard.fn}} + + + + Recipient + {{transaction.recipient?.vcard.fn}} + + + + Token + {{transaction.token.name}} + + + + Value + {{transaction.token.symbol + ' ' + transaction.value}} + + + + View Transaction + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + +
diff --git a/src/app/pages/accounts/account-details/account-details.component.scss b/src/app/pages/accounts/account-details/account-details.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/accounts/account-details/account-details.component.spec.ts b/src/app/pages/accounts/account-details/account-details.component.spec.ts new file mode 100644 index 0000000..a4828ef --- /dev/null +++ b/src/app/pages/accounts/account-details/account-details.component.spec.ts @@ -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; + 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'); + }); +}); diff --git a/src/app/pages/accounts/account-details/account-details.component.ts b/src/app/pages/accounts/account-details/account-details.component.ts new file mode 100644 index 0000000..dec70e8 --- /dev/null +++ b/src/app/pages/accounts/account-details/account-details.component.ts @@ -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; + displayedColumns = ['sender', 'recipient', 'token', 'value', 'view', 'select']; + initialSelection = []; + allowMultiSelect = true; + selection: SelectionModel; + 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(transactions); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + }); + this.selection = new SelectionModel(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; + } +} diff --git a/src/app/pages/accounts/accounts-routing.module.ts b/src/app/pages/accounts/accounts-routing.module.ts new file mode 100644 index 0000000..c3590d4 --- /dev/null +++ b/src/app/pages/accounts/accounts-routing.module.ts @@ -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 { } diff --git a/src/app/pages/accounts/accounts.component.html b/src/app/pages/accounts/accounts.component.html new file mode 100644 index 0000000..1599410 --- /dev/null +++ b/src/app/pages/accounts/accounts.component.html @@ -0,0 +1,113 @@ + +
+ + + + + + +
+ + +
+ +
+ + Accounts + +
+
+ + ACCOUNT TYPE + + ALL + USER + CASHIER + VENDOR + TOKENAGENT + GROUPACCOUNT + + + + +
+
+

{{selection.selected.length}} selected

+ + + +
+
+

{{selection.selected.length}} selected

+ +
+ + + Filter + + search + + + + + NAME + {{user.name}} + + + + PHONE NUMBER + {{user.phone}} + + + + CREATED + {{user.created}} + + + + BALANCE + {{user.balance}} + + + + STATUS + {{user.status}} + + + + FAILED PIN ATTEMPTS + {{user.failedPinAttempts}} + + + + + + + + + + + + + + + + + + +
+
+
+ +
+ + + +
diff --git a/src/app/pages/accounts/accounts.component.scss b/src/app/pages/accounts/accounts.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/accounts/accounts.component.spec.ts b/src/app/pages/accounts/accounts.component.spec.ts new file mode 100644 index 0000000..c1434fe --- /dev/null +++ b/src/app/pages/accounts/accounts.component.spec.ts @@ -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; + 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(); + }); +}); diff --git a/src/app/pages/accounts/accounts.component.ts b/src/app/pages/accounts/accounts.component.ts new file mode 100644 index 0000000..28c9f0b --- /dev/null +++ b/src/app/pages/accounts/accounts.component.ts @@ -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; + displayedColumns = ['name', 'phone', 'created', 'balance', 'status', 'failedPinAttempts', 'select']; + initialSelection = []; + allowMultiSelect = true; + selection: SelectionModel; + isDisbursing = false; + + @ViewChild(MatPaginator) paginator: MatPaginator; + @ViewChild(MatSort) sort: MatSort; + + constructor( + private userService: UserService, + private router: Router + ) { } + + ngOnInit(): void { + this.dataSource = new MatTableDataSource(this.userService.users); + this.selection = new SelectionModel(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}`); + } +} diff --git a/src/app/pages/accounts/accounts.module.ts b/src/app/pages/accounts/accounts.module.ts new file mode 100644 index 0000000..399fb0e --- /dev/null +++ b/src/app/pages/accounts/accounts.module.ts @@ -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 { } diff --git a/src/app/pages/accounts/create-account/create-account.component.html b/src/app/pages/accounts/create-account/create-account.component.html new file mode 100644 index 0000000..6911571 --- /dev/null +++ b/src/app/pages/accounts/create-account/create-account.component.html @@ -0,0 +1,120 @@ + +
+ + + + + + +
+ + +
+
+ + CREATE A USER ACCOUNT + +
+
+
+ + Account Type: + + USER + CASHIER + VENDOR + TOKENAGENT + GROUPACCOUNT + +
+
+ +
+ + ID Number: + + +
+ +
+ + Phone Number: + +
+
+ +
+ + Given Name(s):* + +
+
+ +
+ + Family/Surname: + +
+
+ +
+ + Directory Entry: + +
+
+ +
+ + Location: + +
+
+ +
+ + Gender: + + FEMALE + MALE + OTHER + +
+
+ +
+ + Referrer Phone Number: + +
+
+ +
+ + Business Category: + + Food/Water + Fuel/Energy + Education + Health + Shop + Environment + Transport + Farming/Labour + Savings Group + Other + + +
+ + +
+
+
+
+ +
+ + + +
diff --git a/src/app/pages/accounts/create-account/create-account.component.scss b/src/app/pages/accounts/create-account/create-account.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/accounts/create-account/create-account.component.spec.ts b/src/app/pages/accounts/create-account/create-account.component.spec.ts new file mode 100644 index 0000000..9d271ba --- /dev/null +++ b/src/app/pages/accounts/create-account/create-account.component.spec.ts @@ -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; + + 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(); + }); +}); diff --git a/src/app/pages/accounts/create-account/create-account.component.ts b/src/app/pages/accounts/create-account/create-account.component.ts new file mode 100644 index 0000000..ebca636 --- /dev/null +++ b/src/app/pages/accounts/create-account/create-account.component.ts @@ -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 { + } + +} diff --git a/src/app/pages/accounts/disbursement/disbursement.component.html b/src/app/pages/accounts/disbursement/disbursement.component.html new file mode 100644 index 0000000..0925c91 --- /dev/null +++ b/src/app/pages/accounts/disbursement/disbursement.component.html @@ -0,0 +1,28 @@ +
+
+ NEW TRANSFER +
+
+
+
+ + ACCOUNT TYPE + + DISBURSEMENT + TRANSFER + DEPOSIT + RECLAMATION + + + +
+
+ + Enter Amount: + + + +
+
+
+
diff --git a/src/app/pages/accounts/disbursement/disbursement.component.scss b/src/app/pages/accounts/disbursement/disbursement.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/accounts/disbursement/disbursement.component.spec.ts b/src/app/pages/accounts/disbursement/disbursement.component.spec.ts new file mode 100644 index 0000000..b3a74a5 --- /dev/null +++ b/src/app/pages/accounts/disbursement/disbursement.component.spec.ts @@ -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; + + 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(); + }); +}); diff --git a/src/app/pages/accounts/disbursement/disbursement.component.ts b/src/app/pages/accounts/disbursement/disbursement.component.ts new file mode 100644 index 0000000..88b917a --- /dev/null +++ b/src/app/pages/accounts/disbursement/disbursement.component.ts @@ -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 { + } + +} diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.html b/src/app/pages/accounts/export-accounts/export-accounts.component.html new file mode 100644 index 0000000..4803124 --- /dev/null +++ b/src/app/pages/accounts/export-accounts/export-accounts.component.html @@ -0,0 +1,45 @@ + +
+ + + + + + +
+ + +
+
+ + EXPORT ACCOUNTS + +
+
+
+ + Export : + + VENDORS + PARTNERS + SELECTED + + +
+
+
+ + +
+
+ +
+
+
+
+ +
+ + + +
diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.scss b/src/app/pages/accounts/export-accounts/export-accounts.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.spec.ts b/src/app/pages/accounts/export-accounts/export-accounts.component.spec.ts new file mode 100644 index 0000000..a990fcb --- /dev/null +++ b/src/app/pages/accounts/export-accounts/export-accounts.component.spec.ts @@ -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; + + 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(); + }); +}); diff --git a/src/app/pages/accounts/export-accounts/export-accounts.component.ts b/src/app/pages/accounts/export-accounts/export-accounts.component.ts new file mode 100644 index 0000000..cc96402 --- /dev/null +++ b/src/app/pages/accounts/export-accounts/export-accounts.component.ts @@ -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 { + } + +}