src/app/modules/public/module/signup/components/signup-email-password/signup-email-password.component.ts
OnInit
OnDestroy
AfterViewInit
selector | app-signup-email-password |
styleUrls | ./signup-email-password.component.scss, |
templateUrl | ./signup-email-password.component.html |
constructor(formBuilder: UntypedFormBuilder, resourceService: ResourceService, signupService: SignupService, toasterService: ToasterService, tenantService: TenantService, deviceDetectorService: DeviceDetectorService, activatedRoute: ActivatedRoute, telemetryService: TelemetryService, navigationhelperService: NavigationHelperService, utilService: UtilService, configService: ConfigService, recaptchaService: RecaptchaService, tncService: TncService)
|
||||||||||||||||||||||||||||||||||||||||||
Parameters :
|
startingForm | |
Type : object
|
|
subformInitialized | |
Type : EventEmitter<literal type>
|
|
triggerNext | |
Type : EventEmitter<boolean>
|
|
displayPassword |
displayPassword()
|
Returns :
void
|
enableSignUpSubmitButton |
enableSignUpSubmitButton()
|
Returns :
void
|
generateOTP | ||||
generateOTP(captchaResponse?)
|
||||
Parameters :
Returns :
void
|
generateTelemetry | ||||
generateTelemetry(e)
|
||||
Parameters :
Returns :
void
|
getReCaptchaToken | ||||||||
getReCaptchaToken(inputType: string)
|
||||||||
Parameters :
Returns :
void
|
initializeFormFields |
initializeFormFields()
|
Returns :
void
|
initializeUpdateForm |
initializeUpdateForm()
|
Returns :
void
|
ngAfterViewInit |
ngAfterViewInit()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onContactTypeValueChanges |
onContactTypeValueChanges()
|
Returns :
void
|
onPasswordChange | ||||||
onPasswordChange(passCtrl: UntypedFormControl)
|
||||||
Parameters :
Returns :
void
|
onSubmitSignUpForm | ||||
onSubmitSignUpForm(captchaResponse?)
|
||||
Parameters :
Returns :
void
|
resetGoogleCaptcha |
resetGoogleCaptcha()
|
Returns :
void
|
resetInput |
resetInput()
|
Returns :
void
|
resolved | ||||||
resolved(captchaResponse: string)
|
||||||
Parameters :
Returns :
void
|
setInteractEventData |
setInteractEventData()
|
Returns :
void
|
showAndHidePopup | ||||||
showAndHidePopup(mode: boolean)
|
||||||
Parameters :
Returns :
void
|
showParentForm | ||||
showParentForm(event)
|
||||
Parameters :
Returns :
void
|
signUpTelemetryImpression |
signUpTelemetryImpression()
|
Returns :
void
|
signUpTelemetryStart |
signUpTelemetryStart()
|
Returns :
void
|
submitSignupForm |
submitSignupForm()
|
Returns :
void
|
telemetryLogEvents |
telemetryLogEvents(api: any, status: boolean)
|
Returns :
void
|
vaidateUserContact | ||||
vaidateUserContact(captchaResponse?)
|
||||
Parameters :
Returns :
void
|
Public activatedRoute |
Type : ActivatedRoute
|
birthYearOptions |
Type : Array<number>
|
Default value : []
|
captchaRef |
Type : RecaptchaComponent
|
Decorators :
@ViewChild('captchaRef')
|
captchaResponse |
Type : string
|
Default value : ''
|
Public configService |
Type : ConfigService
|
Public deviceDetectorService |
Type : DeviceDetectorService
|
disableForm |
Default value : false
|
disableSubmitBtn |
Default value : true
|
formInputType |
Type : string
|
googleCaptchaSiteKey |
Type : string
|
instance |
Type : string
|
isIOSDevice |
Default value : false
|
isMinor |
Type : Boolean
|
Default value : false
|
isP1CaptchaEnabled |
Type : any
|
logo |
Type : string
|
Public navigationhelperService |
Type : NavigationHelperService
|
passwordError |
Type : string
|
Public recaptchaService |
Type : RecaptchaService
|
resourceDataSubscription |
Type : any
|
Public resourceService |
Type : ResourceService
|
sbFormBuilder |
Type : UntypedFormBuilder
|
showContact |
Type : string
|
Default value : 'phone'
|
showPassword |
Default value : false
|
showSignUpForm |
Default value : true
|
showTncPopup |
Default value : false
|
showUniqueError |
Type : string
|
Default value : ''
|
showUpdateSignUpForm |
Type : boolean
|
Default value : false
|
signUpForm |
Type : UntypedFormGroup
|
Public signupService |
Type : SignupService
|
submitInteractEdata |
Type : IInteractEventEdata
|
telemetryCdata |
Type : Array<literal type>
|
telemetryImpression |
Type : IImpressionEventInput
|
Public telemetryService |
Type : TelemetryService
|
telemetryStart |
Type : IStartEventInput
|
tenantDataSubscription |
Type : Subscription
|
tenantName |
Type : string
|
Public tenantService |
Type : TenantService
|
termsAndConditionLink |
Type : string
|
tncLatestVersion |
Type : string
|
Public tncService |
Type : TncService
|
Public toasterService |
Type : ToasterService
|
Public unsubscribe |
Default value : new Subject<void>()
|
updateSignUpForm |
Type : UntypedFormGroup
|
Public utilService |
Type : UtilService
|
yearOfBirth |
Type : string
|
import { Component, OnInit, EventEmitter, OnDestroy, AfterViewInit, ViewChild, Output, Input } from '@angular/core';
import { UntypedFormBuilder, Validators, UntypedFormGroup, UntypedFormControl, AbstractControl } from '@angular/forms';
import { Subject, Subscription } from 'rxjs';
import {
ResourceService,
ConfigService,
ServerResponse,
ToasterService,
NavigationHelperService,
UtilService,
RecaptchaService
} from '@sunbird/shared';
import { SignupService } from './../../services';
import { TenantService, TncService } from '@sunbird/core';
import { TelemetryService } from '@sunbird/telemetry';
import * as _ from 'lodash-es';
import { IStartEventInput, IImpressionEventInput, IInteractEventEdata } from '@sunbird/telemetry';
import { DeviceDetectorService } from 'ngx-device-detector';
import { ActivatedRoute } from '@angular/router';
import { RecaptchaComponent } from 'ng-recaptcha';
@Component({
selector: 'app-signup-email-password',
templateUrl: './signup-email-password.component.html',
styleUrls: ['./signup-email-password.component.scss' , '../signup/signup_form.component.scss']
})
export class SignupEmailPasswordComponent implements OnInit, OnDestroy, AfterViewInit {
@ViewChild('captchaRef') captchaRef: RecaptchaComponent;
public unsubscribe = new Subject<void>();
signUpForm: UntypedFormGroup;
sbFormBuilder: UntypedFormBuilder;
showContact = 'phone';
disableSubmitBtn = true;
disableForm = false;
showPassword = false;
captchaResponse = '';
googleCaptchaSiteKey: string;
showSignUpForm = true;
showUniqueError = '';
tenantDataSubscription: Subscription;
logo: string;
tenantName: string;
resourceDataSubscription: any;
telemetryStart: IStartEventInput;
telemetryImpression: IImpressionEventInput;
submitInteractEdata: IInteractEventEdata;
telemetryCdata: Array<{}>;
instance: string;
tncLatestVersion: string;
termsAndConditionLink: string;
passwordError: string;
showTncPopup = false;
birthYearOptions: Array<number> = [];
isMinor: Boolean = false;
formInputType: string;
isP1CaptchaEnabled: any;
yearOfBirth: string;
isIOSDevice = false;
@Output() subformInitialized: EventEmitter<{}> = new EventEmitter<{}>();
@Output() triggerNext: EventEmitter<boolean> = new EventEmitter<boolean>();
@Input() startingForm: object;
updateSignUpForm: UntypedFormGroup;
showUpdateSignUpForm: boolean = false;
constructor(formBuilder: UntypedFormBuilder, public resourceService: ResourceService,
public signupService: SignupService, public toasterService: ToasterService,
public tenantService: TenantService, public deviceDetectorService: DeviceDetectorService,
public activatedRoute: ActivatedRoute, public telemetryService: TelemetryService,
public navigationhelperService: NavigationHelperService, public utilService: UtilService,
public configService: ConfigService, public recaptchaService: RecaptchaService,
public tncService: TncService) {
this.sbFormBuilder = formBuilder;
}
ngOnInit() {
// console.log('Global Object data => ', this.startingForm); // TODO: log!
this.isMinor = _.get(this.startingForm, 'basicInfo.isMinor') ? _.get(this.startingForm, 'basicInfo.isMinor') : false;
this.isIOSDevice = /iPad|iPhone|iPod/.test(navigator.userAgent);
this.instance = _.upperCase(this.resourceService.instance || 'SUNBIRD');
this.tenantDataSubscription = this.tenantService.tenantData$.subscribe(
data => {
if (data && !data.err) {
this.logo = data.tenantData.logo;
this.tenantName = data.tenantData.titleName;
}
}
);
try {
this.googleCaptchaSiteKey = (<HTMLInputElement>document.getElementById('googleCaptchaSiteKey')).value;
} catch (error) {
this.googleCaptchaSiteKey = '';
}
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
this.showUpdateSignUpForm = true;
this.initializeUpdateForm();
} else {
this.initializeFormFields();
}
this.setInteractEventData();
// Telemetry Start
this.signUpTelemetryStart();
this.isP1CaptchaEnabled = (<HTMLInputElement>document.getElementById('p1reCaptchaEnabled'))
? (<HTMLInputElement>document.getElementById('p1reCaptchaEnabled')).value : 'true';
}
signUpTelemetryStart() {
const deviceInfo = this.deviceDetectorService.getDeviceInfo();
this.telemetryStart = {
context: {
env: this.activatedRoute.snapshot.data.telemetry.env,
cdata: this.telemetryCdata,
},
edata: {
type: this.activatedRoute.snapshot.data.telemetry.type,
pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
mode: this.activatedRoute.snapshot.data.telemetry.mode,
uaspec: {
agent: deviceInfo.browser,
ver: deviceInfo.browser_version,
system: deviceInfo.os_version,
platform: deviceInfo.os,
raw: deviceInfo.userAgent
}
}
};
}
signUpTelemetryImpression() {
this.telemetryImpression = {
context: {
env: this.activatedRoute.snapshot.data.telemetry.env,
cdata: this.telemetryCdata,
},
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()
}
};
}
initializeFormFields() {
this.signUpForm = this.sbFormBuilder.group({
password: new UntypedFormControl(null, [Validators.required, Validators.minLength(8)]),
confirmPassword: new UntypedFormControl(null, [Validators.required, Validators.minLength(8)]),
phone: new UntypedFormControl(null, [Validators.required, Validators.pattern(/^[6-9]\d{9}$/)]),
email: new UntypedFormControl(null, [Validators.email]),
contactType: new UntypedFormControl('phone'),
uniqueContact: new UntypedFormControl(null, [Validators.required]),
}, {
validator: (formControl) => {
const passCtrl = formControl.controls.password;
const conPassCtrl = formControl.controls.confirmPassword;
this.onPasswordChange(passCtrl);
if (_.trim(passCtrl.value) === '') { passCtrl.setErrors({ required: true }); }
if (_.trim(conPassCtrl.value) === '') { conPassCtrl.setErrors({ required: true }); }
if (passCtrl.value !== conPassCtrl.value) {
conPassCtrl.setErrors({ validatePasswordConfirmation: true });
} else { conPassCtrl.setErrors(null); }
return null;
}
});
this.onContactTypeValueChanges();
this.enableSignUpSubmitButton();
}
onPasswordChange(passCtrl: UntypedFormControl): void {
let emailVal;
if (this.showContact === 'email') {
emailVal = this.signUpForm.get('email').value;
}
const val = _.get(passCtrl, 'value');
const specRegex = new RegExp('^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[~.,)(}{\\[!"#$%&\'()*+,-./:;<=>?@[^_`{|}~\\]])(?=\\S+$).{8,}');
if (!specRegex.test(val)) {
this.passwordError = _.get(this.resourceService, 'frmelmnts.lbl.passwd');
passCtrl.setErrors({ passwordError: this.passwordError });
} else if (emailVal === val) {
this.passwordError = _.get(this.resourceService, 'frmelmnts.lbl.passwderr');
passCtrl.setErrors({ passwordError: this.passwordError });
} else {
this.passwordError = _.get(this.resourceService, 'frmelmnts.lbl.passwd');
passCtrl.setErrors(null);
}
}
onContactTypeValueChanges(): void {
let _form = this.signUpForm;
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
_form = this.updateSignUpForm;
}
const emailControl = _form.get('email');
const phoneControl = _form.get('phone');
_form.get('contactType').valueChanges.subscribe(
(mode: string) => {
this.setInteractEventData();
_form.controls['uniqueContact'].setValue('');
if (mode === 'email') {
_form.controls['phone'].setValue('');
emailControl.setValidators([Validators.required, Validators.email]);
phoneControl.clearValidators();
} else if (mode === 'phone') {
_form.controls['email'].setValue('');
emailControl.clearValidators();
phoneControl.setValidators([Validators.required, Validators.pattern('^\\d{10}$')]);
}
emailControl.updateValueAndValidity();
phoneControl.updateValueAndValidity();
});
}
enableSignUpSubmitButton() {
let _form = this.signUpForm;
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
_form = this.updateSignUpForm;
}
_form.valueChanges.subscribe(val => {
if (_form.status === 'VALID') {
this.disableSubmitBtn = false;
} else {
this.disableSubmitBtn = true;
}
});
}
vaidateUserContact(captchaResponse?) {
const value = this.signUpForm.controls.contactType.value === 'phone' ?
this.signUpForm?.controls?.phone?.value.toString() : this.signUpForm?.controls?.email?.value;
const uri = this.signUpForm.controls.contactType.value.toString() + '/' + value + '?captchaResponse=' + captchaResponse;
this.signupService.checkUserExists(uri).subscribe(
(data: ServerResponse) => {
if (_.get(data, 'result.exists')) {
this.signUpForm.controls['uniqueContact'].setValue('');
this.showUniqueError = this.signUpForm.controls.contactType.value === 'phone' ?
this.resourceService.frmelmnts.lbl.uniquePhone : this.resourceService.frmelmnts.lbl.uniqueEmail;
} else {
this.signUpForm.controls['uniqueContact'].setValue(true);
this.showUniqueError = '';
}
},
(err) => {
if (_.get(err, 'error.params.status') && err.error.params.status === 'USER_ACCOUNT_BLOCKED') {
this.showUniqueError = this.resourceService.frmelmnts.lbl.blockedUserError;
} else if (err.status === 418) {
this.signUpForm.controls['uniqueContact'].setValue(true);
this.showUniqueError = this.resourceService.frmelmnts.lbl.captchaValidationFailed;
} else {
this.signUpForm.controls['uniqueContact'].setValue(true);
this.showUniqueError = '';
}
}
);
}
displayPassword() {
if (this.showPassword) {
this.showPassword = false;
} else {
this.showPassword = true;
}
}
/**
* @param {string} inputType : User input type `email` or `phone`
* @description : Function to trigger reCaptcha for onBlur event of user input
* @since - release-3.0.1
*/
getReCaptchaToken(inputType: string) {
let _form = this.signUpForm;
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
_form = this.updateSignUpForm;
}
if (this.isP1CaptchaEnabled === 'true') {
this.resetGoogleCaptcha();
this.formInputType = inputType;
const emailControl =_form.get('email');
const phoneControl =_form.get('phone');
if (inputType === 'email' && emailControl.status === 'VALID' && emailControl.value !== '') {
_form.controls['uniqueContact'].setValue('');
this.captchaRef.execute();
} else if (inputType === 'phone' && phoneControl.status === 'VALID' && phoneControl.value !== '') {
_form.controls['uniqueContact'].setValue('');
this.captchaRef.execute();
}
} else if (_.get(this.startingForm, 'routeParams.loginMode') !== 'gmail') {
this.vaidateUserContact();
}
}
/**
* @description - Intermediate function to get captcha token and submit sign up form
* @since - release-3.0.3
*/
submitSignupForm() {
if (this.isP1CaptchaEnabled === 'true') {
this.resetGoogleCaptcha();
this.captchaRef.execute();
} else {
this.onSubmitSignUpForm();
}
}
resolved(captchaResponse: string) {
if (captchaResponse) {
if (this.formInputType && _.get(this.startingForm, 'routeParams.loginMode') !== 'gmail') {
this.vaidateUserContact(captchaResponse);
this.formInputType = undefined;
} else {
this.onSubmitSignUpForm(captchaResponse);
}
}
}
onSubmitSignUpForm(captchaResponse?) {
this.disableSubmitBtn = true;
this.generateOTP(captchaResponse);
}
generateOTP(captchaResponse?) {
let _form = this.signUpForm;
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
_form = this.updateSignUpForm;
}
const request = {
'request': {
'key': _form.controls.contactType.value === 'phone' ?
_form.controls.phone.value.toString() : _form.controls.email.value,
'type': _form.controls.contactType.value.toString()
}
};
if (this.isMinor) {
request.request['templateId'] = this.configService.constants.TEMPLATES.VERIFY_OTP_MINOR;
}
this.signupService.generateOTPforAnonymousUser(request, captchaResponse).subscribe(
(data: ServerResponse) => {
this.showSignUpForm = false;
this.disableSubmitBtn = false;
request.request['password'] = _form?.controls?.password?.value?.toString();
this.subformInitialized.emit(request.request);
this.triggerNext.emit();
},
(err) => {
const failedgenerateOTPMessage = (_.get(err, 'error.params.status') && err.error.params.status === 'PHONE_ALREADY_IN_USE') ||
(_.get(err, 'error.params.status') &&
err.error.params.status === 'EMAIL_IN_USE') ? err.error.params.errmsg : this.resourceService.messages.fmsg.m0085;
this.toasterService.error(failedgenerateOTPMessage);
if (this.isP1CaptchaEnabled === 'true') { this.resetGoogleCaptcha(); }
this.disableSubmitBtn = false;
}
);
}
resetGoogleCaptcha() {
const element: HTMLElement = document.getElementById('resetGoogleCaptcha') as HTMLElement;
element.click();
}
showParentForm(event) {
if (event === 'true') {
this.initializeFormFields();
this.showSignUpForm = true;
}
}
ngAfterViewInit () {
setTimeout(() => {
this.telemetryCdata = [{ 'type': 'signup', 'id': this.activatedRoute.snapshot.data.telemetry.uuid }];
this.signUpTelemetryImpression();
});
}
ngOnDestroy() {
if (this.tenantDataSubscription) {
this.tenantDataSubscription.unsubscribe();
}
this.unsubscribe.next();
this.unsubscribe.complete();
}
setInteractEventData() {
let _form = this.signUpForm;
if (_.get(this.startingForm, 'routeParams.loginMode') === 'gmail') {
_form = this.updateSignUpForm;
}
this.submitInteractEdata = {
id: 'submit-signup',
type: 'click',
pageid: 'signup',
extra: {
'contactType': _form.controls.contactType.value.toString()
}
};
}
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);
}
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;
}
initializeUpdateForm() {
this.updateSignUpForm = this.sbFormBuilder.group({
phone: new UntypedFormControl(null, [Validators.required, Validators.pattern(/^[6-9]\d{9}$/)]),
email: new UntypedFormControl(null, [Validators.email]),
contactType: new UntypedFormControl('phone'),
uniqueContact: new UntypedFormControl(null),
});
this.onContactTypeValueChanges();
this.enableSignUpSubmitButton();
}
resetInput() {
this.updateSignUpForm.controls.phone.reset();
this.updateSignUpForm.controls.email.reset();
}
}
<div *ngIf="showSignUpForm && !showUpdateSignUpForm" [appTelemetryStart]="telemetryStart" class="signup-form-content">
<form class="" [formGroup]="signUpForm" autocomplete="off" id="signUpForm">
<div class="required mb-20 text-center">
<label tabindex="0" id="phoneOrEmail" class="mb-0 fmedium">{{resourceService?.frmelmnts?.lbl?.phoneOrEmail}} <span *ngIf="isMinor">{{resourceService.frmelmnts?.lbl?.parentOrGuardian}}</span><span class="sb-color-red">*</span>
</label>
<label tabindex="0" class="fsmall mb-0 font-weight-normal">{{resourceService?.frmelmnts?.lbl?.otpSentMsg}}</label>
</div>
<div class="d-flex flex-ai-center mb-8" role="radiogroup">
<div class="field">
<div class="sb-radio-btn-checkbox sb-radio-btn-primary" role="radio" tabindex="0" (click)="showContact='phone';showUniqueError=null">
<input class="sb-form-control" type="radio" checked="checked" value="phone" formControlName="contactType"
role="phone" id="phoneNumber" aria-labelledby="phoneNumberLbl">
<label for="phoneNumber" id="phoneNumberLbl"
class="pl-20">{{resourceService.frmelmnts.lbl.phoneNumber}}</label>
</div>
</div>
<div class="field">
<div class="sb-radio-btn-checkbox sb-radio-btn-primary" role="radio" tabindex="0" (click)="showContact='email';showUniqueError=null">
<input class="sb-form-control" type="radio" formControlName="contactType" value="email" role="email"
id="email" aria-labelledby="emailLbl">
<label for="email" id="emailLbl" class="pl-20 text-capitalize">{{resourceService.frmelmnts.lbl.email}}</label>
</div>
</div>
</div>
<div class="field mb-16" *ngIf="showContact === 'email'">
<div class="signup-form signup-form--email">
<input tabindex="0" class="sb-form-control" id="withemail" type="email"
[ngClass]="{'orange-border': signUpForm.controls.email.touched && signUpForm.controls['email'].errors}"
formControlName="email" name="email" placeholder="{{resourceService.frmelmnts.lbl.email}}"
(blur)="getReCaptchaToken('email')">
</div>
<label tabindex="0" aria-describedby="withemail" class="sb-color-red font-weight-normal fsmall mb-0"
*ngIf="signUpForm.controls.email.touched && signUpForm.controls['email'].errors">{{resourceService.frmelmnts.lbl.validEmail}}</label>
<label class="sb-color-red font-weight-normal fsmall mb-0"
*ngIf="showUniqueError && signUpForm.controls.email.touched">{{showUniqueError}}</label>
</div>
<div>
<div class="field w-100 mb-16" *ngIf="showContact === 'phone'">
<div class="signup-form signup-form--phone">
<input id="signup-form-phone" id="withphone" tabindex="0" class="sb-form-control phone"
[ngClass]="{'orange-border': signUpForm.controls.phone.touched && signUpForm.controls['phone'].errors}"
formControlName="phone" type="number" name="phone" aria-required="true"
placeholder="{{resourceService.frmelmnts.lbl.tenDigitPhone}}" (blur)="getReCaptchaToken('phone')">
<div class="default-img fsmall">+91-</div>
</div>
<label class="sb-color-red font-weight-normal fsmall mb-0" *ngIf="showUniqueError && signUpForm.controls.phone.touched">{{showUniqueError}}</label>
</div>
<div class="required mb-16">
<label class="font-weight-normal">{{resourceService.frmelmnts.lbl.password}}<span
class="sb-color-red">*</span></label>
<div class="signup-form signup-form--password">
<input id="signup-form-password" tabindex="0" class="sb-form-control"
[ngClass]="{'orange-border': signUpForm.controls.password.touched && signUpForm.controls['password'].errors}"
[type]="showPassword ? 'text' : 'password'" formControlName="password" name="password" aria-required="true"
placeholder="{{resourceService.frmelmnts.lbl.EnterPassword}}">
<div class="default-img" role="button" [attr.aria-pressed]="showPassword == true ? true : false"
(click)="displayPassword()"><img class="showhideimage"
src="{{ showPassword ? 'assets/images/password-hidden.svg' : 'assets/images/password-visibile.svg'}}"
role="button" alt="show hide password" tabindex="0"></div>
</div>
<label tabindex="0" aria-describedby="signup-form-password" class="font-weight-normal sb-color-red mb-0 mt-4"
[ngClass]="{'error': ((signUpForm.controls.password.touched && signUpForm.controls['password'].errors))}">{{passwordError}}</label>
</div>
</div>
<div class="required mb-16">
<label class="font-weight-normal">{{resourceService.frmelmnts.lbl.confirmPassword}}<span
class="sb-color-red">*</span></label>
<input aria-required="true" id="signup-form-confirmPassword" tabindex="0" class="sb-form-control"
[ngClass]="{'orange-border': signUpForm.controls.confirmPassword.touched && signUpForm.controls['confirmPassword'].errors}"
formControlName="confirmPassword" type="password" name="confirmPassword"
placeholder="{{resourceService.frmelmnts.lbl.reEnterPassword}}">
<label aria-describedby="signup-form-confirmPassword" class="font-weight-normal sb-color-red mb-0"
*ngIf="signUpForm.controls.confirmPassword.touched && signUpForm.controls['confirmPassword'].errors">{{resourceService.frmelmnts.lbl.errorConfirmPassword}}</label>
</div>
<re-captcha *ngIf="isP1CaptchaEnabled === 'true'" tabindex='-1' #captchaRef="reCaptcha"
(resolved)="$event && resolved($event) && captchaRef.reset()" siteKey="{{googleCaptchaSiteKey}}" size="invisible">
</re-captcha>
</form>
<button [attr.aria-disabled]="disableSubmitBtn" [disabled]="disableSubmitBtn" type="submit" appTelemetryInteract
[telemetryInteractEdata]="submitInteractEdata" [telemetryInteractCdata]="telemetryCdata"
[ngClass]="{'sb-btn-disabled':disableSubmitBtn, 'sb-btn-primary':!disableSubmitBtn}"
class="sb-btn sb-btn-normal width-100 mt-8 text-uppercase" tabindex="0"
(click)="submitSignupForm()"><span>{{resourceService.frmelmnts.lbl.continue}}</span><span
class='arrow-icon pl-8'><i class="icon-svg icon-svg--xxs icon-back">
<svg class="icon icon-svg--white">
<use xlink:href="./assets/images/sprite.svg#arrow-long-right"></use>
</svg></i></span></button>
<a tabindex="0" role="button" aria-label="re captcha" (click)="captchaRef.reset()" id="resetGoogleCaptcha"></a>
</div>
<!-- Gmail user registration workflow with only phone / email fields -->
<div *ngIf="showSignUpForm && showUpdateSignUpForm" [appTelemetryStart]="telemetryStart" class="signup-form-content">
<form class="" [formGroup]="updateSignUpForm" autocomplete="off" id="updateSignUpForm">
<div class="required mb-20 text-center">
<label tabindex="0" id="phoneOrEmail" class="mb-0 fmedium">{{resourceService?.frmelmnts?.lbl?.phoneOrEmail}} <span *ngIf="isMinor">{{resourceService.frmelmnts?.lbl?.parentOrGuardian}}</span><span class="sb-color-red">*</span>
</label>
<label tabindex="0" class="fsmall mb-0 font-weight-normal">{{resourceService?.frmelmnts?.lbl?.otpSentMsg}}</label>
</div>
<div class="d-flex flex-ai-center mb-8" role="radiogroup">
<div class="field">
<div class="sb-radio-btn-checkbox sb-radio-btn-primary" role="radio" tabindex="0" (click)="showContact='phone';showUniqueError=null;resetInput()">
<input class="sb-form-control" type="radio" checked="checked" value="phone" formControlName="contactType"
role="phone" id="phoneNumber" aria-labelledby="phoneNumberLbl">
<label for="phoneNumber" id="phoneNumberLbl"
class="pl-20">{{resourceService.frmelmnts.lbl.phoneNumber}}</label>
</div>
</div>
<div class="field">
<div class="sb-radio-btn-checkbox sb-radio-btn-primary" role="radio" tabindex="0" (click)="showContact='email';showUniqueError=null;resetInput()">
<input class="sb-form-control" type="radio" formControlName="contactType" value="email" role="email"
id="email" aria-labelledby="emailLbl">
<label for="email" id="emailLbl" class="pl-20 text-capitalize">{{resourceService.frmelmnts.lbl.email}}</label>
</div>
</div>
</div>
<div class="field mb-16" *ngIf="showContact === 'email'">
<div class="signup-form signup-form--email">
<input tabindex="0" class="sb-form-control" id="withemail" type="email"
[ngClass]="{'orange-border': updateSignUpForm.controls.email.touched && updateSignUpForm.controls['email'].errors}"
formControlName="email" name="email" placeholder="{{resourceService.frmelmnts.lbl.email}}"
(blur)="getReCaptchaToken('email')">
</div>
<label tabindex="0" aria-describedby="withemail" class="sb-color-red font-weight-normal fsmall mb-0"
*ngIf="updateSignUpForm.controls.email.touched && updateSignUpForm.controls['email'].errors">{{resourceService.frmelmnts.lbl.validEmail}}</label>
<label class="sb-color-red font-weight-normal fsmall mb-0"
*ngIf="showUniqueError && updateSignUpForm.controls.email.touched">{{showUniqueError}}</label>
</div>
<div>
<div class="field w-100 mb-16" *ngIf="showContact === 'phone'">
<div class="signup-form signup-form--phone">
<input id="signup-form-phone" id="withphone" tabindex="0" class="sb-form-control phone"
[ngClass]="{'orange-border': updateSignUpForm.controls.phone.touched && updateSignUpForm.controls['phone'].errors}"
formControlName="phone" type="number" name="phone" aria-required="true"
placeholder="{{resourceService.frmelmnts.lbl.tenDigitPhone}}" (blur)="getReCaptchaToken('phone')">
<div class="default-img fsmall">+91-</div>
</div>
<label class="sb-color-red font-weight-normal fsmall mb-0" *ngIf="showUniqueError && updateSignUpForm.controls.phone.touched">{{showUniqueError}}</label>
</div>
</div>
<!-- Google invisible recaptcha -->
<re-captcha *ngIf="isP1CaptchaEnabled === 'true'" tabindex='-1' #captchaRef="reCaptcha"
(resolved)="$event && resolved($event) && captchaRef.reset()" siteKey="{{googleCaptchaSiteKey}}" size="invisible">
</re-captcha>
</form>
<button [attr.aria-disabled]="disableSubmitBtn" [disabled]="disableSubmitBtn" type="submit" appTelemetryInteract
[telemetryInteractEdata]="submitInteractEdata" [telemetryInteractCdata]="telemetryCdata"
[ngClass]="{'sb-btn-disabled':disableSubmitBtn, 'sb-btn-primary':!disableSubmitBtn}"
class="sb-btn sb-btn-normal width-100 mt-8 text-uppercase" tabindex="0"
(click)="submitSignupForm()"><span>{{resourceService.frmelmnts.lbl.continue}}</span><span
class='arrow-icon pl-8'><i class="icon-svg icon-svg--xxs icon-back">
<svg class="icon icon-svg--white">
<use xlink:href="./assets/images/sprite.svg#arrow-long-right"></use>
</svg></i></span></button>
<a tabindex="0" role="button" aria-label="re captcha" (click)="captchaRef.reset()" id="resetGoogleCaptcha"></a>
</div>
./signup-email-password.component.scss
@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
.signup-form {
position: relative;
.default-img {
position: absolute;
}
&--phone {
.default-img {
left: calculateRem(8px);
top: 50%;
transform: translateY(-50%);
}
}
&--password {
.default-img {
top: calculateRem(8px);
right: calculateRem(12px);
}
}
.sb-form-control {
&.phone {
padding-left: calculateRem(40px);
}
}
}
../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
}