import { AfterViewInit, 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, AfterViewInit { transactionsDataSource: MatTableDataSource; transactionsDisplayedColumns: Array = ['sender', 'recipient', 'value', 'created', 'type']; transactionsDefaultPageSize: number = 10; transactionsPageSizeOptions: Array = [10, 20, 50, 100]; @ViewChild('TransactionTablePaginator', { static: true }) transactionTablePaginator: MatPaginator; @ViewChild('TransactionTableSort', { static: true }) transactionTableSort: MatSort; userDataSource: MatTableDataSource; userDisplayedColumns: Array = ['name', 'phone', 'created', 'balance', 'location']; usersDefaultPageSize: number = 10; usersPageSizeOptions: Array = [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 = []; accountsType: string = 'all'; categories: Array; areaNames: Array; areaTypes: Array; transaction: any; transactions: Array; transactionsType: string = 'all'; accountTypes: Array; transactionsTypes: Array; genders: Array; matcher: CustomErrorStateMatcher = new CustomErrorStateMatcher(); submitted: boolean = false; bloxbergLink: string; tokenSymbol: string; category: string; area: string; areaType: string; accountsLoading: boolean = true; transactionsLoading: boolean = true; 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 { 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], }); this.transactionService.resetTransactionsList(); 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.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(accounts); this.userDataSource.paginator = this.userTablePaginator; this.userDataSource.sort = this.userTableSort; this.accounts = accounts; if (accounts.length > 0) { this.accountsLoading = false; } this.cdr.detectChanges(); }); this.transactionService.transactionsSubject.subscribe((transactions) => { this.transactionsDataSource = new MatTableDataSource(transactions); this.transactionsDataSource.paginator = this.transactionTablePaginator; this.transactionsDataSource.sort = this.transactionTableSort; this.transactions = transactions; if (transactions.length > 0) { this.transactionsLoading = false; } 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(); } }); } ngAfterViewInit(): void { if (this.userDataSource) { this.userDataSource.paginator = this.userTablePaginator; this.userDataSource.sort = this.userTableSort; } if (this.transactionsDataSource) { this.transactionsDataSource.paginator = this.transactionTablePaginator; this.transactionsDataSource.sort = this.transactionTableSort; } } 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 { 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, }); } } }