src/app/modules/public/module/signup/components/otp/otp.component.ts
OnInit
selector | app-otp |
styleUrls | ./otp.component.scss, |
templateUrl | ./otp.component.html |
constructor(resourceService: ResourceService, signupService: SignupService, activatedRoute: ActivatedRoute, telemetryService: TelemetryService, deviceDetectorService: DeviceDetectorService, router: Router, utilService: UtilService, configService: ConfigService, tncService: TncService, toasterService: ToasterService, profileService: ProfileService)
|
||||||||||||||||||||||||||||||||||||
Parameters :
|
signUpdata | |
Type : any
|
|
startingForm | |
Type : any
|
|
redirectToParent | |
Type : EventEmitter
|
|
subformInitialized | |
Type : EventEmitter<literal type>
|
|
triggerNext | |
Type : EventEmitter<boolean>
|
|
createUser | ||||||
createUser(data?: any)
|
||||||
Parameters :
Returns :
void
|
enableSignUpSubmitButton |
enableSignUpSubmitButton()
|
Returns :
void
|
generateResendOTP |
generateResendOTP()
|
Returns :
void
|
generateTelemetry | ||||
generateTelemetry(e)
|
||||
Parameters :
Returns :
void
|
logCreateUserError | ||||
logCreateUserError(error)
|
||||
Parameters :
Returns :
void
|
logGenerateOtpError | ||||
logGenerateOtpError(error)
|
||||
Parameters :
Returns :
void
|
logVerifyOtpError | ||||
logVerifyOtpError(error)
|
||||
Parameters :
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 :
Returns :
boolean
|
resendOtpEnablePostTimer |
resendOtpEnablePostTimer()
|
Returns :
void
|
resetGoogleCaptcha |
resetGoogleCaptcha()
|
Returns :
void
|
resolved | ||||||
resolved(captchaResponse: string)
|
||||||
Parameters :
Returns :
void
|
setInteractEvent |
setInteractEvent()
|
Returns :
void
|
showAndHidePopup | ||||||
showAndHidePopup(mode: boolean)
|
||||||
Parameters :
Returns :
void
|
telemetryLogEvents |
telemetryLogEvents(api: any, status: boolean)
|
Returns :
void
|
updateUserBasicInfo |
updateUserBasicInfo()
|
Returns :
void
|
verifyOTP |
verifyOTP()
|
Returns :
void
|
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
}