File

src/app/modules/public/module/signup/components/otp/otp.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(resourceService: ResourceService, signupService: SignupService, activatedRoute: ActivatedRoute, telemetryService: TelemetryService, deviceDetectorService: DeviceDetectorService, router: Router, utilService: UtilService, configService: ConfigService, tncService: TncService, toasterService: ToasterService, profileService: ProfileService)
Parameters :
Name Type Optional
resourceService ResourceService No
signupService SignupService No
activatedRoute ActivatedRoute No
telemetryService TelemetryService No
deviceDetectorService DeviceDetectorService No
router Router No
utilService UtilService No
configService ConfigService No
tncService TncService No
toasterService ToasterService No
profileService ProfileService No

Inputs

signUpdata
Type : any
startingForm
Type : any

Outputs

redirectToParent
Type : EventEmitter
subformInitialized
Type : EventEmitter<literal type>
triggerNext
Type : EventEmitter<boolean>

Methods

createUser
createUser(data?: any)
Parameters :
Name Type Optional
data any Yes
Returns : void
enableSignUpSubmitButton
enableSignUpSubmitButton()
Returns : void
generateResendOTP
generateResendOTP()
Returns : void
generateTelemetry
generateTelemetry(e)
Parameters :
Name Optional
e No
Returns : void
logCreateUserError
logCreateUserError(error)
Parameters :
Name Optional
error No
Returns : void
logGenerateOtpError
logGenerateOtpError(error)
Parameters :
Name Optional
error No
Returns : void
logVerifyOtpError
logVerifyOtpError(error)
Parameters :
Name Optional
error No
Returns : void
ngOnInit
ngOnInit()
Returns : void
redirectToSignPage
redirectToSignPage()

Redirects to sign in Page with success message

Returns : void
redirectToSignUp
redirectToSignUp()
Returns : void
resendOTP
resendOTP(captchaResponse?)
Parameters :
Name Optional
captchaResponse Yes
Returns : boolean
resendOtpEnablePostTimer
resendOtpEnablePostTimer()
Returns : void
resetGoogleCaptcha
resetGoogleCaptcha()
Returns : void
resolved
resolved(captchaResponse: string)
Parameters :
Name Type Optional
captchaResponse string No
Returns : void
setInteractEvent
setInteractEvent()
Returns : void
showAndHidePopup
showAndHidePopup(mode: boolean)
Parameters :
Name Type Optional
mode boolean No
Returns : void
telemetryLogEvents
telemetryLogEvents(api: any, status: boolean)
Parameters :
Name Type Optional
api any No
status boolean No
Returns : void
updateUserBasicInfo
updateUserBasicInfo()
Returns : void
verifyOTP
verifyOTP()
Returns : void

Properties

Public activatedRoute
Type : ActivatedRoute
captchaRef
Type : RecaptchaComponent
Decorators :
@ViewChild('captchaRef')
Public configService
Type : ConfigService
counter
createUserErrorInteractEdata
Type : any
Public deviceDetectorService
Type : DeviceDetectorService
disableResendButton
Default value : false
disableSubmitBtn
Default value : true
emailAddress
Type : any
errorMessage
Type : string
generateOTPErrorInteractEdata
Type : any
generateVerifyOtpErrorInteractEdata
Type : any
googleCaptchaSiteKey
Type : string
infoMessage
Type : string
instance
Type : string
isP2CaptchaEnabled
Type : any
maxResendTry
Type : number
Default value : 4
mode
Type : string
otpForm
Type : UntypedFormGroup
phoneNumber
Type : any
redirecterrorMessage
Default value : false
remainingAttempt
resendOTPbtn
resendOtpCounter
Type : number
Default value : 1
Public resourceService
Type : ResourceService
Public router
Type : Router
showSignUpLink
Default value : false
showTncPopup
Default value : false
Public signupService
Type : SignupService
submitOtpInteractEdata
Type : IInteractEventEdata
submitResendOtpInteractEdata
Type : IInteractEventEdata
telemetryCdata
Type : Array<literal type>
telemetryEnd
Type : IEndEventInput
Public telemetryService
Type : TelemetryService
termsAndConditionLink
Type : string
tncLatestVersion
Type : string
Public tncService
Type : TncService
unabletoVerifyErrorMessage
Type : string
Public utilService
Type : UtilService
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { SignupService } from './../../services';
import { ResourceService, ServerResponse, UtilService, ConfigService, ToasterService } from '@sunbird/shared';
import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import * as _ from 'lodash-es';
import { DeviceDetectorService } from 'ngx-device-detector';
import { IEndEventInput, IInteractEventEdata, TelemetryService } from '@sunbird/telemetry';
import { TncService } from '@sunbird/core';
import { RecaptchaComponent } from 'ng-recaptcha';
import { ProfileService } from '@sunbird/profile';

