File

feature-libs/user/profile/components/register/register.component.ts

Implements

OnInit OnDestroy

Metadata

selector cx-register
templateUrl ./register.component.html

Index

Properties
Methods

Constructor

constructor(userRegister: UserRegisterFacade, globalMessageService: GlobalMessageService, fb: FormBuilder, router: RoutingService, anonymousConsentsService: AnonymousConsentsService, anonymousConsentsConfig: AnonymousConsentsConfig, authConfigService: AuthConfigService)
Parameters :
Name Type Optional
userRegister UserRegisterFacade No
globalMessageService GlobalMessageService No
fb FormBuilder No
router RoutingService No
anonymousConsentsService AnonymousConsentsService No
anonymousConsentsConfig AnonymousConsentsConfig No
authConfigService AuthConfigService No

Methods

collectDataFromRegisterForm
collectDataFromRegisterForm(formData: any)
Parameters :
Name Type Optional
formData any No
Returns : UserSignUp
isConsentGiven
isConsentGiven(consent: AnonymousConsent)
Parameters :
Name Type Optional
consent AnonymousConsent No
Returns : boolean
Private isConsentRequired
isConsentRequired()
Returns : boolean
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Private onRegisterUserSuccess
onRegisterUserSuccess()
Returns : void
registerUser
registerUser()
Returns : void
submitForm
submitForm()
Returns : void
titleSelected
titleSelected(title: Title)
Parameters :
Name Type Optional
title Title No
Returns : void
toggleAnonymousConsent
toggleAnonymousConsent()
Returns : void

Properties

anonymousConsent$
Type : Observable<literal type>
isLoading$
Default value : new BehaviorSubject(false)
registerForm
Type : FormGroup
Default value : this.fb.group( { titleCode: [''], firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.required, CustomFormValidators.emailValidator]], password: [ '', [Validators.required, CustomFormValidators.passwordValidator], ], passwordconf: ['', Validators.required], newsletter: new FormControl({ value: false, disabled: this.isConsentRequired(), }), termsandconditions: [false, Validators.requiredTrue], }, { validators: CustomFormValidators.passwordsMustMatch( 'password', 'passwordconf' ), } )
Private subscription
Default value : new Subscription()
titles$
Type : Observable<Title[]>
import { Component, OnDestroy, OnInit } from '@angular/core';
import {
  FormBuilder,
  FormControl,
  FormGroup,
  Validators,
} from '@angular/forms';
import {
  AnonymousConsent,
  AnonymousConsentsConfig,
  AnonymousConsentsService,
  AuthConfigService,
  ConsentTemplate,
  GlobalMessageEntities,
  GlobalMessageService,
  GlobalMessageType,
  OAuthFlow,
  RoutingService,
} from '@spartacus/core';
import { CustomFormValidators, sortTitles } from '@spartacus/storefront';
import {
  Title,
  UserRegisterFacade,
  UserSignUp,
} from '@spartacus/user/profile/root';
import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators';

@Component({
  selector: 'cx-register',
  templateUrl: './register.component.html',
})
export class RegisterComponent implements OnInit, OnDestroy {
  titles$: Observable<Title[]>;

  isLoading$ = new BehaviorSubject(false);

  private subscription = new Subscription();

  anonymousConsent$: Observable<{
    consent: AnonymousConsent;
    template: string;
  }>;

  registerForm: FormGroup = this.fb.group(
    {
      titleCode: [''],
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      email: ['', [Validators.required, CustomFormValidators.emailValidator]],
      password: [
        '',
        [Validators.required, CustomFormValidators.passwordValidator],
      ],
      passwordconf: ['', Validators.required],
      newsletter: new FormControl({
        value: false,
        disabled: this.isConsentRequired(),
      }),
      termsandconditions: [false, Validators.requiredTrue],
    },
    {
      validators: CustomFormValidators.passwordsMustMatch(
        'password',
        'passwordconf'
      ),
    }
  );

  constructor(
    protected userRegister: UserRegisterFacade,
    protected globalMessageService: GlobalMessageService,
    protected fb: FormBuilder,
    protected router: RoutingService,
    protected anonymousConsentsService: AnonymousConsentsService,
    protected anonymousConsentsConfig: AnonymousConsentsConfig,
    protected authConfigService: AuthConfigService
  ) {}

