### File

`src/app/pages/accounts/account-details/account-details.component.ts`

### Implements

`OnInit`

### Metadata

changeDetection | `ChangeDetectionStrategy.OnPush`
selector | `app-account-details`
styleUrls | `./account-details.component.scss`
templateUrl | `./account-details.component.html`

### Index

###### Properties
account accountAddress accountInfoForm accounts accountStatus accountsType accountTypes area areaNames areaType areaTypes bloxbergLink categories category genders matcher submitted tokenSymbol transaction transactions transactionsDataSource transactionsDefaultPageSize transactionsDisplayedColumns transactionsPageSizeOptions transactionsType transactionsTypes transactionTablePaginator transactionTableSort userDataSource userDisplayedColumns usersDefaultPageSize usersPageSizeOptions userTablePaginator userTableSort
###### Methods
copyAddress doTransactionFilter doUserFilter downloadCsv filterAccounts filterTransactions Async ngOnInit resetPin Async saveInfo viewAccount viewTransaction
###### Accessors
accountInfoFormStub

### Constructor

`constructor(formBuilder: FormBuilder, locationService: LocationService, transactionService: TransactionService, userService: UserService, route: ActivatedRoute, router: Router, tokenService: TokenService, loggingService: LoggingService, blockSyncService: BlockSyncService, cdr: ChangeDetectorRef, snackBar: MatSnackBar)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:70
Parameters :
Name | Type | Optional
formBuilder | `FormBuilder` | No
locationService | `LocationService` | No
transactionService | `TransactionService` | No
userService | `UserService` | No
route | `ActivatedRoute` | No
router | `Router` | No
tokenService | `TokenService` | No
loggingService | `LoggingService` | No
blockSyncService | `BlockSyncService` | No
cdr | `ChangeDetectorRef` | No
snackBar | `MatSnackBar` | No

### Methods

copyAddress
`copyAddress()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:287
Returns : `void`

doTransactionFilter
`doTransactionFilter(value: string)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:202
Parameters :
Name | Type | Optional
value | `string` | No
Returns : `void`

doUserFilter
`doUserFilter(value: string)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:206
Parameters :
Name | Type | Optional
value | `string` | No
Returns : `void`

downloadCsv
`downloadCsv(data: any, filename: string)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:283
Parameters :
Name | Type | Optional
data | `any` | No
filename | `string` | No
Returns : `void`

filterAccounts
`filterAccounts()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:245
Returns : `void`

filterTransactions
`filterTransactions()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:258
Returns : `void`

Async ngOnInit
`ngOnInit()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:92
Returns : `Promise<void>`

resetPin
`resetPin()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:271
Returns : `void`

Async saveInfo
`saveInfo()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:224
Returns : `Promise<void>`

viewAccount
`viewAccount(account)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:214
Parameters :
Name | Optional
account | No
Returns : `void`

viewTransaction
`viewTransaction(transaction)`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:210
Parameters :
Name | Optional
transaction | No
Returns : `void`

### Properties

account
Type : `AccountDetails`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:50

accountAddress
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:51

accountInfoForm
Type : `FormGroup`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:49

accounts
Type : `Array<AccountDetails>`
Default value : `[]`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:53

accountStatus
Type : `any`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:52

accountsType
Type : `string`
Default value : `'all'`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:54

accountTypes
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:61

area
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:69

areaNames
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:56

areaType
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:70

areaTypes
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:57

bloxbergLink
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:66

categories
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:55

category
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:68

genders
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:63

matcher
Type : `CustomErrorStateMatcher`
Default value : `new CustomErrorStateMatcher()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:64

submitted
Type : `boolean`
Default value : `false`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:65

tokenSymbol
Type : `string`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:67

transaction
Type : `any`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:58

transactions
Type : `Array<Transaction>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:59

transactionsDataSource
Type : `MatTableDataSource<any>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:35

transactionsDefaultPageSize
Type : `number`
Default value : `10`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:37

transactionsDisplayedColumns
Type : `Array<string>`
Default value : `['sender', 'recipient', 'value', 'created', 'type']`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:36

transactionsPageSizeOptions
Type : `Array<number>`
Default value : `[10, 20, 50, 100]`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:38

transactionsType
Type : `string`
Default value : `'all'`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:60