@Component({
  selector: 'app-otp',
  templateUrl: './otp.component.html',
  styleUrls: ['./otp.component.scss', '../signup/signup_form.component.scss']
})
export class OtpComponent implements OnInit {
  @ViewChild('captchaRef') captchaRef: RecaptchaComponent;
  @Input() signUpdata: any;
  @Output() redirectToParent = new EventEmitter();
  otpForm: UntypedFormGroup;
  disableSubmitBtn = true;
  mode: string;
  errorMessage: string;
  infoMessage: string;
  unabletoVerifyErrorMessage: string;
  disableResendButton = false;
  showSignUpLink = false;

  telemetryEnd: IEndEventInput;
  submitOtpInteractEdata: IInteractEventEdata;
  submitResendOtpInteractEdata: IInteractEventEdata;
  generateOTPErrorInteractEdata: any;
  generateVerifyOtpErrorInteractEdata: any;
  createUserErrorInteractEdata: any;
  telemetryCdata: Array<{}>;
  instance: string;
  emailAddress: any;
  phoneNumber: any;
  remainingAttempt: 'string';
  resendOTPbtn;
  counter;
  resendOtpCounter = 1;
  maxResendTry = 4;
  googleCaptchaSiteKey: string;
  isP2CaptchaEnabled: any;
  redirecterrorMessage = false;
  termsAndConditionLink: string;
  tncLatestVersion: string;
  showTncPopup = false;
  @Output() subformInitialized: EventEmitter<{}> = new EventEmitter<{}>();
  @Output() triggerNext: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Input() startingForm: any;

  constructor(public resourceService: ResourceService, public signupService: SignupService,
    public activatedRoute: ActivatedRoute, public telemetryService: TelemetryService,
    public deviceDetectorService: DeviceDetectorService, public router: Router,
    public utilService: UtilService, public configService: ConfigService,
    public tncService: TncService, private toasterService: ToasterService,
    private profileService: ProfileService) {
  }

