src/app/modules/public/module/sign-in/sso/components/update-contact/update-contact.component.ts
| styleUrls | update-contact.component.scss | 
| templateUrl | update-contact.component.html | 
| constructor(activatedRoute: ActivatedRoute, tenantService: any, resourceService: any, userService: any, otpService: any, toasterService: any, navigationHelperService: any, orgDetailsService: any, utilService: any, signupService: SignupService, telemetryService: any) | 
| toggleTncCheckBox | 
| toggleTncCheckBox(e: any) | 
| Toogles contact form value based on event data 
                                        Parameters :
                                         
 
                                    Returns:      void | 
| Private generateInteractEvent | 
| generateInteractEvent(cData: any, eData: any) | 
| Used to generate interact telemetry 
                                        Parameters :
                                         
 
                                    Returns:      void | 
| fetchTncConfiguration | 
| fetchTncConfiguration() | 
| Fetches tnc related configuration 
                                    Returns:      void | 
| handleFormChangeEvent | 
| handleFormChangeEvent() | 
| 
                                    Returns:      void | 
| Private checkUserExist | 
| checkUserExist() | 
| 
                                    Returns:      void | 
| Private getCustodianOrgDetails | 
| getCustodianOrgDetails() | 
| 
                                    Returns:      void | 
| Public onFormUpdate | 
| onFormUpdate() | 
| 
                                    Returns:      void | 
| Private generateOtp | 
| generateOtp() | 
| 
                                    Returns:      void | 
| resetForm | 
| resetForm(type: string) | 
| 
                                    Returns:      void | 
| Private prepareOtpData | 
| prepareOtpData() | 
| 
                                    Returns:      void | 
| Public handleOtpValidationFailed | 
| handleOtpValidationFailed() | 
| 
                                    Returns:      void | 
| getQueryParams | 
| getQueryParams(queryObj: any) | 
| 
                                    Returns:      void | 
| Public handleOtpValidationSuccess | 
| handleOtpValidationSuccess() | 
| 
                                    Returns:      void | 
| Private setTenantInfo | 
| setTenantInfo() | 
| 
                                    Returns:      void | 
| telemetryLogEvents | 
| telemetryLogEvents(api: any, status: boolean) | 
| 
                                    Returns:      void | 
| showAndHidePopup | 
| showAndHidePopup(mode: boolean) | 
| 
                                    Returns:      void | 