  ngOnInit() {
    this.titles$ = this.userRegister.getTitles().pipe(
      map((titles: Title[]) => {
        return titles.sort(sortTitles);
      })
    );

    // TODO: Workaround: allow server for decide is titleCode mandatory (if yes, provide personalized message)
    this.subscription.add(
      this.globalMessageService
        .get()
        .pipe(filter((messages) => !!Object.keys(messages).length))
        .subscribe((globalMessageEntities: GlobalMessageEntities) => {
          const messages =
            globalMessageEntities &&
            globalMessageEntities[GlobalMessageType.MSG_TYPE_ERROR];

          if (
            messages &&
            messages.some((message) => message === 'This field is required.')
          ) {
            this.globalMessageService.remove(GlobalMessageType.MSG_TYPE_ERROR);
            this.globalMessageService.add(
              { key: 'register.titleRequired' },
              GlobalMessageType.MSG_TYPE_ERROR
            );
          }
        })
    );

    const registerConsent =
      this.anonymousConsentsConfig?.anonymousConsents?.registerConsent ?? '';

    this.anonymousConsent$ = combineLatest([
      this.anonymousConsentsService.getConsent(registerConsent),
      this.anonymousConsentsService.getTemplate(registerConsent),
    ]).pipe(
      map(([consent, template]: [AnonymousConsent, ConsentTemplate]) => {
        return {
          consent,
          template: template?.description ? template.description : '',
        };
      })
    );

    this.subscription.add(
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      this.registerForm.get('newsletter')!.valueChanges.subscribe(() => {
        this.toggleAnonymousConsent();
      })
    );
  }

  submitForm(): void {
    if (this.registerForm.valid) {
      this.registerUser();
    } else {
      this.registerForm.markAllAsTouched();
    }
  }

  registerUser(): void {
    this.isLoading$.next(true);
    this.userRegister
      .register(this.collectDataFromRegisterForm(this.registerForm.value))
      .subscribe({
        next: () => this.onRegisterUserSuccess(),
        complete: () => this.isLoading$.next(false),
      });
  }

  titleSelected(title: Title): void {
    this.registerForm['controls'].titleCode.setValue(title.code);
  }

  collectDataFromRegisterForm(formData: any): UserSignUp {
    const { firstName, lastName, email, password, titleCode } = formData;

    return {
      firstName,
      lastName,
      uid: email.toLowerCase(),
      password,
      titleCode,
    };
  }

  isConsentGiven(consent: AnonymousConsent): boolean {
    return this.anonymousConsentsService.isConsentGiven(consent);
  }

  private isConsentRequired(): boolean {
    const requiredConsents =
      this.anonymousConsentsConfig?.anonymousConsents?.requiredConsents;
    const registerConsent =
      this.anonymousConsentsConfig?.anonymousConsents?.registerConsent;

    if (requiredConsents && registerConsent) {
      return requiredConsents.includes(registerConsent);
    }

    return false;
  }

  private onRegisterUserSuccess(): void {
    if (
      this.authConfigService.getOAuthFlow() ===
      OAuthFlow.ResourceOwnerPasswordFlow
    ) {
      this.router.go('login');
    }
    this.globalMessageService.add(
      { key: 'register.postRegisterMessage' },
      GlobalMessageType.MSG_TYPE_CONFIRMATION
    );
  }

