File

src/app/modules/public/module/sign-in/sso/components/update-contact/update-contact.component.ts

Implements

OnInit AfterViewInit

Metadata

Index

Properties
Methods

Constructor

constructor(activatedRoute: ActivatedRoute, tenantService: TenantService, resourceService: ResourceService, userService: UserService, otpService: OtpService, toasterService: ToasterService, navigationHelperService: NavigationHelperService, orgDetailsService: OrgDetailsService, utilService: UtilService, signupService: SignupService, telemetryService: TelemetryService, tncService: TncService)
Parameters :
Name Type Optional
activatedRoute ActivatedRoute No
tenantService TenantService No
resourceService ResourceService No
userService UserService No
otpService OtpService No
toasterService ToasterService No
navigationHelperService NavigationHelperService No
orgDetailsService OrgDetailsService No
utilService UtilService No
signupService SignupService No
telemetryService TelemetryService No
tncService TncService No

Methods

Private checkUserExist
checkUserExist(captchaResponse?)
Parameters :
Name Optional
captchaResponse Yes
Returns : void
fetchTncConfiguration
fetchTncConfiguration()

Fetches tnc related configuration

Returns : void
Private generateInteractEvent
generateInteractEvent(cData, eData)

Used to generate interact telemetry

Parameters :
Name Optional
cData No
eData No
Returns : void
Private generateOtp
generateOtp()
Returns : void
getQueryParams
getQueryParams(queryObj)
Parameters :
Name Optional
queryObj No
Returns : string
handleFormChangeEvent
handleFormChangeEvent()
Returns : void
Public handleOtpValidationFailed
handleOtpValidationFailed()
Returns : void
Public handleOtpValidationSuccess
handleOtpValidationSuccess()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public onFormUpdate
onFormUpdate(captchaResponse?)
Parameters :
Name Optional
captchaResponse Yes
Returns : void
Private prepareOtpData
prepareOtpData()
Returns : void
resetForm
resetForm(type: string)
Parameters :
Name Type Optional Default value
type string No 'phone'
Returns : void
resetGoogleCaptcha
resetGoogleCaptcha()
Returns : void
resolved
resolved(captchaResponse: string)
Parameters :
Name Type Optional Description
captchaResponse string No
  • reCaptcha token
Returns : void
Private setTenantInfo
setTenantInfo()
Returns : void
showAndHidePopup
showAndHidePopup(mode: boolean)
Parameters :
Name Type Optional
mode boolean No
Returns : void
submitForm
submitForm()
Returns : void
telemetryLogEvents
telemetryLogEvents(api: any, status: boolean)
Parameters :
Name Type Optional
api any No
status boolean No
Returns : void
toggleTncCheckBox
toggleTncCheckBox(e)

Toogles contact form value based on event data

Parameters :
Name Optional Description
e No

event data

Returns : void

Properties

Public activatedRoute
Type : ActivatedRoute
captchaRef
Type : RecaptchaComponent
Decorators :
@ViewChild('captchaRef')
captchaValidationFailed
Default value : false
Private contactDetailsForm
Decorators :
@ViewChild('contactDetailsForm')
Public contactForm
Type : object
Default value : { value: '', type: 'phone', tncAccepted: false }
Public custodianOrgDetails
Public disableSubmitBtn
Default value : true
googleCaptchaSiteKey
Type : string
instance
Type : string
isP1CaptchaEnabled
Type : any
Public isValidIdentifier
Public navigationHelperService
Type : NavigationHelperService
Public otpData
Type : object
Default value : {}
Public otpService
Type : OtpService
Public resourceService
Type : ResourceService
Public showError
Default value : false
Public showMergeConfirmation
Default value : false
Public showOtpComp
Default value : false
showTncPopup
Default value : false
Public signupService
Type : SignupService
Public telemetryImpression
Public telemetryService
Type : TelemetryService
Public tenantInfo
Type : any
Default value : {}
termsAndConditionLink
Type : string
tncLatestVersion
Type : string
Public tncService
Type : TncService
Public toasterService
Type : ToasterService
Public userBlocked
Default value : false
Public userDetails
Type : any
Default value : {}
Public userExist
Default value : false
Public userService
Type : UserService
Public utilService
Type : UtilService
Public validationPattern
Type : object
Default value : { phone: /^[6-9]\d{9}$/, email: /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[a-z]{2,4}$/ }
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { TenantService, UserService, OtpService, OrgDetailsService, TncService } from '@sunbird/core';
import { first, delay } from 'rxjs/operators';
import {
  ResourceService, ToasterService, NavigationHelperService,
  ServerResponse, UtilService
} from '@sunbird/shared';
import * as _ from 'lodash-es';
import {SignupService} from '../../../../signup/services';
import { map } from 'rxjs/operators';
import { combineLatest } from 'rxjs';
import { TelemetryService } from '@sunbird/telemetry';
import { RecaptchaComponent } from 'ng-recaptcha';

