Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(tu-02-56): register form #182

Merged
merged 1 commit into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions src/app/auth/components/register-form/register-form.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<form class="register-form" [formGroup]="registrationForm" (ngSubmit)="submitForm()">
<h2 class="register-title">Sign Up</h2>
<div class="register-inputs-container">
<div class="register-form-item">
<label for="email" class="register-label">Email</label>
<div class="register-field">
<input
id="email"
type="email"
pInputText
formControlName="email"
placeholder="Enter your email"
class="register-input p-inputtext"
/>
@if (registrationForm.get('email')?.invalid && registrationForm.get('email')?.touched) {
@if (registrationForm.get('email')?.errors?.['required']) {
<small class="p-error">Please input your email!</small>
}
@if (registrationForm.get('email')?.errors?.['email']) {
<small class="p-error">Please input a valid email address!</small>
}
}
@if (registrationForm.hasError('invalidUniqueKey')) {
<small class="p-error">Account with this email already exists!</small>
}
@if (registrationForm.hasError('invalidEmail')) {
<small class="p-error">Email is wrong. Please input a valid email address!</small>
}
</div>
</div>
<div class="register-form-item">
<label for="password" class="register-label">Password</label>
<div class="register-field">
<input
id="password"
type="password"
pInputText
formControlName="password"
placeholder="Enter your password"
class="register-input p-inputtext"
/>
@if (registrationForm.get('password')?.invalid && registrationForm.get('password')?.touched) {
@if (registrationForm.get('password')?.errors?.['required']) {
<small class="p-error">Please input your password!</small>
}
@if (registrationForm.get('password')?.errors?.['minlength']) {
<small class="p-error">Password must be at least 8 characters long!</small>
}
}
@if (registrationForm.hasError('invalidPassword')) {
<small class="p-error">Password is wrong. Password must be at least 8 characters long</small>
}
</div>
</div>

<div class="register-form-item">
<label for="confirm" class="register-label">Repeat Password</label>
<div class="register-field">
<input
id="confirm"
type="password"
pInputText
formControlName="confirm"
placeholder="Repeat Password"
class="register-input p-inputtext"
/>
@if (registrationForm.get('confirm')?.invalid && registrationForm.get('confirm')?.touched) {
<small class="p-error">Please confirm your password!</small>
}
</div>
</div>
@if (registrationForm.hasError('passwordMismatch') && registrationForm.get('confirm')?.dirty) {
<small class="p-error">Passwords do not match!</small>
}
@if (registrationForm.hasError('invalidFields')) {
<small class="p-error">Fields are empty. Please input email and password.</small>
}
</div>
<div class="register-button-container">
<p-button
type="submit"
label="Register"
[disabled]="!registrationForm.valid || authService.isSignUpLoading$$()"
class="p-mt-2"
[icon]="authService.isSignUpLoading$$() ? 'pi pi-spin pi-spinner' : 'pi pi-user-plus'"
></p-button>
<p-link pButton [routerLink]="APP_ROUTE.SIGN_IN" label="Sign In" class="p-button-text p-mt-2"></p-link>
</div>
</form>
56 changes: 56 additions & 0 deletions src/app/auth/components/register-form/register-form.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@import 'variables';

:host {
display: contents;
}

.register-form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;

width: $offset-xxxl * 5;
height: auto;
margin: auto;
padding: $offset-ms;

background-color: $gray-100;
box-shadow: $shadow-100;

.register-title {
margin-bottom: $offset-xs;
font-weight: 700;
}

.register-form-item {
height: $offset-xl;
margin-bottom: $offset-xs;

.register-field {
position: relative;
display: flex;
flex-direction: column;
}
}

.register-button-container {
display: flex;
gap: $offset-xs;
margin-top: $offset-s;
}

.p-error,
.register-input {
width: $offset-xl * 5;
}

.p-error {
min-height: $offset-s;
margin-top: $four;
}

.register-inputs-container {
height: $offset-xxxl * 3;
}
}
67 changes: 67 additions & 0 deletions src/app/auth/components/register-form/register-form.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { ChangeDetectionStrategy, Component, inject, OnDestroy } from '@angular/core';
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
import { RouterLink } from '@angular/router';

import { ButtonModule } from 'primeng/button';
import { InputTextModule } from 'primeng/inputtext';
import { PasswordModule } from 'primeng/password';
import { Subscription, take } from 'rxjs';

import { OverriddenHttpErrorResponse } from '@/app/api/models/errorResponse';
import { APP_ROUTE } from '@/app/shared/constants/routes';
import { PASSWORD_MIN_LENGTH } from '@/app/shared/validators/constants/constants';
import { passwordMatchValidator } from '@/app/shared/validators/validators';

import { AuthService } from '../../services/auth-service/auth.service';