  toggleAnonymousConsent(): void {
    const registerConsent =
      this.anonymousConsentsConfig?.anonymousConsents?.registerConsent;

    if (registerConsent) {
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      if (Boolean(this.registerForm.get('newsletter')!.value)) {
        this.anonymousConsentsService.giveConsent(registerConsent);
      } else {
        this.anonymousConsentsService.withdrawConsent(registerConsent);
      }
    }
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}
<section
  class="cx-page-section container"
  *ngIf="!(isLoading$ | async); else loading"
>
  <div class="row justify-content-center">
    <div class="col-md-6">
      <div class="cx-section">
        <form (ngSubmit)="submitForm()" [formGroup]="registerForm">
          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.title' | cxTranslate
              }}</span>
              <select formControlName="titleCode" class="form-control">
                <option selected value="" disabled>
                  {{ 'register.selectTitle' | cxTranslate }}
                </option>
                <option
                  *ngFor="let title of titles$ | async"
                  [value]="title.code"
                >
                  {{ title.name }}
                </option>
              </select>
            </label>
          </div>

          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.firstName.label' | cxTranslate
              }}</span>
              <input
                aria-required="true"
                class="form-control"
                type="text"
                name="firstname"
                placeholder="{{
                  'register.firstName.placeholder' | cxTranslate
                }}"
                formControlName="firstName"
              />
              <cx-form-errors
                aria-live="assertive"
                aria-atomic="true"
                [control]="registerForm.get('firstName')"
              ></cx-form-errors>
            </label>
          </div>

          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.lastName.label' | cxTranslate
              }}</span>
              <input
                aria-required="true"
                class="form-control"
                type="text"
                name="lastname"
                placeholder="{{
                  'register.lastName.placeholder' | cxTranslate
                }}"
                formControlName="lastName"
              />
              <cx-form-errors
                aria-live="assertive"
                aria-atomic="true"
                [control]="registerForm.get('lastName')"
              ></cx-form-errors>
            </label>
          </div>

          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.emailAddress.label' | cxTranslate
              }}</span>
              <input
                aria-required="true"
                class="form-control"
                type="email"
                name="email"
                placeholder="{{
                  'register.emailAddress.placeholder' | cxTranslate
                }}"
                formControlName="email"
              />
              <cx-form-errors
                aria-live="assertive"
                aria-atomic="true"
                [control]="registerForm.get('email')"
              ></cx-form-errors>
            </label>
          </div>

          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.password.label' | cxTranslate
              }}</span>
              <input
                aria-required="true"
                class="form-control"
                type="password"
                name="password"
                placeholder="{{
                  'register.password.placeholder' | cxTranslate
                }}"
                formControlName="password"
              />
              <cx-form-errors
                aria-live="assertive"
                aria-atomic="true"
                [control]="registerForm.get('password')"
              ></cx-form-errors>
            </label>
          </div>

          <div class="form-group">
            <label>
              <span class="label-content">{{
                'register.confirmPassword.label' | cxTranslate
              }}</span>
              <input
                aria-required="true"
                class="form-control"
                type="password"
                name="confirmpassword"
                placeholder="{{
                  'register.confirmPassword.placeholder' | cxTranslate
                }}"
                formControlName="passwordconf"
              />
              <cx-form-errors
                aria-live="assertive"
                aria-atomic="true"
                [control]="registerForm.get('passwordconf')"
              ></cx-form-errors>
            </label>
          </div>

          <div class="form-group">
            <div class="form-check">
              <label *ngIf="anonymousConsent$ | async as anonymousConsent">
                <input
                  type="checkbox"
                  name="newsletter"
                  class="form-check-input"
                  formControlName="newsletter"
                  [checked]="isConsentGiven(anonymousConsent.consent)"
                />
                <span class="form-check-label">
                  {{ anonymousConsent.template }}
                </span>
              </label>
            </div>
          </div>

          <div class="form-group">
            <div class="form-check">
              <label>
                <input
                  aria-required="true"
                  type="checkbox"
                  name="termsandconditions"
                  formControlName="termsandconditions"
                />
                <span class="form-check-label">
                  {{ 'register.confirmThatRead' | cxTranslate }}
                  <a
                    [routerLink]="{ cxRoute: 'termsAndConditions' } | cxUrl"
                    target="_blank"
                  >
                    {{ 'register.termsAndConditions' | cxTranslate }}
                  </a>
                </span>
                <cx-form-errors
                  aria-live="assertive"
                  aria-atomic="true"
                  [control]="registerForm.get('termsandconditions')"
                ></cx-form-errors>
              </label>
            </div>
          </div>
          <button type="submit" class="btn btn-block btn-primary">
            {{ 'register.register' | cxTranslate }}
          </button>
          <a
            class="cx-login-link btn-link"
            [routerLink]="{ cxRoute: 'login' } | cxUrl"
            >{{ 'register.signIn' | cxTranslate }}</a
          >
        </form>
      </div>
    </div>
  </div>
</section>

<ng-template #loading>
  <div class="cx-spinner"><cx-spinner></cx-spinner></div>
</ng-template>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""