src/app/sending-money/new-payment/new-payment.component.ts
| selector | app-new-payment | 
            
| styleUrls | new-payment.component.css | 
            
| templateUrl | ./new-payment.component.html | 
            
                        Properties | 
                
                        Methods | 
                
    constructor(router: Router, app: AppState)
                         | 
                    
| formatPhoneNumber | ||||||
    formatPhoneNumber(phoneNumber: string)
                         | 
                    ||||||
| 
    
                                 
                                        Parameters :
                                         
                                
 
                                    Returns :      
                                    any
    
                                 | 
                    
| ngAfterViewInit | 
    ngAfterViewInit()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| ngOnInit | 
    ngOnInit()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| onContactChanged | 
    onContactChanged()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| resetPayForm | 
    resetPayForm()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| Private setContactType | 
                                
                            setContactType()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| submit | 
    submit()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        void
    
                                 | 
                    
| Private validateContact | 
                                
                            validateContact()
                         | 
                    
| 
    
                                 
                                    Returns :      
                        any
    
                                 | 
                    
| cleanValue | 
                            cleanValue:     
                         | 
                    
                                Type :     string
    
                             | 
                        
| contact | 
                            contact:     
                         | 
                    
                                Type :     string
    
                             | 
                        
                                Default value : ''
                             | 
                        
| contactElement | 
                            contactElement:     
                         | 
                    
                                Type :     ElementRef
    
                             | 
                        
                                Decorators : ViewChild
                             | 
                        
| contactModel | 
                            contactModel:     
                         | 
                    
                                Decorators : ViewChild
                             | 
                        
| contactType | 
                            contactType:     
                         | 
                    
                                Default value : ContactType.Invalid
                             | 
                        
| init$ | 
                            init$:     
                         | 
                    
                                Type :     Observable<any>
    
                             | 
                        
| isAppValid | 
                            isAppValid:     
                         | 
                    
                                Default value : false
                             | 
                        
| isContactValid | 
                            isContactValid:     
                         | 
                    
                                Default value : false
                             | 
                        
| isvisible | 
                            isvisible:     
                         | 
                    
                                Default value : false
                             | 
                        
| memo | 
                            memo:     
                         | 
                    
                                Type :     string
    
                             | 
                        
                                Default value : ''
                             | 
                        
| payform | 
                            payform:     
                         | 
                    
                                Decorators : ViewChild
                             | 
                        
| phoneNumberFormatted | 
                            phoneNumberFormatted:     
                         | 
                    
                                Type :     string
    
                             | 
                        
| phoneNumberValue | 
                            phoneNumberValue:     
                         | 
                    
                                Type :     number
    
                             | 
                        
| types | 
                            types:     
                         | 
                    
                                Default value : ContactType
                             | 
                        