  ngOnInit() {
    // console.log('Global Object data => ', this.startingForm); // TODO: log!
    this.emailAddress = _.get(this.startingForm, 'emailPassInfo.type') === 'email' ? _.get(this.startingForm, 'emailPassInfo.key') : '';
    this.phoneNumber = _.get(this.startingForm, 'emailPassInfo.type') === 'phone' ? _.get(this.startingForm, 'emailPassInfo.key') : '';
    this.mode = _.get(this.startingForm, 'emailPassInfo.type');
    this.otpForm = new UntypedFormGroup({
      otp: new UntypedFormControl('', [Validators.required]),
      tncAccepted: new UntypedFormControl(false, [Validators.requiredTrue])
    });
    this.tncService.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'));
    });
    this.enableSignUpSubmitButton();
    this.unabletoVerifyErrorMessage = this.mode === 'phone' ? this.resourceService.frmelmnts.lbl.unableToVerifyPhone :
      this.resourceService.frmelmnts.lbl.unableToVerifyEmail;
    this.setInteractEvent();
    this.instance = _.upperCase(this.resourceService.instance);
    this.resendOtpEnablePostTimer();
    try {
      this.googleCaptchaSiteKey = (<HTMLInputElement>document.getElementById('googleCaptchaSiteKey')).value;
    } catch (error) {
      this.googleCaptchaSiteKey = '';
    }
    this.isP2CaptchaEnabled = (<HTMLInputElement>document.getElementById('p2reCaptchaEnabled'))
      ? (<HTMLInputElement>document.getElementById('p2reCaptchaEnabled')).value : 'true';
  }
  resendOtpEnablePostTimer() {
    this.counter = 20;
    this.disableResendButton = false;
    setTimeout(() => {
      this.disableResendButton = true;
    }, 22000);
    const interval = setInterval(() => {
      this.resendOTPbtn = this.resourceService.frmelmnts.lbl.resendOTP + ' (' + this.counter + ')';
      this.counter--;
      if (this.counter < 0) {
        this.resendOTPbtn = this.resourceService.frmelmnts.lbl.resendOTP;
        clearInterval(interval);
      }
    }, 1000);
  }
  verifyOTP() {
    const wrongOTPMessage = this.mode === 'phone' ? this.resourceService.frmelmnts.lbl.wrongPhoneOTP :
      this.resourceService.frmelmnts.lbl.wrongEmailOTP;
    this.disableSubmitBtn = true;
    const request = {
      'request': {
        'key': _.get(this.startingForm, 'emailPassInfo.key'),
        'type': this.mode,
        'otp': _.trim(this.otpForm.controls.otp.value)
      }
    };
    this.signupService.verifyOTP(request).subscribe(
      (data: ServerResponse) => {
        this.infoMessage = '';
        this.errorMessage = '';
        if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
          this.updateUserBasicInfo();
        } else {
          this.createUser(data);
        }
      },
      (err) => {
        this.logVerifyOtpError(err.error.params.errmsg);
        this.telemetryService.interact(this.generateVerifyOtpErrorInteractEdata);
        if (_.get(err, 'error.result.remainingAttempt') === 0) {
          this.utilService.redirectToLogin(this.resourceService.messages.emsg.m0050);
        } else {
          this.infoMessage = '';
          this.otpForm.controls.otp.setValue('');
          this.remainingAttempt = _.get(err, 'error.result.remainingAttempt');
          this.errorMessage =
            _.get(err, 'error.params.status') === this.configService.constants.HTTP_STATUS_CODES.OTP_VERIFICATION_FAILED ?
              _.get(this.resourceService, 'messages.imsg.m0086') : wrongOTPMessage;
          if (this.disableResendButton) {
            this.showSignUpLink = true;
            this.telemetryService.end(this.telemetryEnd);
          }
          this.disableSubmitBtn = false;
        }
      }
    );
  }

  logVerifyOtpError(error) {
    this.generateVerifyOtpErrorInteractEdata = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: this.telemetryCdata,
      },
      edata: {
        id: 'invalid-otp-error',
        type: 'click',
        pageid: 'otp',
        extra: {
          'isError': 'true'
        }
      }
    };
  }

  createUser(data?: any) {
    let identifier = '';
    const createRequest = {
      params: {
        source: _.get(this.activatedRoute, 'snapshot.queryParams.client_id'),
        signupType: 'self'
      },
      'request': {
        'firstName': _.trim(_.get(this.startingForm, 'basicInfo.name')),
        'password': _.trim(_.get(this.startingForm, 'emailPassInfo.password')),
        'dob': _.get(this.startingForm, 'basicInfo.yearOfBirth').toString(),
      }
    };
    if (this.mode === 'phone') {
      createRequest.request['phone'] = _.get(this.startingForm, 'emailPassInfo.key').toString();
      createRequest.request['phoneVerified'] = true;
      identifier = _.get(this.startingForm, 'emailPassInfo.key').toString();
    } else {
      createRequest.request['email'] = _.get(this.startingForm, 'emailPassInfo.key');
      createRequest.request['emailVerified'] = true;
      identifier = _.get(this.startingForm, 'emailPassInfo.key');
    }
    createRequest.request['reqData'] = _.get(data, 'reqData');
    if (this.otpForm.controls.tncAccepted.value && this.otpForm.controls.tncAccepted.status === 'VALID') {
      this.signupService.createUserV3(createRequest).subscribe((resp: ServerResponse) => {
        this.telemetryLogEvents('sign-up', true);
        const tncAcceptRequestBody = {
          request: {
            version: this.tncLatestVersion,
            identifier: identifier
          }
        };
        this.signupService.acceptTermsAndConditions(tncAcceptRequestBody).subscribe(res => {
          this.telemetryLogEvents('accept-tnc', true);
          this.redirectToSignPage();
        }, (err) => {
          this.telemetryLogEvents('accept-tnc', false);
          this.redirectToSignPage();
        });
      },
        (err) => {
          this.telemetryLogEvents('sign-up', false);
          this.infoMessage = '';
          this.errorMessage = this.resourceService.messages.fmsg.m0085;
          this.disableSubmitBtn = false;
          this.logCreateUserError(err.error.params.errmsg);
          this.telemetryService.interact(this.createUserErrorInteractEdata);
          if (err.status === 301) {
            this.redirecterrorMessage = true;
          } else {
            this.redirecterrorMessage = false;
          }
        }
      );
    }
  }

  /**
   * Redirects to sign in Page with success message
   */
  redirectToSignPage() {
    const reqQuery = this.activatedRoute.snapshot.queryParams;
    const queryObj = _.pick(reqQuery,
      ['client_id', 'redirect_uri', 'scope', 'state', 'response_type', 'version']);
    queryObj['success_message'] = this.mode === 'phone' ? this.resourceService.frmelmnts.lbl.createUserSuccessWithPhone :
      this.resourceService.frmelmnts.lbl.createUserSuccessWithEmail;
    const query = Object.keys(queryObj).map((key) => {
      return encodeURIComponent(key) + '=' + encodeURIComponent(queryObj[key]);
    }).join('&');
    const redirect_uri = reqQuery.error_callback + '?' + query;
    this.telemetryService.end(this.telemetryEnd);
    window.location.href = redirect_uri;
  }

  logCreateUserError(error) {
    this.createUserErrorInteractEdata = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: this.telemetryCdata,
      },
      edata: {
        id: 'create-user-error',
        type: 'click',
        pageid: 'otp',
        extra: {
          'isError': 'true'
        }
      }
    };
  }

  resendOTP(captchaResponse?) {
    this.resendOtpCounter = this.resendOtpCounter + 1;
    if (this.resendOtpCounter >= this.maxResendTry) {
      this.disableResendButton = false;
      this.infoMessage = '';
      this.errorMessage = this.resourceService.frmelmnts.lbl.OTPresendMaxretry;
      return false;
    }
    const request = {
      'request': {
        'key': _.trim(_.get(this.startingForm, 'emailPassInfo.key').toString()),
        'type': this.mode
      }
    };
    this.signupService.generateOTPforAnonymousUser(request, captchaResponse).subscribe(
      (data: ServerResponse) => {
        this.resendOtpEnablePostTimer();
        this.errorMessage = '';
        this.infoMessage = this.resourceService.frmelmnts.lbl.resentOTP;
      },
      (err) => {
        this.infoMessage = '';
        this.errorMessage = this.resourceService.messages.fmsg.m0085;
        this.logGenerateOtpError(err.error.params.errmsg);
        this.telemetryService.interact(this.generateOTPErrorInteractEdata);
      }
    );
  }

  resolved(captchaResponse: string) {
    if (captchaResponse) {
      this.resendOTP(captchaResponse);
    }
  }

  resetGoogleCaptcha() {
    const element: HTMLElement = document.getElementById('resetGoogleCaptcha') as HTMLElement;
    element.click();
  }

  generateResendOTP() {
    if (this.isP2CaptchaEnabled === 'true') {
      this.resetGoogleCaptcha();
      this.captchaRef.execute();
    } else {
      this.resendOTP();
    }
  }

  logGenerateOtpError(error) {
    this.generateOTPErrorInteractEdata = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: this.telemetryCdata,
      },
      edata: {
        id: 'resend-otp-error',
        type: 'click',
        pageid: 'otp',
        extra: {
          'isError': 'true'
        }
      }
    };
  }

  enableSignUpSubmitButton() {
    this.otpForm.valueChanges.subscribe(val => {
      if (this.otpForm.status === 'VALID') {
        this.disableSubmitBtn = false;
      } else {
        this.disableSubmitBtn = true;
      }
    });
  }

  redirectToSignUp() {
    this.redirectToParent.emit('true');
  }

  setInteractEvent() {
    this.telemetryCdata = [{ 'type': 'otp', 'id': this.activatedRoute.snapshot.data.telemetry.uuid }];

    this.submitOtpInteractEdata = {
      id: 'submit-otp',
      type: 'click',
      pageid: 'otp',
      extra: {
        'values': '/sign-up'
      }
    };

    this.submitResendOtpInteractEdata = {
      id: 'resend-otp',
      type: 'click',
      pageid: 'otp'
    };

    this.telemetryEnd = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: this.telemetryCdata,
      },
      edata: {
        type: 'signup',
        pageid: 'signup',
        mode: 'self'
      }
    };
  }

  telemetryLogEvents(api: any, status: boolean) {
    let level = 'ERROR';
    let msg = api + ' failed';
    if (status) {
      level = 'SUCCESS';
      msg = api + ' success';
    }
    const event = {
      context: {
        env: 'self-signup'
      },
      edata: {
        type: api,
        level: level,
        message: msg
      }
    };
    this.telemetryService.log(event);
  }

  showAndHidePopup(mode: boolean) {
    this.showTncPopup = mode;
  }

  generateTelemetry(e) {
    const selectedType = e.target.checked ? 'selected' : 'unselected';
    const interactData = {
      context: {
        env: 'self-signup',
        cdata: [
          { id: 'user:tnc:accept', type: 'Feature' },
          { id: 'SB-16663', type: 'Task' }
        ]
      },
      edata: {
        id: 'user:tnc:accept',
        type: 'click',
        subtype: selectedType,
        pageid: 'self-signup'
      }
    };
    this.telemetryService.interact(interactData);
  }

  updateUserBasicInfo() {
    const req = {
      'firstName': _.trim(_.get(this.startingForm, 'basicInfo.name')),
      'dob': _.get(this.startingForm, 'basicInfo.yearOfBirth').toString(),
    };
    this.profileService.updateProfile(req).subscribe(res => {
      if(_.get(res, 'result.response') === 'SUCCESS') {
        let _msg =  _.get(this.startingForm, 'emailPassInfo.type') === 'phone' ? this.resourceService.frmelmnts.lbl.createUserSuccessWithPhone :
        this.resourceService.frmelmnts.lbl.createUserSuccessWithEmail;
        this.toasterService.success(_msg);
        setTimeout(() => {
          this.router.navigate(['/resources']);
        }, 1000);
      } else {
        this.toasterService.error(this.resourceService.messages.fmsg.m0085);
      }
    }, err => {
      this.toasterService.error(this.resourceService.messages.fmsg.m0085);
    });
  }
}
<!-- user-details gray box new design -->
 <div class="user-detail-container p-24 my-16"role="list">
  <div class="user-detail-list" role="listitem" tabindex="0" attr.aria-label="Name:{{startingForm?.basicInfo?.name}}"  *ngIf="startingForm && startingForm?.basicInfo?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">Name:</label>
    <label class="label-values fnormal font-weight-bold">{{startingForm?.basicInfo?.name}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="Year of Birth:{{startingForm?.basicInfo?.yearOfBirth}}" *ngIf="startingForm && startingForm?.basicInfo?.yearOfBirth">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">Year of Birth:</label>
    <label class="label-values fnormal font-weight-bold">{{startingForm?.basicInfo?.yearOfBirth}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="State:{{startingForm?.onboardingInfo?.children?.persona?.state?.name}}" *ngIf="startingForm && startingForm?.onboardingInfo?.children?.persona?.state?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">State:</label>
    <label
      class="label-values fnormal font-weight-bold">{{startingForm?.onboardingInfo?.children?.persona?.state?.name}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="District:{{startingForm?.onboardingInfo?.children?.persona?.district?.name}}" *ngIf="startingForm && startingForm?.onboardingInfo?.children?.persona?.district?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">District:</label>
    <label
      class="label-values fnormal font-weight-bold">{{startingForm?.onboardingInfo?.children?.persona?.district?.name}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="School:{{startingForm?.onboardingInfo?.children?.persona?.school?.name}}" *ngIf="startingForm && startingForm?.onboardingInfo?.children?.persona?.school?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">School:</label>
    <label
      class="label-values fnormal font-weight-bold">{{startingForm?.onboardingInfo?.children?.persona?.school?.name}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="Block:{{startingForm?.onboardingInfo?.children?.persona?.block?.name}}" *ngIf="startingForm && startingForm?.onboardingInfo?.children?.persona?.block?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">Block:</label>
    <label
      class="label-values fnormal font-weight-bold">{{startingForm?.onboardingInfo?.children?.persona?.block?.name}}</label>
  </div>
  <div class="user-detail-list" role="listitem" tabindex="0"  attr.aria-label="Cluster:{{startingForm?.onboardingInfo?.children?.persona?.cluster?.name}}" *ngIf="startingForm && startingForm?.onboardingInfo?.children?.persona?.cluster?.name">
    <label class="label-names fnormal font-weight-normal pr-8" role="heading">Cluster:</label>
    <label
      class="label-values fnormal font-weight-bold">{{startingForm?.onboardingInfo?.children?.persona?.cluster?.name}}</label>
  </div>
</div>
<!-- user-details gray box new design end-->
<div class="signup-form-content">
<!-- <p *ngIf="mode === 'phone' && !showSignUpLink" class="line-height-1-3 grey text text-center mb-50">{{resourceService.frmelmnts.instn.t0081 | interpolate:'{instance}': instance}}</p>
<p *ngIf="mode === 'email' && !showSignUpLink" class="line-height-1-3 grey text text-center mb-50">{{resourceService.frmelmnts.instn.t0082 | interpolate:'{instance}': instance}}</p> -->

<!-- <div class="grey text text-center pt-16">{{resourceService.frmelmnts.lbl.OTPhasbeensent}} {{resourceService.frmelmnts.lbl.toYourEmailPhone}}</div>-->
<div tabindex="0" class="grey text text-center otp-label">
  <span *ngIf="emailAddress">{{resourceService.frmelmnts.lbl.OTPhasbeensentToEmail}}:<br><b>{{emailAddress}}</b></span>
  <span *ngIf="phoneNumber">{{resourceService.frmelmnts.lbl.OTPhasbeensentToPhone}}:<br><b>{{phoneNumber}}</b></span>
</div>
<div tabindex="0" class="grey text text-center mb-16 grey-text">{{resourceService.frmelmnts.lbl.OTPvalid}}</div>

<div tabindex="0" class="grey text font-weight-bold text-center otp-label" *ngIf="startingForm && startingForm?.basicInfo?.isMinor">
  <span>{{resourceService.frmelmnts.lbl.enterOTPByParent}}</span>
</div>

<label  tabindex="0" *ngIf="redirecterrorMessage" class="color-danger sb-color-red text fs-1 text-center mb-8">The redirectURL/errorcallbackURL do not match the domain</label>
<div *ngIf="showSignUpLink" class="">{{unabletoVerifyErrorMessage}}<br> Please <span tabindex="0" (click)="redirectToSignUp()" class="fs-1 blue text font-weight-bold cursor-pointer" role="button" tabindex="0">{{resourceService.frmelmnts.lbl.signUp}}</span> again
</div>
<form class="sb-form borderd my-16" [formGroup]="otpForm">
  <div class="sb-field-group mb-16 text-left">
    <div class="sb-field">
      <label *ngIf="!infoMessage" for="enterOTP"
        class="fs-1 text-left mb-8 font-weight-bold">{{resourceService.frmelmnts.lbl.oneTimePassword}}</label>
      <label *ngIf="errorMessage" class="sb-text-error d-inline-block line-height-1-3">{{errorMessage |
        interpolate:'{remainingAttempt}': remainingAttempt}}</label>
      <label *ngIf="infoMessage" class="text-center mb-10 d-inline-block line-height-1-3">{{infoMessage}}</label>
      <input class="sb-form-control" tabindex="0" autofocus id="enterOTP" [ngClass]="{'orange-border': errorMessage}"
        formControlName="otp" type="text" name="otp" placeholder="{{resourceService.frmelmnts.lbl.enterOTP}}">
    </div>
  </div>
  <re-captcha *ngIf="isP2CaptchaEnabled === 'true'" #captchaRef="reCaptcha"
    (resolved)="$event && resolved($event) && captchaRef.reset()" siteKey="{{googleCaptchaSiteKey}}" size="invisible">
  </re-captcha>

  <!-- Terms and Conditions popup -->
  <!-- For Minor -->
  <div *ngIf="startingForm && startingForm?.basicInfo?.isMinor"
    class="required sb-checkbox sb-checkbox-primary sb-field my-16">
    <input type="checkbox" id="tncAccepted" role="checkbox" tabindex="0" (click)="generateTelemetry($event)"
      formControlName="tncAccepted" name="tncAccepted">
    <label for="tncAccepted" class="fsmall mr-0">{{resourceService?.frmelmnts?.lbl?.tncLabelForMinor}}
      <a class="text-underline fsmall" href="javascript:void(0)" tabindex="0" (click)="showAndHidePopup(true)">
        {{resourceService?.frmelmnts?.lbl?.tncAcceptLabel | interpolate:'{instance}': instance}}
      </a> {{resourceService?.frmelmnts?.lbl?.tncLabelForMinorSub | interpolate:'{instance}': instance}}
    </label>
  </div>
  <!-- For Minor -->

  <!-- For Major -->
  <div *ngIf="startingForm && !startingForm?.basicInfo?.isMinor"
    class="required sb-checkbox sb-checkbox-primary sb-field my-16">
    <input type="checkbox" id="tncAccepted" role="checkbox" tabindex="0" (click)="generateTelemetry($event)"
      formControlName="tncAccepted" name="tncAccepted">
    <label for="tncAccepted" class="fsmall mr-0">{{resourceService?.frmelmnts?.lbl?.tncLabelForMajor}}
      <a class="text-underline fsmall" href="javascript:void(0)" tabindex="0" (click)="showAndHidePopup(true)">
        {{resourceService?.frmelmnts?.lbl?.tncAcceptLabel | interpolate:'{instance}': instance}}
      </a>
    </label>
  </div>
  <!-- For Major -->
  <!-- Terms and Conditions popup -->

  <div class="assessment-action-buttons mt-16 d-flex flex-ai-center flex-dc">
    <button type="submit" [attr.readonly]="disableSubmitBtn" role="button" appTelemetryInteract
      [telemetryInteractEdata]="submitOtpInteractEdata" [telemetryInteractCdata]="telemetryCdata"
      class="sb-btn sb-btn-normal w-100" [disabled]="disableSubmitBtn"
      [attr.aria-disabled]="disableSubmitBtn == true ? true : false"
      [ngClass]="{'sb-btn-disabled':disableSubmitBtn, 'sb-btn-primary':!disableSubmitBtn}" tabindex="0"
      (click)="verifyOTP()">{{resourceService.frmelmnts.lbl.submit}}</button>

      <span class="mt-16 w-100 text-center">Didn’t Receive an OTP? <button type="button" [attr.readonly]="disableResendButton" appTelemetryInteract
        [telemetryInteractEdata]="submitResendOtpInteractEdata" [telemetryInteractCdata]="telemetryCdata"
        class="sb-btn sb-btn-normal sb-btn-outline-primary mr-8" tabindex="0"
        [ngClass]="{'sb-btn-disabled resend-disable': !disableResendButton}" [disabled]="!disableResendButton"
        [attr.aria-disabled]="disableResendButton == false ? false : true" (click)="generateResendOTP();" type="button"
        value="{{resendOTPbtn}}">{{resendOTPbtn}}</button></span>
  </div>
  <a tabindex="0" role="button" aria-label="re captcha" (click)="captchaRef.reset()" id="resetGoogleCaptcha"></a>
</form>
<app-tnc-popup (close)="showAndHidePopup(false)" [tncUrl]="termsAndConditionLink" #termsAndCondPopUp
  *ngIf="showTncPopup"></app-tnc-popup>
</div>


./otp.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

.ui.raised.shadow.container.segment {
    margin-left: auto !important;
    margin-right: auto !important;
    padding: 0;
    width: calc(100% - 4%) !important;
}

@media only screen and (min-width: 1024px) {
    .ui.raised.shadow.container.segment {
        margin: calculateRem(50px) auto !important;
        width: calculateRem(944px) !important;
        padding: calculateRem(20px);
        box-shadow: 0 calculateRem(2px) calculateRem(16px) 0 rgba(var(--rc-rgba-black), 0.2);
    }
}
@media only screen and (max-width: 767px) {
    .ui.form .fields {
        flex-wrap: nowrap;
    }
}
.ui.form.borderd input[type=text],
.ui.form.borderd input[type=text]:focus,
.ui.form.borderd input[type=email],
.ui.form.borderd input[type=number],
.ui.form.borderd input[type=tel],
.ui.form.borderd input[type=password],
.ui.form.borderd input[type=url],
.ui.form.borderd input:not([type]),
.ui.form.borderd input:not([type]):focus {
    border: calculateRem(1px) solid var(--gray-300);
    padding: 0.8em 0 0.8em 1em;
    border-radius: calculateRem(4px);
}
.ui.light-sea-green.button {
    background: var(--secondary-400);
    color: var(--white);
}
.ui.grey.button {
    font-size: var(--font-size-sm);
    height: calculateRem(32px);
}
.ui.button.sb-btn-primary{
    border-color: var(--primary-color);
    background-color: var(--primary-color);
    color: var(--white);
    height: calculateRem(32px);
    font-size: var(--font-size-sm);
}
.grey-text{
    color: var(--gray-800) !important;
    font-size: calculateRem(12px) !important;
}
.grey.text {
    color: var(--black);
    pointer-events: none !important;
    cursor: not-allowed !important;
    font-size: calculateRem(14px);
}

.fullpage {
    ::ng-deep {
        .ui.fullscreen.modal>.close {
            opacity: 0;
            pointer-events: none;
        }        
    }
}
i.close.icon {
    font-size: 1.5rem;
    position: absolute;
    right: calculateRem(6px);
    top: calculateRem(12px);
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.ui.form .field>label {
    font-size: 1rem !important;
    font-weight: normal;
}
.width-300 {
    width: calculateRem(300px) !important;
}
.ui.form.borderd [type="radio"]:checked + label:before,
.ui.form.borderd [type="radio"]:not(:checked) + label:before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    width: calculateRem(16px);
    height: calculateRem(16px);
    border: calculateRem(2px) solid var(--gray-300) !important;
    border-radius: 100%;
    background: var(--white);
}
.ui.form.borderd [type="radio"]:checked + label:before {
    border: calculateRem(2px) solid var(--primary-400) !important;
}
.ui.form.borderd [type="radio"]:checked + label:after,
.ui.form.borderd [type="radio"]:not(:checked) + label:after {
    content: '';
    width: calculateRem(8px);
    height: calculateRem(8px);
    background: var(--primary-400) !important;
    position: absolute;
    top: calculateRem(4px);
    left: calculateRem(4px);
    border-radius: 100%;
    -webkit-transition: all 0.2s ease;
    transition: all 0.2s ease;
}
.ui.form.borderd [type="radio"]:not(:checked) + label:after {
    opacity: 0;
    -webkit-transform: scale(0);
    transform: scale(0);
}
.ui.form.borderd [type="radio"]:checked + label:after {
    opacity: 1;
    -webkit-transform: scale(1);
    transform: scale(1);
}

.ui[class*="left icon"].input>input {
    padding-left: 3.37142857em !important;
}

.ui.left.icon.input .icon {
    left: calculateRem(11px);
    top: calculateRem(14px);
    font-size: 1rem;
    font-family: inherit;
}
.opacity-1 {
    opacity: 1 !important;
}
.ctct-inline-form .g-recaptcha {
    display: none !important
}
.otp-label{
    line-height: 1.8;
}
.resend-disable {
    background-color: var(--gray-100) !important;
    color: var(--gray-200) !important;
}
.sb-btn-disabled {
    color: var(--gray-400);
  }

  // user-details gray box new design css
.user-detail-container{
    border-radius: 1.5rem;
    background: var(--rc-dddddd);
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 0.5rem;
    text-transform: capitalize;
    width: 100%;
    max-width: 36rem;
    margin: 1rem auto;

    .user-detail-list{
        display: flex;
        @include respond-below(sm){
            flex-direction: column;
        }
        .label-values{
            word-break: break-word;
        }
    }

    .user-detail-list:nth-child(1){ order: 1; }
    .user-detail-list:nth-child(2) { order: 2; }
    .user-detail-list:nth-child(3) { order: 3; }
    .user-detail-list:nth-child(4){ order: 4; }
    .user-detail-list:nth-child(5){ order: 1; }
    .user-detail-list:nth-child(6) { order: 2; }
    .user-detail-list:nth-child(7) { order: 3; }
  }
  
  @include respond-below(sm){
    .user-detail-container {
      grid-template-columns: 1fr;
      border-radius:0;

      .user-detail-list:nth-child(1){ order: 1; }
      .user-detail-list:nth-child(2) { order: 2; }
      .user-detail-list:nth-child(3) { order: 3; }
      .user-detail-list:nth-child(4){ order: 4; }
      .user-detail-list:nth-child(5){ order: 5; }
      .user-detail-list:nth-child(6) { order: 6; }
      .user-detail-list:nth-child(7) { order: 7; }
  
   }
  }

../signup/signup_form.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

.signup-form-content,.logo-content{
    width: 100%;
    max-width: calculateRem(360px);
    margin: 0 auto;
    padding:0 1rem
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""