@Component({
selector: 'app-register-form',
standalone: true,
imports: [ReactiveFormsModule, InputTextModule, ButtonModule, PasswordModule, RouterLink],
templateUrl: './register-form.component.html',
styleUrl: './register-form.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegisterFormComponent implements OnDestroy {
public authService = inject(AuthService);
private fb = inject(FormBuilder);
private subscription = new Subscription();
public registrationForm = this.fb.nonNullable.group(
{
email: ['', [Validators.required.bind(this), Validators.email.bind(this)]],
password: ['', [Validators.required.bind(this), Validators.minLength(PASSWORD_MIN_LENGTH).bind(this)]],
confirm: ['', [Validators.required.bind(this)]],
},
{
validators: passwordMatchValidator,
},
);
public APP_ROUTE = APP_ROUTE;

public submitForm(): void {
if (this.registrationForm.valid) {
this.authService.isRegistrationSuccess$$.set(null);
this.subscription.add(
this.authService
.registerUser(this.registrationForm.getRawValue())
.pipe(take(1))
.subscribe({
next: () => {
this.authService.handleRegisterSuccess();
},
error: (err: OverriddenHttpErrorResponse) => {
this.authService.handleRegisterError(err);
this.registrationForm.setErrors({ [this.authService.errorMessage$$()]: true });
},
}),
);
} else {
this.registrationForm.markAllAsTouched();
this.registrationForm.updateValueAndValidity();
}
}

public ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
90 changes: 1 addition & 89 deletions src/app/auth/pages/register/register.component.html
Original file line number Diff line number Diff line change
@@ -1,91 +1,3 @@
<section class="register-container">
<form class="register-form" [formGroup]="registrationForm" (ngSubmit)="submitForm()">
<h2 class="register-title">Sign Up</h2>
<div class="register-inputs-container">
<div class="register-form-item">
<label for="email" class="register-label">Email</label>
<div class="register-field">
<input
id="email"
type="email"
pInputText
formControlName="email"
placeholder="Enter your email"
class="register-input p-inputtext"
/>
@if (registrationForm.get('email')?.invalid && registrationForm.get('email')?.touched) {
@if (registrationForm.get('email')?.errors?.['required']) {
<small class="p-error">Please input your email!</small>
}
@if (registrationForm.get('email')?.errors?.['email']) {
<small class="p-error">Please input a valid email address!</small>
}
}
@if (registrationForm.hasError('invalidUniqueKey')) {
<small class="p-error">Account with this email already exists!</small>
}
@if (registrationForm.hasError('invalidEmail')) {
<small class="p-error">Email is wrong. Please input a valid email address!</small>
}
</div>
</div>
<div class="register-form-item">
<label for="password" class="register-label">Password</label>
<div class="register-field">
<input
id="password"
type="password"
pInputText
formControlName="password"
placeholder="Enter your password"
class="register-input p-inputtext"
/>
@if (registrationForm.get('password')?.invalid && registrationForm.get('password')?.touched) {
@if (registrationForm.get('password')?.errors?.['required']) {
<small class="p-error">Please input your password!</small>
}
@if (registrationForm.get('password')?.errors?.['minlength']) {
<small class="p-error">Password must be at least 8 characters long!</small>
}
}
@if (registrationForm.hasError('invalidPassword')) {
<small class="p-error">Password is wrong. Password must be at least 8 characters long</small>
}
</div>
</div>

<div class="register-form-item">
<label for="confirm" class="register-label">Repeat Password</label>
<div class="register-field">
<input
id="confirm"
type="password"
pInputText
formControlName="confirm"
placeholder="Repeat Password"
class="register-input p-inputtext"
/>
@if (registrationForm.get('confirm')?.invalid && registrationForm.get('confirm')?.touched) {
<small class="p-error">Please confirm your password!</small>
}
</div>
</div>
@if (registrationForm.hasError('passwordMismatch') && registrationForm.get('confirm')?.dirty) {
<small class="p-error">Passwords do not match!</small>
}
@if (registrationForm.hasError('invalidFields')) {
<small class="p-error">Fields are empty. Please input email and password.</small>
}
</div>
<div class="register-button-container">
<p-button
type="submit"
label="Register"
[disabled]="!registrationForm.valid || authService.isSignUpLoading$$()"
class="p-mt-2"
[icon]="authService.isSignUpLoading$$() ? 'pi pi-spin pi-spinner' : 'pi pi-user-plus'"
></p-button>
<p-link pButton routerLink="{{ signInPath }}" label="Sign In" class="p-button-text p-mt-2"></p-link>
</div>
</form>
<app-register-form></app-register-form>
</section>
51 changes: 0 additions & 51 deletions src/app/auth/pages/register/register.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,54 +5,3 @@
justify-content: center;
height: calc(100% - $offset-xl);
}

.register-form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;

width: $offset-xxxl * 5;
height: auto;
margin: auto;
padding: $offset-ms;

background-color: $gray-100;
box-shadow: $shadow-100;

.register-title {
margin-bottom: $offset-xs;
font-weight: 700;
}

.register-form-item {
height: $offset-xl;
margin-bottom: $offset-xs;

.register-field {
position: relative;
display: flex;
flex-direction: column;
}
}

.register-button-container {
display: flex;
gap: $offset-xs;
margin-top: $offset-s;
}

.p-error,
.register-input {
width: $offset-xl * 5;
}

.p-error {
min-height: $offset-s;
margin-top: $four;
}

.register-inputs-container {
height: $offset-xxxl * 3;
}
}
Loading
Loading