| activatedRoute | 
| activatedRoute:      | 
| Private contactDetailsForm | 
| contactDetailsForm:      | 
| Public contactForm | 
| contactForm:      | 
| Public custodianOrgDetails | 
| custodianOrgDetails:      | 
| Public disableSubmitBtn | 
| disableSubmitBtn:      | 
| Default value: true | 
| instance | 
| instance:      | 
| Public isValidIdentifier | 
| isValidIdentifier:      | 
| navigationHelperService | 
| navigationHelperService:      | 
| Public otpData | 
| otpData:      | 
| otpService | 
| otpService:      | 
| resourceService | 
| resourceService:      | 
| Public showError | 
| showError:      | 
| Default value: false | 
| Public showMergeConfirmation | 
| showMergeConfirmation:      | 
| Default value: false | 
| Public showOtpComp | 
| showOtpComp:      | 
| Default value: false | 
| showTncPopup | 
| showTncPopup:      | 
| Default value: false | 
| signupService | 
| signupService:      | 
| Public telemetryImpression | 
| telemetryImpression:      | 
| telemetryService | 
| telemetryService:      | 
| Public tenantInfo | 
| tenantInfo:      | 
| termsAndConditionLink | 
| termsAndConditionLink:      | 
| tncLatestVersion | 
| tncLatestVersion:      | 
| toasterService | 
| toasterService:      | 
| Public userBlocked | 
| userBlocked:      | 
| Default value: false | 
| Public userDetails | 
| userDetails:      | 
| Public userExist | 
| userExist:      | 
| Default value: false | 
| userService | 
| userService:      | 
| utilService | 
| utilService:      | 
| Public validationPattern | 
| validationPattern:      | 
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { TenantService, UserService, OtpService, OrgDetailsService } from '@sunbird/core';
import { first, delay } from 'rxjs/operators';
import {
  ResourceService, ToasterService, NavigationHelperService,
  ServerResponse, UtilService
} from '@sunbird/shared';
import * as _ from 'lodash-es';
import {SignupService} from '../../../../signup/services';
import { map } from 'rxjs/operators';
import { combineLatest, of } from 'rxjs';
import { TelemetryService } from '@sunbird/telemetry';
@Component({
  templateUrl: './update-contact.component.html',
  styleUrls: ['./update-contact.component.scss']
})
export class UpdateContactComponent implements OnInit, AfterViewInit {
  @ViewChild('contactDetailsForm') private contactDetailsForm;
  public telemetryImpression;
  public tenantInfo: any = {};
  public showOtpComp = false;
  public showMergeConfirmation = false;
  public userBlocked = false;
  public userExist = false;
  public disableSubmitBtn = true;
  public otpData = {};
  public userDetails: any = {};
  public showError = false;
  public custodianOrgDetails;
  public isValidIdentifier;
  public validationPattern = {
    phone: /^[6-9]\d{9}$/,
    email: /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[a-z]{2,4}$/
  };
  public contactForm = {
    value: '',
    type: 'phone',
    tncAccepted: false
  };
  tncLatestVersion: string;
  termsAndConditionLink: string;
  instance: string;
  showTncPopup = false;
  constructor(public activatedRoute: ActivatedRoute, private tenantService: TenantService, public resourceService: ResourceService,
              public userService: UserService, public otpService: OtpService, public toasterService: ToasterService,
              public navigationHelperService: NavigationHelperService, private orgDetailsService: OrgDetailsService,
              public utilService: UtilService, public signupService: SignupService,
              public telemetryService: TelemetryService) {
  }
  ngOnInit() {
    this.instance = _.upperCase(this.resourceService.instance || 'SUNBIRD');
    this.fetchTncConfiguration();
    this.setTenantInfo();
  }
  ngAfterViewInit () {
    this.handleFormChangeEvent();
    setTimeout(() => {
      this.telemetryImpression = {
        context: {
          env: this.activatedRoute.snapshot.data.telemetry.env,
        },
        edata: {
          type: this.activatedRoute.snapshot.data.telemetry.type,
          pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
          uri: this.activatedRoute.snapshot.data.telemetry.uri,
          duration: this.navigationHelperService.getPageLoadTime()
        }
      };
    });
  }
  /**
   * Toogles contact form value based on event data
   * @param e event data
   */
  toggleTncCheckBox(e) {
    this.contactForm.tncAccepted = e.target.checked;
    const cData = {
      env: 'sso-signup',
      cdata: [
        {id: 'user:tnc:accept', type: 'Feature'},
        {id: 'SB-16663', type: 'Task'}
      ]
    };
    const eData = {
      id: 'user:tnc:accept',
      type: 'click',
      subtype: this.contactForm.tncAccepted ? 'selected' : 'unselected',
      pageid: 'sso-signup'
    };
    this.generateInteractEvent(cData, eData);
  }
  /**
   * Used to generate interact telemetry
   * @param tncAcceptedStatus
   */
  private generateInteractEvent(cData, eData) {
    const interactData = {
      context: cData,
      edata: eData
    };
    this.telemetryService.interact(interactData);
  }
  /**
   * Fetches tnc related configuration
   */
  fetchTncConfiguration() {
    this.signupService.getTncConfig().subscribe((data: ServerResponse) => {
      this.telemetryLogEvents('fetch-terms-condition', true);
        const response = _.get(data, 'result.response.value');
        if (response) {
          try {
            const tncConfig = this.utilService.parseJson(response);
            this.tncLatestVersion = _.get(tncConfig, 'latestVersion') || {};
            this.termsAndConditionLink = tncConfig[this.tncLatestVersion].url;
          } catch (e) {
            this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
          }
        }
      }, (err) => {
      this.telemetryLogEvents('fetch-terms-condition', false);
      this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
      }
    );
  }
  handleFormChangeEvent() {
    this.contactDetailsForm.valueChanges.pipe(delay(1)).subscribe((data, data2) => {
      if (_.get(this.contactDetailsForm, 'status') === 'VALID' &&
        _.get(this.contactDetailsForm, 'controls.tncAccepted.value')) {
        this.disableSubmitBtn = false;
         this.isValidIdentifier = true;
        this.userExist = false;
        this.userBlocked = false;
      } else {
        this.disableSubmitBtn = true;
        this.isValidIdentifier = _.get(this.contactDetailsForm, 'controls.value.status') === 'VALID'
          && this.validationPattern[this.contactForm.type].test(this.contactForm.value);
        this.userExist = false;
        this.userBlocked = false;
      }
    });
  }
  private checkUserExist() {
    const uri = this.contactForm.type + '/' + this.contactForm.value;
    combineLatest(this.userService.getUserByKey(uri), this.getCustodianOrgDetails())
    .pipe(map(data => ({
      userDetails: data[0], custOrgDetails: data[1]
    })))
    .subscribe(({userDetails, custOrgDetails}) => {
        if (_.get(userDetails, 'result.response.rootOrgId') === _.get(custOrgDetails, 'result.response.value')) {
          this.userDetails = userDetails.result.response;
          this.disableSubmitBtn = false;
          this.userExist = false;
          this.userBlocked =  false;
          this.generateOtp();
        } else {
          this.userExist = true;
          this.userBlocked =  false;
          this.disableSubmitBtn = true;
        }
      }, err => {
        this.userDetails = {};
        if (_.get(err, 'error.params.status') && err.error.params.status === 'USER_ACCOUNT_BLOCKED') {
          this.userBlocked =  true;
          this.userExist = false;
          this.disableSubmitBtn = true;
          return;
        }
        this.generateOtp();
        this.disableSubmitBtn = false;
        this.userExist = false;
        this.userBlocked = false;
    });
  }
  private getCustodianOrgDetails() {
    if (this.custodianOrgDetails) {
      return of(this.custodianOrgDetails);
    }
    return this.orgDetailsService.getCustodianOrg().pipe(map((custodianOrgDetails) => {
      this.custodianOrgDetails = custodianOrgDetails;
      return custodianOrgDetails;
    }));
  }
  public onFormUpdate() {
    this.checkUserExist();
    const cData = {
      env: 'sso-signup',
      cdata: []
    };
    const eData = {
      id: this.contactForm.type === 'email' ? 'submit-email' : 'submit-phone',
      type: 'click',
      pageid: 'sso-sign-in',
    };
    this.generateInteractEvent(cData, eData);
  }
  private generateOtp() {
    const request = {
      request: {
        'key': this.contactForm.value,
        'type': this.contactForm.type
      }
    };
    this.otpService.generateOTP(request).subscribe((data) => {
        this.prepareOtpData();
        this.showOtpComp = true;
      }, (err) => {
        const errorMessage = (err.error.params.status === 'PHONE_ALREADY_IN_USE') || (err.error.params.status === 'EMAIL_IN_USE') ||
          (err.error.params.status === 'ERROR_RATE_LIMIT_EXCEEDED') ? err.error.params.errmsg : this.resourceService.messages.fmsg.m0085;
        this.toasterService.error(errorMessage);
      }
    );
  }
  resetForm(type = 'phone') {
    this.disableSubmitBtn = true;
    this.contactForm = {
      value: '',
      type: type,
      tncAccepted: false
    };
    this.userDetails = {};
    this.userExist = false;
    this.userBlocked = false;
  }
  private prepareOtpData() {
    this.otpData = {
      type: this.contactForm.type,
      value: this.contactForm.value,
      instructions: this.contactForm.type === 'phone' ?
        this.resourceService.frmelmnts.instn.t0083 : this.resourceService.frmelmnts.instn.t0084,
      retryMessage: this.contactForm.type === 'phone' ?
        this.resourceService.frmelmnts.lbl.unableToUpdateMobile : this.resourceService.frmelmnts.lbl.unableToUpdateEmail,
      wrongOtpMessage: this.contactForm.type === 'phone' ? this.resourceService.frmelmnts.lbl.wrongPhoneOTP :
        this.resourceService.frmelmnts.lbl.wrongEmailOTP
    };
  }
  public handleOtpValidationFailed() {
    this.showOtpComp = false;
    this.resetForm();
    setTimeout(() => this.handleFormChangeEvent(), 100);
  }
  getQueryParams(queryObj) {
    return '?' + Object.keys(queryObj).filter(key => queryObj[key])
      .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryObj[key])}`)
      .join('&');
  }
  public handleOtpValidationSuccess() {
    const query: any = {
      type: this.contactForm.type,
      value: this.contactForm.value,
      tncAccepted: this.contactForm.tncAccepted,
      tncVersion: this.tncLatestVersion
    };
    if (!_.isEmpty(this.userDetails)) {
      if (this.userDetails.id) {
        this.showOtpComp = false;
        this.showMergeConfirmation = true;
      }
    } else {
      window.location.href = `/v1/sso/contact/verified` +
        this.getQueryParams({...this.activatedRoute.snapshot.queryParams, ...query});
    }
  }
  private setTenantInfo() {
    this.tenantService.tenantData$.pipe(first()).subscribe(data => {
      if (!data.err) {
        this.tenantInfo = {
          logo: data.tenantData.logo,
          tenantName: data.tenantData.titleName
        };
      }
    });
  }
  telemetryLogEvents(api: any, status: boolean) {
    let level = 'ERROR';
    let msg = api + ' failed';
    if (status) {
      level = 'SUCCESS';
      msg = api + ' success';
    }
    const event = {
      context: {
        env: 'sso-signup'
      },
      edata: {
        type: api,
        level: level,
        message: msg
      }
    };
    this.telemetryService.log(event);
  }
  showAndHidePopup(mode: boolean) {
    this.showTncPopup = mode;
  }
}