@Component({
  templateUrl: './update-contact.component.html',
  styleUrls: ['./update-contact.component.scss']
})
export class UpdateContactComponent implements OnInit, AfterViewInit {
  @ViewChild('contactDetailsForm') private contactDetailsForm;
  @ViewChild('captchaRef') captchaRef: RecaptchaComponent;
  public telemetryImpression;
  public tenantInfo: any = {};
  public showOtpComp = false;
  public showMergeConfirmation = false;
  public userBlocked = false;
  public userExist = false;
  public disableSubmitBtn = true;
  public otpData = {};
  public userDetails: any = {};
  public showError = false;
  public custodianOrgDetails;
  public isValidIdentifier;
  public validationPattern = {
    phone: /^[6-9]\d{9}$/,
    email: /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[a-z]{2,4}$/
  };
  public contactForm = {
    value: '',
    type: 'phone',
    tncAccepted: false
  };
  tncLatestVersion: string;
  termsAndConditionLink: string;
  instance: string;
  showTncPopup = false;
  googleCaptchaSiteKey: string;
  isP1CaptchaEnabled: any;
  captchaValidationFailed = false;


  constructor(public activatedRoute: ActivatedRoute, private tenantService: TenantService, public resourceService: ResourceService,
              public userService: UserService, public otpService: OtpService, public toasterService: ToasterService,
              public navigationHelperService: NavigationHelperService, private orgDetailsService: OrgDetailsService,
              public utilService: UtilService, public signupService: SignupService,
              public telemetryService: TelemetryService, public tncService: TncService) {
  }

  ngOnInit() {
    this.instance = _.upperCase(this.resourceService.instance || 'SUNBIRD');
    this.isP1CaptchaEnabled = (<HTMLInputElement>document.getElementById('p1reCaptchaEnabled'))
      ? (<HTMLInputElement>document.getElementById('p1reCaptchaEnabled')).value : 'true';
    try {
      this.googleCaptchaSiteKey = (<HTMLInputElement>document.getElementById('googleCaptchaSiteKey')).value;
    } catch (error) {
      this.googleCaptchaSiteKey = '';
    }
    this.fetchTncConfiguration();
    this.setTenantInfo();
  }
  ngAfterViewInit () {
    setTimeout(() => {
      this.handleFormChangeEvent();
      this.telemetryImpression = {
        context: {
          env: this.activatedRoute.snapshot.data.telemetry.env,
        },
        edata: {
          type: this.activatedRoute.snapshot.data.telemetry.type,
          pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
          uri: this.activatedRoute.snapshot.data.telemetry.uri,
          duration: this.navigationHelperService.getPageLoadTime()
        }
      };
    });
  }

  /**
   * Toogles contact form value based on event data
   * @param e event data
   */
  toggleTncCheckBox(e) {
    this.contactForm.tncAccepted = e.target.checked;
    const cData = {
      env: 'sso-signup',
      cdata: [
        {id: 'user:tnc:accept', type: 'Feature'},
        {id: 'SB-16663', type: 'Task'}
      ]
    };
    const eData = {
      id: 'user:tnc:accept',
      type: 'click',
      subtype: this.contactForm.tncAccepted ? 'selected' : 'unselected',
      pageid: 'sso-signup'
    };
    this.generateInteractEvent(cData, eData);
  }

  /**
   * Used to generate interact telemetry
   * @param tncAcceptedStatus
   */
  private generateInteractEvent(cData, eData) {
    const interactData = {
      context: cData,
      edata: eData
    };
    this.telemetryService.interact(interactData);
  }