transactionsTypes
Type : `Array<string>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:62

transactionTablePaginator
Type : `MatPaginator`
Decorators : `@ViewChild('TransactionTablePaginator', {static: true})`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:39

transactionTableSort
Type : `MatSort`
Decorators : `@ViewChild('TransactionTableSort', {static: true})`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:40

userDataSource
Type : `MatTableDataSource<any>`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:42

userDisplayedColumns
Type : `Array<string>`
Default value : `['name', 'phone', 'created', 'balance', 'location']`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:43

usersDefaultPageSize
Type : `number`
Default value : `10`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:44

usersPageSizeOptions
Type : `Array<number>`
Default value : `[10, 20, 50, 100]`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:45

userTablePaginator
Type : `MatPaginator`
Decorators : `@ViewChild('UserTablePaginator', {static: true})`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:46

userTableSort
Type : `MatSort`
Decorators : `@ViewChild('UserTableSort', {static: true})`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:47

### Accessors

accountInfoFormStub
get `accountInfoFormStub()`
Defined in src/app/pages/accounts/account-details/account-details.component.ts:220

    import {
      ChangeDetectionStrategy,
      ChangeDetectorRef,
      Component,
      OnInit,
      ViewChild,
    } from '@angular/core';
    import { MatTableDataSource } from '@angular/material/table';
    import { MatPaginator } from '@angular/material/paginator';
    import { MatSort } from '@angular/material/sort';
    import {
      BlockSyncService,
      LocationService,
      LoggingService,
      TokenService,
      TransactionService,
      UserService,
    } from '@app/_services';
    import { ActivatedRoute, Params, Router } from '@angular/router';
    import { first } from 'rxjs/operators';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    import { copyToClipboard, CustomErrorStateMatcher, exportCsv } from '@app/_helpers';
    import { MatSnackBar } from '@angular/material/snack-bar';
    import { add0x, strip0x } from '@src/assets/js/ethtx/dist/hex';
    import { environment } from '@src/environments/environment';
    import { AccountDetails, Transaction } from '@app/_models';

    @Component({
      selector: 'app-account-details',
      templateUrl: './account-details.component.html',
      styleUrls: ['./account-details.component.scss'],
      changeDetection: ChangeDetectionStrategy.OnPush,
    })
    export class AccountDetailsComponent implements OnInit {
      transactionsDataSource: MatTableDataSource<any>;
      transactionsDisplayedColumns: Array<string> = ['sender', 'recipient', 'value', 'created', 'type'];
      transactionsDefaultPageSize: number = 10;
      transactionsPageSizeOptions: Array<number> = [10, 20, 50, 100];
      @ViewChild('TransactionTablePaginator', { static: true }) transactionTablePaginator: MatPaginator;
      @ViewChild('TransactionTableSort', { static: true }) transactionTableSort: MatSort;

      userDataSource: MatTableDataSource<any>;
      userDisplayedColumns: Array<string> = ['name', 'phone', 'created', 'balance', 'location'];
      usersDefaultPageSize: number = 10;
      usersPageSizeOptions: Array<number> = [10, 20, 50, 100];
      @ViewChild('UserTablePaginator', { static: true }) userTablePaginator: MatPaginator;
      @ViewChild('UserTableSort', { static: true }) userTableSort: MatSort;

      accountInfoForm: FormGroup;
      account: AccountDetails;
      accountAddress: string;
      accountStatus: any;
      accounts: Array<AccountDetails> = [];
      accountsType: string = 'all';
      categories: Array<string>;
      areaNames: Array<string>;
      areaTypes: Array<string>;
      transaction: any;
      transactions: Array<Transaction>;
      transactionsType: string = 'all';
      accountTypes: Array<string>;
      transactionsTypes: Array<string>;
      genders: Array<string>;
      matcher: CustomErrorStateMatcher = new CustomErrorStateMatcher();
      submitted: boolean = false;
      bloxbergLink: string;
      tokenSymbol: string;
      category: string;
      area: string;
      areaType: string;

      constructor(
        private formBuilder: FormBuilder,
        private locationService: LocationService,
        private transactionService: TransactionService,
        private userService: UserService,
        private route: ActivatedRoute,
        private router: Router,
        private tokenService: TokenService,
        private loggingService: LoggingService,
        private blockSyncService: BlockSyncService,
        private cdr: ChangeDetectorRef,
        private snackBar: MatSnackBar
      ) {
        this.route.paramMap.subscribe((params: Params) => {
          this.accountAddress = add0x(params.get('id'));
          this.bloxbergLink =
            'https://blockexplorer.bloxberg.org/address/' + this.accountAddress + '/transactions';
        });
      }

      async ngOnInit(): Promise<void> {
        this.accountInfoForm = this.formBuilder.group({
          firstName: ['', Validators.required],
          lastName: ['', Validators.required],
          phoneNumber: ['', Validators.required],
          age: [''],
          type: ['', Validators.required],
          bio: ['', Validators.required],
          gender: ['', Validators.required],
          businessCategory: ['', Validators.required],
          userLocation: ['', Validators.required],
          location: ['', Validators.required],
          locationType: ['', Validators.required],
        });
        await this.blockSyncService.init();
        await this.tokenService.init();
        await this.transactionService.init();
        await this.userService.init();
        await this.blockSyncService.blockSync(this.accountAddress);
        this.userService.resetAccountsList();
        (await this.userService.getAccountByAddress(this.accountAddress, 100)).subscribe(
          async (res) => {
            if (res !== undefined) {
              this.account = res;
              this.cdr.detectChanges();
              this.loggingService.sendInfoLevelMessage(this.account);
              this.locationService.areaNamesSubject.subscribe((response) => {
                this.area = this.locationService.getAreaNameByLocation(
                  this.account.location.area_name,
                  response
                );
                this.cdr.detectChanges();
                this.locationService.areaTypesSubject.subscribe((result) => {
                  this.areaType = this.locationService.getAreaTypeByArea(this.area, result);
                  this.cdr.detectChanges();
                });
              });
              this.userService.categoriesSubject.subscribe((result) => {
                this.category = this.userService.getCategoryByProduct(this.account.products[0], result);
                this.cdr.detectChanges();
              });
              const fullName = this.account.vcard?.fn[0].value.split(' ');
              this.accountInfoForm.patchValue({
                firstName: fullName[0].split(',')[0],
                lastName: fullName.slice(1).join(' '),
                phoneNumber: this.account.vcard?.tel[0].value,
                age: this.account.age,
                type: this.account.type,
                bio: this.account.products,
                gender: this.account.gender,
                businessCategory: this.account.category || this.category || 'other',
                userLocation: this.account.location.area_name,
                location: this.account.location.area || this.area || 'other',
                locationType: this.account.location.area_type || this.areaType || 'other',
              });
              this.userService
                .getAccountStatus(this.account.vcard?.tel[0].value)
                .pipe(first())
                .subscribe((response) => (this.accountStatus = response.status));
            } else {
              alert('Account not found!');
            }
          }
        );
        this.userService.accountsSubject.subscribe((accounts) => {
          this.userDataSource = new MatTableDataSource<any>(accounts);
          this.userDataSource.paginator = this.userTablePaginator;
          this.userDataSource.sort = this.userTableSort;
          this.accounts = accounts;
          this.cdr.detectChanges();
        });

        this.transactionService.transactionsSubject.subscribe((transactions) => {
          this.transactionsDataSource = new MatTableDataSource<any>(transactions);
          this.transactionsDataSource.paginator = this.transactionTablePaginator;
          this.transactionsDataSource.sort = this.transactionTableSort;
          this.transactions = transactions;
          this.cdr.detectChanges();
        });
        this.userService.getCategories();
        this.userService.categoriesSubject.subscribe((res) => {
          this.categories = Object.keys(res);
        });
        this.locationService.getAreaNames();
        this.locationService.areaNamesSubject.subscribe((res) => {
          this.areaNames = Object.keys(res);
        });
        this.locationService.getAreaTypes();
        this.locationService.areaTypesSubject.subscribe((res) => {
          this.areaTypes = Object.keys(res);
        });
        this.userService
          .getAccountTypes()
          .pipe(first())
          .subscribe((res) => (this.accountTypes = res));
        this.userService
          .getTransactionTypes()
          .pipe(first())
          .subscribe((res) => (this.transactionsTypes = res));
        this.userService
          .getGenders()
          .pipe(first())
          .subscribe((res) => (this.genders = res));
        this.tokenService.load.subscribe(async (status: boolean) => {
          if (status) {
            this.tokenSymbol = await this.tokenService.getTokenSymbol();
          }
        });
      }

      doTransactionFilter(value: string): void {
        this.transactionsDataSource.filter = value.trim().toLocaleLowerCase();
      }

      doUserFilter(value: string): void {
        this.userDataSource.filter = value.trim().toLocaleLowerCase();
      }

      viewTransaction(transaction): void {
        this.transaction = transaction;
      }

      viewAccount(account): void {
        this.router.navigateByUrl(
          `/accounts/${strip0x(account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0])}`
        );
      }

      get accountInfoFormStub(): any {
        return this.accountInfoForm.controls;
      }

      async saveInfo(): Promise<void> {
        this.submitted = true;
        if (this.accountInfoForm.invalid || !confirm(`Change user's profile information?`)) {
          return;
        }
        const accountKey = await this.userService.changeAccountInfo(
          this.accountAddress,
          this.accountInfoFormStub.firstName.value + ', ' + this.accountInfoFormStub.lastName.value,
          this.accountInfoFormStub.phoneNumber.value,
          this.accountInfoFormStub.age.value,
          this.accountInfoFormStub.type.value,
          this.accountInfoFormStub.bio.value,
          this.accountInfoFormStub.gender.value,
          this.accountInfoFormStub.businessCategory.value,
          this.accountInfoFormStub.userLocation.value,
          this.accountInfoFormStub.location.value,
          this.accountInfoFormStub.locationType.value
        );
        this.submitted = false;
      }

      filterAccounts(): void {
        if (this.accountsType === 'all') {
          this.userService.accountsSubject.subscribe((accounts) => {
            this.userDataSource.data = accounts;
            this.accounts = accounts;
          });
        } else {
          this.userDataSource.data = this.accounts.filter(
            (account) => account.type === this.accountsType
          );
        }
      }

      filterTransactions(): void {
        if (this.transactionsType === 'all') {
          this.transactionService.transactionsSubject.subscribe((transactions) => {
            this.transactionsDataSource.data = transactions;
            this.transactions = transactions;
          });
        } else {
          this.transactionsDataSource.data = this.transactions.filter(
            (transaction) => transaction.type + 's' === this.transactionsType
          );
        }
      }

      resetPin(): void {
        if (!confirm(`Reset user's pin?`)) {
          return;
        }
        this.userService
          .resetPin(this.account.vcard.tel[0].value)
          .pipe(first())
          .subscribe((res) => {
            this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
          });
      }

      downloadCsv(data: any, filename: string): void {
        exportCsv(data, filename);
      }

      copyAddress(): void {
        if (copyToClipboard(this.accountAddress)) {
          this.snackBar.open(this.accountAddress + ' copied successfully!', 'Close', {
            duration: 3000,
          });
        }
      }
    }

    <!-- 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>
          <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
              <li class="breadcrumb-item"><a routerLink="/home">Home</a></li>
              <li class="breadcrumb-item"><a routerLink="/accounts">Accounts</a></li>
              <li *ngIf="account" class="breadcrumb-item active" aria-current="page">
                {{ account?.vcard?.fn[0].value }}
              </li>
            </ol>
          </nav>
          <div *ngIf="!account" class="text-center">
            <div class="spinner-grow text-primary m-1" role="status" style="width: 3rem; height: 3rem">
              <span class="sr-only">Loading...</span>
            </div>
            <div class="spinner-grow text-primary m-1" role="status" style="width: 3rem; height: 3rem">
              <span class="sr-only">Loading...</span>
            </div>
            <div class="spinner-grow text-primary m-1" role="status" style="width: 3rem; height: 3rem">
              <span class="sr-only">Loading...</span>
            </div>
          </div>
          <div *ngIf="account" class="card mb-3">
            <div class="row card-body">
              <h3>
                <strong> {{ account?.vcard?.fn[0].value }} </strong>
              </h3>
              <span class="ml-auto"
                ><strong>Balance:</strong> {{ account?.balance | tokenRatio }}
                {{ tokenSymbol | uppercase }}</span
              >
              <span class="ml-2"
                ><strong>Created:</strong> {{ account?.date_registered | unixDate }}</span
              >
              <span class="ml-2"
                ><strong>Address:</strong>
                <a href="{{ bloxbergLink }}" target="_blank"> {{ accountAddress }} </a>
                <img
                  src="assets/images/checklist.svg"
                  class="ml-2"
                  height="20rem"
                  (click)="copyAddress()"
                  alt="Copy"
                />
              </span>
            </div>
          </div>
          <div *ngIf="account" class="card mt-3 mb-3">
            <div class="card-body">
              <form [formGroup]="accountInfoForm" (ngSubmit)="saveInfo()">
                <div class="row form-inline">
                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label>First Name: *</mat-label>
                      <input
                        matInput
                        type="text"
                        id="firstName"
                        placeholder="{{ account?.vcard?.fn[0].value.split(' ')[0] }}"
                        value="{{ account?.vcard?.fn[0].value.split(' ')[0] }}"
                        formControlName="firstName"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.firstName.errors"
                        >First Name is required.</mat-error
                      >
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label>Last Name(s): *</mat-label>
                      <input
                        matInput
                        type="text"
                        id="lastName"
                        placeholder="{{ account?.vcard?.fn[0].value.split(' ').slice(1).join(' ') }}"
                        value="{{ account?.vcard?.fn[0].value.split(' ').slice(1).join(' ') }}"
                        formControlName="lastName"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.lastName.errors"
                        >Last Name is required.</mat-error
                      >
                    </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?.vcard?.tel[0].value }}"
                        value="{{ account?.vcard?.tel[0].value }}"
                        formControlName="phoneNumber"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.phoneNumber.errors"
                        >Phone Number is required.</mat-error
                      >
                    </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"
                        formControlName="type"
                        [errorStateMatcher]="matcher"
                      >
                        <mat-option *ngFor="let accountType of accountTypes" [value]="accountType">
                          {{ accountType | uppercase }}
                        </mat-option>
                      </mat-select>
                      <mat-error *ngIf="submitted && accountInfoFormStub.type.errors"
                        >Type is required.</mat-error
                      >
                    </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"
                        formControlName="gender"
                        [errorStateMatcher]="matcher"
                      >
                        <mat-option *ngFor="let gender of genders" [value]="gender">
                          {{ gender | uppercase }}
                        </mat-option>
                      </mat-select>
                      <mat-error *ngIf="submitted && accountInfoFormStub.gender.errors"
                        >Gender is required.</mat-error
                      >
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label>Age: </mat-label>
                      <input
                        matInput
                        type="text"
                        id="age"
                        placeholder="{{ account?.age }}"
                        value="{{ account?.age }}"
                        formControlName="age"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.age.errors"
                        >Age is required.</mat-error
                      >
                    </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?.products }}"
                        value="{{ account?.products }}"
                        formControlName="bio"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.bio.errors"
                        >Bio is required.</mat-error
                      >
                    </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"
                        [(value)]="category"
                        formControlName="businessCategory"
                        [errorStateMatcher]="matcher"
                      >
                        <mat-option *ngFor="let category of categories" [value]="category">
                          {{ category | titlecase }}
                        </mat-option>
                      </mat-select>
                      <mat-error *ngIf="submitted && accountInfoFormStub.businessCategory.errors">
                        Category is required.
                      </mat-error>
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label>User Location: </mat-label>
                      <input
                        matInput
                        type="text"
                        id="userLocation"
                        placeholder="{{ account?.location.area_name }}"
                        value="{{ account?.location.area_name }}"
                        formControlName="userLocation"
                        [errorStateMatcher]="matcher"
                      />
                      <mat-error *ngIf="submitted && accountInfoFormStub.userLocation.errors">
                        User Location is required.
                      </mat-error>
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label> LOCATION: </mat-label>
                      <mat-select
                        id="location"
                        [(value)]="area"
                        formControlName="location"
                        [errorStateMatcher]="matcher"
                      >
                        <mat-option *ngFor="let area of areaNames" [value]="area">
                          {{ area | uppercase }}
                        </mat-option>
                      </mat-select>
                      <mat-error *ngIf="submitted && accountInfoFormStub.location.errors"
                        >Location is required.</mat-error
                      >
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <mat-form-field appearance="outline">
                      <mat-label> LOCATION TYPE: </mat-label>
                      <mat-select
                        id="locationType"
                        [(value)]="areaType"
                        formControlName="locationType"
                        [errorStateMatcher]="matcher"
                      >
                        <mat-option *ngFor="let type of areaTypes" [value]="type">
                          {{ type | uppercase }}
                        </mat-option>
                      </mat-select>
                      <mat-error *ngIf="submitted && accountInfoFormStub.locationType.errors"
                        >Location Type is required.</mat-error
                      >
                    </mat-form-field>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <button
                      mat-raised-button
                      color="primary"
                      type="button"
                      class="btn btn-outline-success mb-3"
                      (click)="resetPin()"
                    >
                      Reset Pin
                    </button>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <button
                      mat-raised-button
                      color="warn"
                      type="button"
                      class="btn btn-outline-danger mb-3"
                    >
                      Delete User
                    </button>
                  </div>

                  <div class="col-md-6 col-lg-4">
                    <button
                      mat-raised-button
                      color="primary"
                      type="submit"
                      class="btn btn-outline-primary"
                    >
                      SAVE DETAILS
                    </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">BALANCE</th>
                      <th scope="col">CREATED</th>
                      <th scope="col">STATUS</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                      <td>{{ account?.vcard?.fn[0].value || accountAddress }}</td>
                      <td>{{ account?.balance | tokenRatio }} {{ tokenSymbol | uppercase }}</td>
                      <td>{{ account?.date_registered | unixDate }}</td>
                      <td>
                        <span class="badge badge-success badge-pill">
                          {{ accountStatus }}
                        </span>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>

          <mat-tab-group *ngIf="account" dynamicHeight mat-align-tabs="start">
            <mat-tab label="Transactions">
              <app-transaction-details
                [transaction]="transaction"
                (closeWindow)="transaction = $event"
              ></app-transaction-details>
              <div class="card mt-1">
                <div class="card-header">
                  <div class="row">
                    <mat-form-field appearance="outline">
                      <mat-label> TRANSACTION TYPE </mat-label>
                      <mat-select
                        id="transferSelect"
                        [(value)]="transactionsType"
                        (selectionChange)="filterTransactions()"
                      >
                        <mat-option value="all">ALL TRANSFERS</mat-option>
                        <mat-option
                          *ngFor="let transactionType of transactionsTypes"
                          [value]="transactionType"
                        >
                          {{ transactionType | uppercase }}
                        </mat-option>
                      </mat-select>
                    </mat-form-field>
                    <button
                      mat-raised-button
                      color="primary"
                      type="button"
                      class="btn btn-outline-primary ml-auto mr-2"
                      (click)="downloadCsv(transactions, 'transactions')"
                    >
                      EXPORT
                    </button>
                  </div>
                </div>

                <div class="card-body">
                  <mat-form-field appearance="outline">
                    <mat-label> Filter </mat-label>
                    <input
                      matInput
                      type="text"
                      (keyup)="doTransactionFilter($event.target.value)"
                      placeholder="Filter"
                    />
                    <mat-icon matSuffix>search</mat-icon>
                  </mat-form-field>

                  <table
                    mat-table
                    class="mat-elevation-z10"
                    [dataSource]="transactionsDataSource"
                    matSort
                    matSortActive="created"
                    #TransactionTableSort="matSort"
                    matSortDirection="asc"
                    matSortDisableClear
                  >
                    <ng-container matColumnDef="sender">
                      <th mat-header-cell *matHeaderCellDef mat-sort-header>Sender</th>
                      <td mat-cell *matCellDef="let transaction">
                        {{ transaction?.sender?.vcard.fn[0].value || transaction.from }}
                      </td>
                    </ng-container>

                    <ng-container matColumnDef="recipient">
                      <th mat-header-cell *matHeaderCellDef mat-sort-header>Recipient</th>
                      <td mat-cell *matCellDef="let transaction">
                        {{ transaction?.recipient?.vcard.fn[0].value || transaction.to }}
                      </td>
                    </ng-container>

                    <ng-container matColumnDef="value">
                      <th mat-header-cell *matHeaderCellDef mat-sort-header>Value</th>
                      <td mat-cell *matCellDef="let transaction">
                        <span *ngIf="transaction.type == 'transaction'"
                          >{{ transaction?.value | tokenRatio }} {{ tokenSymbol | uppercase }}</span
                        >
                        <span *ngIf="transaction.type == 'conversion'"
                          >{{ transaction?.toValue | tokenRatio }} {{ tokenSymbol | uppercase }}</span
                        >
                      </td>
                    </ng-container>

                    <ng-container matColumnDef="created">
                      <th mat-header-cell *matHeaderCellDef mat-sort-header>Created</th>
                      <td mat-cell *matCellDef="let transaction">
                        {{ transaction?.tx.timestamp | unixDate }}
                      </td>
                    </ng-container>

                    <ng-container matColumnDef="type">
                      <th mat-header-cell *matHeaderCellDef mat-sort-header>TYPE</th>
                      <td mat-cell *matCellDef="let transaction">
                        <span class="badge badge-success badge-pill"> {{ transaction?.type }} </span>
                      </td>
                    </ng-container>

                    <tr mat-header-row *matHeaderRowDef="transactionsDisplayedColumns"></tr>
                    <tr
                      mat-row
                      *matRowDef="let transaction; columns: transactionsDisplayedColumns"
                      matRipple
                      (click)="viewTransaction(transaction)"
                    ></tr>
                  </table>

                  <mat-paginator
                    #TransactionTablePaginator="matPaginator"
                    [pageSize]="transactionsDefaultPageSize"
                    [pageSizeOptions]="transactionsPageSizeOptions"
                    showFirstLastButtons
                  ></mat-paginator>
                </div>
              </div>
            </mat-tab>

            <mat-tab label="Users">
              <div class="card mt-1">
                <mat-card-title class="card-header"> Accounts </mat-card-title>
                <div class="card-body">
                  <div class="row card-header">
                    <mat-form-field appearance="outline">
                      <mat-label> ACCOUNT TYPE </mat-label>
                      <mat-select
                        id="typeSelect"
                        [(value)]="accountsType"
                        (selectionChange)="filterAccounts()"
                      >
                        <mat-option value="all">ALL</mat-option>
                        <mat-option *ngFor="let accountType of accountTypes" [value]="accountType">
                          {{ accountType | uppercase }}
                        </mat-option>
                      </mat-select>
                    </mat-form-field>
                    <button
                      mat-raised-button
                      color="primary"
                      type="button"
                      class="btn btn-outline-primary ml-auto mr-2"
                      (click)="downloadCsv(accounts, 'accounts')"
                    >
                      EXPORT
                    </button>
                  </div>

                  <mat-form-field appearance="outline">
                    <mat-label> Filter </mat-label>
                    <input
                      matInput
                      type="text"
                      (keyup)="doUserFilter($event.target.value)"
                      placeholder="Filter"
                    />
                    <mat-icon matSuffix>search</mat-icon>
                  </mat-form-field>

                  <mat-table
                    class="mat-elevation-z10"
                    [dataSource]="userDataSource"
                    matSort
                    #UserTableSort="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?.vcard.fn[0].value }} </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?.vcard.tel[0].value }} </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?.date_registered | unixDate }}
                      </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 | tokenRatio }} {{ tokenSymbol | uppercase }}
                      </mat-cell>
                    </ng-container>

                    <ng-container matColumnDef="location">
                      <mat-header-cell *matHeaderCellDef mat-sort-header> LOCATION </mat-header-cell>
                      <mat-cell *matCellDef="let user"> {{ user?.location.area_name }} </mat-cell>
                    </ng-container>

                    <mat-header-row *matHeaderRowDef="userDisplayedColumns"></mat-header-row>
                    <mat-row
                      *matRowDef="let account; columns: userDisplayedColumns"
                      (click)="viewAccount(account)"
                      matRipple
                    ></mat-row>
                  </mat-table>

                  <mat-paginator
                    #UserTablePaginator="matPaginator"
                    [pageSize]="usersDefaultPageSize"
                    [pageSizeOptions]="usersPageSizeOptions"
                    showFirstLastButtons
                  ></mat-paginator>
                </div>
              </div>
            </mat-tab>
          </mat-tab-group>
        </div>
        <app-footer appMenuSelection></app-footer>
      </div>
      <!-- ============================================================== -->
      <!-- End Page content -->
      <!-- ============================================================== -->
    </div>

`./account-details.component.scss`

Legend
Html element
Component
Html element with directive

# result-matching ""

# No results matching ""