import { Observable } from 'rxjs/Observable';
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { first, tap, debounceTime } from 'rxjs/operators';
import { AppState } from '../../stores/app-state.store';
import { ContactType } from './../../enums/contact-type.enum';
import { concat } from 'rxjs/observable/concat';
@Component({
  selector: 'app-new-payment',
  templateUrl: './new-payment.component.html',
  styleUrls: ['./new-payment.component.css'],
})
export class NewPaymentComponent implements OnInit, AfterViewInit {
  types = ContactType;
  @ViewChild('userFormPay')
  payform;
  @ViewChild('contactModel')
  contactModel;
  @ViewChild('contactElement')
  contactElement: ElementRef;
  isvisible = false;
  contact = '';
  memo = '';
  phoneNumberFormatted: string;
  isAppValid = false;
  phoneNumberValue: number;
  cleanValue: string;
  init$: Observable<any>;
  contactType = ContactType.Invalid;
  isContactValid = false;
  constructor(private router: Router, private app: AppState) {}
  ngAfterViewInit(): void {
    this.contactElement.nativeElement.focus();
  }
  ngOnInit() {
    this.init$ = this.app.state$.pipe(
      debounceTime(1000),
      tap((state) => {
        this.contact = this.app.getContactInfo();
        this.isAppValid = state.isValid;
        this.onContactChanged();
      })
    );
  }
  submit() {
    if (!this.app.isValid) {
      return;
    }
    this.app.payment.memo = this.memo;
    this.app.isNew = true;
    this.app.setContactInfo(this.contact);
    this.app.template.payFromBankAccount = this.app.bankAccount;
    this.router.navigate(['payment/create']);
  }
  resetPayForm() {
    this.contact = '';
    this.memo = '';
  }
  private setContactType() {
    if (!this.contact) {
      this.contactType = ContactType.Invalid;
      return;
    }
    if (this.contact.includes('@')) {
      this.contactType = ContactType.Email;
      return;
    }
    if (this.contact.length > 7) {
      const removeSpecialCharacters = this.contact.replace('(', '');
      this.phoneNumberValue = parseInt(removeSpecialCharacters, 10);
    }
    if (this.phoneNumberValue >= 1) {
      if (
        this.contact.length === 7 ||
        this.contact.length === 10 ||
        (this.contact.length > 10 && this.contact.includes('(')) ||
        (this.contact.length > 10 && this.contact.includes('-')) ||
        (this.contact.length > 10 && this.contact.includes('.')) ||
        (this.contact.length > 10 && this.contact.includes('+'))
      ) {
        this.contactType = ContactType.Phone;
        return;
      }
    }
    this.contactType = ContactType.Invalid;
  }
  formatPhoneNumber(phoneNumber: string) {
    if (phoneNumber.length === 7) {
      const firstValue = phoneNumber.substring(0, 3);
      const secondValue = phoneNumber.substring(3, 7);
      this.contactElement.nativeElement.value = firstValue + '-' + secondValue;
      return;
    }
    if (phoneNumber.length > 13) {
      const removeOneValue = phoneNumber.replace('+1', '');
      this.cleanValue = ('' + removeOneValue).replace(/\D/g, '');
    } else {
      this.cleanValue = ('' + phoneNumber).replace(/\D/g, '');
    }
    const match = this.cleanValue.match(/^(\d{3})(\d{3})(\d{4})$/);
    if (match) {
      this.contactElement.nativeElement.value = '(' + match[1] + ')' + match[2] + '-' + match[3];
    }
    return null;
  }
  private validateContact() {
    this.setContactType();
    return (
      this.contactModel.pristine || (this.contactModel.dirty && this.contactType !== ContactType.Invalid)
    );
  }
  onContactChanged() {
    this.isContactValid = this.validateContact();
    if (this.contactType === ContactType.Invalid) {
      return;
    }
    if (this.contactType === ContactType.Phone) {
      this.formatPhoneNumber(this.contact);
    }
    this.contact = this.app.trim(this.contact);
    this.app.setContactInfo(this.contact);
  }
}
    <ng-container *ngIf="init$ | async"></ng-container>
<form #userFormPay="ngForm">
  <p class="new-payment">What is their email or mobile phone number?</p>
  <input
    #contactElement
    #contactModel="ngModel"
    type="text"
    [(ngModel)]="contact"
    (keyup)="onContactChanged()"
    (blur)="onContactChanged()"
    (keydown.Enter)="submit()"
    [ngClass]="isContactValid && !contactModel.pristine ? 'contact-info-valid' : 'contact-info-unvalid'"
    id="contact"
    name="contact"
    tabindex="3"
    autocomplete="off"
    placeholder="Email or Mobile Phone Number:"
  />
  <span class="approve"> <i class="material-icons status-positive">check</i> </span>
  <div *ngIf="!isContactValid" class="alert alert-danger">A valid email or phone number is required</div>
  <p class="feedback-tag">Send a message with your payment (Optional)</p>
  <input
    type="text"
    [(ngModel)]="memo"
    (keydown.Enter)="submit()"
    #memoInfo="ngModel"
    id="memo"
    name="memo"
    tabindex="4"
    placeholder="Dinner, Rent, Etc."
    pattern="[A-Za-z0-9,\s!.'-]+"
    autocomplete="off"
  />
  <span *ngIf="memo.length > 0">
    <div [hidden]="memoInfo.valid || memoInfo.pristine" class="alert alert-danger text-align">
      Please only use A-Z, a-z, 0-9, periods, commas, dashes, spaces, apostrophes, and exclamation points
    </div>
  </span>
  <button
    [disabled]="!isAppValid || !userFormPay.form.valid || !isContactValid"
    (click)="submit()"
    type="button"
    class="action-button"
    id="submitButton"
    tabindex="5"
  >
    <p class="button-inside">Continue to the next step</p>
  </button>
</form>