  /**
   * Fetches tnc related configuration
   */
  fetchTncConfiguration() {
    this.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'));
      }
    );
  }

  handleFormChangeEvent() {
    if(this.contactDetailsForm){
      this.contactDetailsForm.valueChanges.pipe(delay(1)).subscribe((data, data2) => {
        if (_.get(this.contactDetailsForm, 'status') === 'VALID' &&
          _.get(this.contactDetailsForm, 'controls.tncAccepted.value')) {
          this.disableSubmitBtn = false;
          this.isValidIdentifier = true;
          this.userExist = false;
          this.userBlocked = false;
        } else {
          this.disableSubmitBtn = true;
          this.isValidIdentifier = _.get(this.contactDetailsForm, 'controls.value.status') === 'VALID'
            && this.validationPattern[this.contactForm.type].test(this.contactForm.value);
          this.userExist = false;
          this.userBlocked = false;
        }
      });
  }
  }
  private checkUserExist(captchaResponse?) {
    const uri = this.contactForm.type + '/' + this.contactForm.value + '?captchaResponse=' + captchaResponse;
    combineLatest(this.userService.getUserByKey(uri), this.orgDetailsService.getCustodianOrgDetails())
    .pipe(map(data => ({
      userDetails: data[0], custOrgDetails: data[1]
    })))
    .subscribe(({userDetails, custOrgDetails}) => {
        this.resetGoogleCaptcha();
        if (_.get(userDetails, 'result.response.rootOrgId') === _.get(custOrgDetails, 'result.response.value')) {
          this.userDetails = userDetails.result.response;
          this.disableSubmitBtn = false;
          this.userExist = false;
          this.userBlocked =  false;
          this.generateOtp();
        } else {
          this.userExist = true;
          this.userBlocked =  false;
          this.disableSubmitBtn = true;
        }
      }, err => {
        this.userDetails = {};
        if (_.get(err, 'error.params.status') && err.error.params.status === 'USER_ACCOUNT_BLOCKED') {
          this.userBlocked =  true;
          this.userExist = false;
          this.disableSubmitBtn = true;
          return;
        }
        if (_.get(err, 'error.params.status') && err.error.params.status === 'I\'m a teapot') {
          this.disableSubmitBtn = true;
          this.captchaValidationFailed = true;
          return;
        }
        this.generateOtp();
        this.disableSubmitBtn = false;
        this.userExist = false;
        this.userBlocked = false;
    });
  }

  public onFormUpdate(captchaResponse?) {
    this.checkUserExist(captchaResponse);
    const cData = {
      env: 'sso-signup',
      cdata: []
    };
    const eData = {
      id: this.contactForm.type === 'email' ? 'submit-email' : 'submit-phone',
      type: 'click',
      pageid: 'sso-sign-in',
    };
    this.generateInteractEvent(cData, eData);
  }

  private generateOtp() {
    const request = {
      request: {
        'key': this.contactForm.value,
        'type': this.contactForm.type
      }
    };
    this.otpService.generateOTP(request).subscribe((data) => {
        this.prepareOtpData();
        this.showOtpComp = true;
      }, (err) => {
        const errorMessage = (err.error.params.status === 'PHONE_ALREADY_IN_USE') || (err.error.params.status === 'EMAIL_IN_USE') ||
          (err.error.params.status === 'ERROR_RATE_LIMIT_EXCEEDED') ? err.error.params.errmsg : this.resourceService.messages.fmsg.m0085;
        this.toasterService.error(errorMessage);
      }
    );
  }
  resetForm(type = 'phone') {
    this.disableSubmitBtn = true;
    this.contactForm = {
      value: '',
      type: type,
      tncAccepted: false
    };
    this.userDetails = {};
    this.userExist = false;
    this.userBlocked = false;
  }
  private prepareOtpData() {
    this.otpData = {
      type: this.contactForm.type,
      value: this.contactForm.value,
      instructions: this.contactForm.type === 'phone' ?
        this.resourceService.frmelmnts.instn.t0083 : this.resourceService.frmelmnts.instn.t0084,
      retryMessage: this.contactForm.type === 'phone' ?
        this.resourceService.frmelmnts.lbl.unableToUpdateMobile : this.resourceService.frmelmnts.lbl.unableToUpdateEmail,
      wrongOtpMessage: this.contactForm.type === 'phone' ? this.resourceService.frmelmnts.lbl.wrongPhoneOTP :
        this.resourceService.frmelmnts.lbl.wrongEmailOTP
    };
  }
  public handleOtpValidationFailed() {
    this.showOtpComp = false;
    this.resetForm();
    setTimeout(() => this.handleFormChangeEvent(), 100);
  }
  getQueryParams(queryObj) {
    return '?' + Object.keys(queryObj).filter(key => queryObj[key])
      .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryObj[key])}`)
      .join('&');
  }
  public handleOtpValidationSuccess() {
    const query: any = {
      type: this.contactForm.type,
      value: this.contactForm.value,
      tncAccepted: this.contactForm.tncAccepted,
      tncVersion: this.tncLatestVersion
    };
    if (!_.isEmpty(this.userDetails)) {
      if (this.userDetails.id) {
        this.showOtpComp = false;
        this.showMergeConfirmation = true;
      }
    } else {
      window.location.href = `/v1/sso/contact/verified` +
        this.getQueryParams({...this.activatedRoute.snapshot.queryParams, ...query});
    }
  }
  private setTenantInfo() {
    this.tenantService.tenantData$.pipe(first()).subscribe(data => {
      if (!data.err) {
        this.tenantInfo = {
          logo: data.tenantData.logo,
          tenantName: data.tenantData.titleName
        };
      }
    });
  }

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

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

  /**
   * @param  {string} captchaResponse - reCaptcha token
   * @description - Callback function for reCaptcha response
   * @since - release-3.1.0
   */
  resolved(captchaResponse: string) {
    if (captchaResponse) {
      this.onFormUpdate(captchaResponse);
    }
  }

  /**
   * @description - Function to reset reCaptcha
   * @since - release-3.1.0
   */
  resetGoogleCaptcha() {
    const element: HTMLElement = document.getElementById('resetGoogleCaptcha') as HTMLElement;
    element && element.click();
  }

  /**
   * @description - Function to be called on form submit
   * @since - release-3.1.0
   */
  submitForm() {
    if (this.isP1CaptchaEnabled === 'true') {
      this.resetGoogleCaptcha();
      this.captchaRef && this.captchaRef.execute();
    } else {
      this.onFormUpdate();
    }
  }
}
<app-modal-wrapper #modal [config]="{disableClose: true, size: 'large', panelClass: ['overflow-visible', 'material-modal']}">
  <ng-template sbModalContent>
    <div class="sb-mat__modal sb-mat__modal--fullscreen">

      <div [appTelemetryImpression]="telemetryImpression" class="signup-background">
        <div class="fullpage-background-image">
          <div class="container-wrapper">

            <div *ngIf="!showOtpComp">
              <div class="d-flex flex-jc-center mb-24">
                <img class="image centered" alt={{tenantInfo.tenantName}} height="45" src="{{tenantInfo.logo}}">
              </div>
              <p class="text-center mb-24">{{resourceService?.frmelmnts?.lbl?.mobileEmailInfoText |
                    interpolate:'{instance}': resourceService.instance}}</p>
              <form class="sb-form borderd" #contactDetailsForm="ngForm">
                <div class="inline fields d-flex flex-w-wrap mb-8" id="Mandatory">
                  <div class="ui radio checkbox mr-16" tabindex="0" (click)="resetForm('phone')">
                    <input type="radio" value="phone" [(ngModel)]="contactForm.type" name='type'>
                    <label for="phoneNumber">{{resourceService?.frmelmnts?.lbl?.phoneNumber}}</label>
                  </div>
                  <div class="ui radio checkbox" tabindex="0" (click)="resetForm('email')">
                    <input type="radio" value="email" [(ngModel)]="contactForm.type" name='type'>
                    <label for="email">{{resourceService?.frmelmnts?.lbl?.email}}</label>
                  </div>
                </div>
                <div *ngIf="contactForm.type === 'phone'" class="ui left icon input d-flex sb-field">
                  <input [(ngModel)]="contactForm.value" name="value"
                    placeholder="{{ resourceService?.frmelmnts?.lbl?.tenDigitPhone }}" class="sb-form-control" required>
                  <!-- pattern="validationPattern.phone" -->
                  <i class=" icon">+91-</i>
                </div>
                <label
                  *ngIf="!userBlocked && !isValidIdentifier && contactForm.type === 'phone' && contactDetailsForm.controls.value && disableSubmitBtn && contactDetailsForm.controls.value.touched"
                  class="sb-color-warning fxsmall mt-8">
                  {{ resourceService.frmelmnts?.lbl?.validPhone}}</label>
                <div *ngIf="contactForm.type === 'email'" class="sb-field">
                  <input [(ngModel)]="contactForm.value" class="sb-form-control" name="value"
                    placeholder="{{ resourceService.frmelmnts?.lbl?.email }}" required>
                  <!-- pattern="validationPattern.email" -->
                </div>
                <label
                  *ngIf="!userBlocked && !isValidIdentifier && contactForm.type === 'email' && contactDetailsForm.controls.value && disableSubmitBtn && contactDetailsForm.controls.value.touched"
                  class="sb-color-warning fxsmall mt-8 pb-0">
                  {{resourceService.frmelmnts?.lbl?.validEmail}}</label>
                <label *ngIf="disableSubmitBtn && userBlocked" class="sb-color-warning fxsmall mt-8">
                  {{resourceService.frmelmnts?.lbl?.blockedUserError}}</label>
                <label *ngIf="disableSubmitBtn && userExist" class="sb-color-warning fxsmall mt-8">
                  {{ contactForm.type === 'phone' ? resourceService.frmelmnts?.lbl?.uniquePhone :
                      resourceService.frmelmnts?.lbl?.uniqueEmail}}</label>
                <label *ngIf="disableSubmitBtn && captchaValidationFailed" class="sb-color-warning fxsmall mt-8">
                  {{resourceService.frmelmnts?.lbl?.captchaValidationFailed}}</label>
                <div class="required sb-checkbox sb-checkbox-primary sb-field mt-16">
                  <input type="checkbox" id="tncAccepted" role="checkbox" [(ngModel)]="contactForm.tncAccepted"
                    (change)="toggleTncCheckBox($event)" name="tncAccepted" class="mr-10 cursor-pointer" required
                    #tncAccepted="ngModel">
                  <label for="tncAccepted" class="fsmall mr-0">{{resourceService?.frmelmnts?.lbl?.tncLabel}}
                    <a class="text-underline fsmall" href="javascript:void(0)" tabindex="0"
                      (click)="showAndHidePopup(true)">
                      {{resourceService?.frmelmnts?.lbl?.tncLabelLink | interpolate:'{instance}': instance}}
                    </a>
                  </label>
                </div>
                <re-captcha *ngIf="isP1CaptchaEnabled === 'true' && googleCaptchaSiteKey" #captchaRef="reCaptcha"
                  (resolved)="$event && resolved($event) && captchaRef.reset()" siteKey="{{googleCaptchaSiteKey}}"
                  size="invisible"></re-captcha>
                <a tabindex="0" (click)="captchaRef.reset()" id="resetGoogleCaptcha"></a>
                <div class="text-center">
                  <button [disabled]="disableSubmitBtn"
                    [ngClass]="{'sb-btn-disabled':disableSubmitBtn, 'sb-btn-primary':!disableSubmitBtn}"
                    class="sb-btn sb-btn-normal mt-24 w-100" tabindex="0"
                    (click)="submitForm()">{{resourceService.frmelmnts?.btn?.submitbtn}}</button>
                </div>
              </form>
            </div>

            <div *ngIf="showOtpComp">
              <app-otp-popup [otpData]="otpData" [redirectToLogin]="true"
                (verificationSuccess)="handleOtpValidationSuccess($event)"
                (redirectToParent)="handleOtpValidationFailed($event)">
              </app-otp-popup>
            </div>
            <div *ngIf="showMergeConfirmation">
              <app-sso-merge-confirmation [userDetails]="userDetails" [identifierType]="contactForm.type"
                [identifierValue]="contactForm.value" [isTncAccepted]="contactForm.tncAccepted"
                [tncVersionAccepted]="tncLatestVersion">
              </app-sso-merge-confirmation>
            </div>
          </div>

        </div>
      </div>
      <app-tnc-popup (close)="showAndHidePopup(false)" [tncUrl]="termsAndConditionLink" #termsAndCondPopUp
        *ngIf="showTncPopup">
      </app-tnc-popup>

    </div>
  </ng-template>
</app-modal-wrapper>

./update-contact.component.scss

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

.ui.raised.shadow.container.segment {
  margin: calculateRem(20px) auto !important;
  padding: 0;
  padding: calculateRem(10px);
  width: calc(100% - 4%) !important;
  min-height: 90vh;
}

@media only screen and (min-width: 1024px) {
  .ui.raised.shadow.container.segment {
    margin: calculateRem(35px) 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);
}
.grey.text {
  color: var(--gray-400);
}
.orange.text {
  color: var(--accessibility-red);
}
.orange-border {
  border-color: var(--accessibility-red) !important;
}
.blue.text {
  color: var(--primary-color);
}
.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[class*="left icon"].input > input {
  padding-left: 3.37142857em !important;
}

.ui.left.icon.input .icon {
  left: calculateRem(2px);
  top: calculateRem(11px);
  font-size: calculateRem(12px);
  font-family: inherit;
}
.opacity-1 {
  opacity: 1 !important;
}

.ui[class*="left icon"].input > input {
  padding-left: calculateRem(32px) !important;
  border: 0.0625rem solid var(--gray-200);
  height: calculateRem(32px);
}

.ui.radio.checkbox input:checked ~ label:before {
  border: calculateRem(2px) solid var(--primary-400);
}
.ui.radio.checkbox input:checked ~ label:after {
  background: var(--primary-400);
}

::ng-deep {

  .signup-background .fullpage-background-image {
    .sb-mat__modal__content, .sb-mat__modal__actions {
      background: inherit;
    }
    .sb-mat__modal__actions {
      border-top: none;
    }
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""