Implementation of Better Error Handling on SignUp

This commit is contained in:
2023-08-01 01:22:48 -03:00
parent 0b9b648861
commit 3cca992db3
5 changed files with 185 additions and 89 deletions

View File

@@ -1,6 +1,6 @@
.error-box { .error-box {
background-color: #ff00001a; background-color: #ff00001a;
min-width: 250px; max-width: 320px;
display: flex; display: flex;
border-radius: 5px; border-radius: 5px;
padding: 25px; padding: 25px;

View File

@@ -1,8 +1,8 @@
<app-popup [state]="popupState" <app-popup [state]="state"
(stateChange)="onStateChange($event)" (stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside"> [ignoreClickOutside]="ignoreClickOutside">
<div class="container overflow-hidden" <div class="container m-0 overflow-hidden"
[@resizeContainerForErrorMessage]="hideErrorMessage()"> [@resizeContainerForErrorMessage]="hideErrorMessage()">
<app-error-box [errorMessage]="errorMessage" <app-error-box [errorMessage]="errorMessage"

View File

@@ -3,7 +3,7 @@ import { FormControl, FormGroup, Validators } from '@angular/forms';
import { MatIconRegistry } from '@angular/material/icon'; import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser'; import { DomSanitizer } from '@angular/platform-browser';
import { faLock, faUser } from '@fortawesome/free-solid-svg-icons'; import { faLock, faUser } from '@fortawesome/free-solid-svg-icons';
import {Subscription, timeout} from 'rxjs'; import {Subscription} from 'rxjs';
import { AuthService } from 'src/app/shared/auth/auth.service'; import { AuthService } from 'src/app/shared/auth/auth.service';
import { HttpError } from 'src/app/shared/model/httpError/httpError.model'; import { HttpError } from 'src/app/shared/model/httpError/httpError.model';
import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker'; import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker';
@@ -24,7 +24,7 @@ const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
state('hide', state('hide',
style({ style({
height: '100px', height: '100px',
width: '370px', width: '320px',
}) })
), ),
transition( transition(
@@ -44,7 +44,7 @@ const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
style({ style({
opacity: 1, opacity: 1,
height: '100px', height: '100px',
width: '340px', width: '320px',
}) })
), ),
state('hide', state('hide',
@@ -94,8 +94,6 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
@Output() @Output()
stateChange = new EventEmitter<boolean>(); stateChange = new EventEmitter<boolean>();
popupState = false;
loginForm!: FormGroup; loginForm!: FormGroup;
authSubject!: Subscription; authSubject!: Subscription;
@@ -137,7 +135,6 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
} }
ngAfterViewInit(): void { ngAfterViewInit(): void {
this.popupState = this.state;
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
} }
@@ -175,7 +172,7 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
} }
private closePopup() { private closePopup() {
this.popupState = false; this.state = false;
this.loginForm.reset(); this.loginForm.reset();
} }

View File

@@ -1,73 +1,85 @@
<app-popup [state]="state" <app-popup [state]="state"
(stateChange)="onStateChange($event)" (stateChange)="onStateChange($event)"
[ignoreClickOutside]="ignoreClickOutside"> [ignoreClickOutside]="ignoreClickOutside">
{{errorMessage}}
<div class="container authentication-container">
<div class="row"> <div class="container m-0 overflow-hidden"
<div class="col-lg-6 auth-body auth-body-form"> [@resizeContainerForErrorMessage]="hideErrorMessage()">
<form [formGroup]="signupForm" (ngSubmit)="onSignUp()">
<div class="input-div"> <app-error-box [errorMessage]="errorMessage"
<fa-icon class="input-div-icon" [@showErrorMessage]="showErrorMessage()">
[icon]="_fullnameIcon"> </app-error-box>
</fa-icon>
<input type="text" id="fullname" <div class="container authentication-container"
formControlName="fullname" [@hideAuthContainer]="hideErrorMessage()"
class="form-control" (@hideAuthContainer.done)="hideAuthContainer($event)">
placeholder="Full Name"> <div class="row">
</div> <div class="col-lg-6 auth-body auth-body-form">
<div class="input-div"> <form [formGroup]="signupForm" (ngSubmit)="onSignUp()">
<fa-icon class="input-div-icon" <div class="input-div">
[icon]="_emailIcon"> <fa-icon class="input-div-icon"
</fa-icon> [icon]="_fullnameIcon">
<input type="text" id="email" </fa-icon>
formControlName="email" <input type="text" id="fullname"
class="form-control" formControlName="fullname"
placeholder="Email"> class="form-control"
</div> placeholder="Full Name">
<div class="input-div"> </div>
<fa-icon class="input-div-icon" <div class="input-div">
[icon]="_userIcon"> <fa-icon class="input-div-icon"
</fa-icon> [icon]="_emailIcon">
<input type="text" id="username" </fa-icon>
formControlName="username" <input type="text" id="email"
class="form-control" formControlName="email"
placeholder="Username"> class="form-control"
</div> placeholder="Email">
<div class="input-div"> </div>
<fa-icon class="input-div-icon" <div class="input-div">
[icon]="_passwordIcon"> <fa-icon class="input-div-icon"
</fa-icon> [icon]="_userIcon">
<input type="password" id="password" </fa-icon>
formControlName="password" <input type="text" id="username"
class="form-control" formControlName="username"
placeholder="Password"> class="form-control"
</div> placeholder="Username">
<button class="btn" </div>
type="submit"> <div class="input-div">
SignUp <fa-icon class="input-div-icon"
[icon]="_passwordIcon">
</fa-icon>
<input type="password" id="password"
formControlName="password"
class="form-control"
placeholder="Password">
</div>
<button class="btn"
type="submit">
SignUp
</button>
</form>
</div>
<div class="separator-line">
<div class="line"></div>
</div>
<div class="col-lg-6 auth-body auth-body-links">
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGoogleLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="google-logo"></mat-icon>
Login With Google
</button> </button>
</form> <button mat-button
</div> class="oauth-button d-flex justify-content-center align-items-center"
<div class="separator-line"> (click)="onGithubLogin()">
<div class="line"></div> <mat-icon style="width: 50px; height:30px"
</div> svgIcon="github-logo"></mat-icon>
<div class="col-lg-6 auth-body auth-body-links"> Login With Github
<button mat-button </button>
class="oauth-button d-flex justify-content-center align-items-center" </div>
(click)="onGoogleLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="google-logo"></mat-icon>
Login With Google
</button>
<button mat-button
class="oauth-button d-flex justify-content-center align-items-center"
(click)="onGithubLogin()">
<mat-icon style="width: 50px; height:30px"
svgIcon="github-logo"></mat-icon>
Login With Github
</button>
</div> </div>
</div> </div>
</div> </div>
</app-popup> </app-popup>

View File

@@ -9,6 +9,7 @@ import { HttpError } from 'src/app/shared/model/httpError/httpError.model';
import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker'; import HttpErrorChecker from 'src/app/shared/model/httpError/httpErrorChecker';
import UserChecker from 'src/app/shared/model/user/user.checker'; import UserChecker from 'src/app/shared/model/user/user.checker';
import { User } from 'src/app/shared/model/user/user.model'; import { User } from 'src/app/shared/model/user/user.model';
import {animate, animateChild, group, query, state, style, transition, trigger} from "@angular/animations";
const GOOGLE_LOGO_SVG = "assets/img/providers/google.svg"; const GOOGLE_LOGO_SVG = "assets/img/providers/google.svg";
@@ -17,18 +18,81 @@ const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
@Component({ @Component({
selector: 'app-signup', selector: 'app-signup',
templateUrl: './signup.component.html', templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css'] styleUrls: ['./signup.component.css'],
animations: [
trigger('resizeContainerForErrorMessage', [
state('hide',
style({
height: '100px',
width: '320px',
})
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate('1s ease')
])
)
]),
trigger('showErrorMessage', [
state('show',
style({
opacity: 1,
height: '100px',
width: '320px',
})
),
state('hide',
style({
opacity: 0,
height: '0px',
width: '0px',
})
),
transition(
'* => show',
animate(
'500ms ease-in'
)
),
]),
trigger('hideAuthContainer', [
state('hide',
style({
opacity: 0,
})
),
transition(
'show => hide',
group([
query(
"@*",
animateChild(),
{ optional: true }
),
animate(
'250ms ease-out'
)
])
)
]),
]
}) })
export class SignupComponent implements OnInit { export class SignupComponent implements OnInit {
@Input() @Input()
state: boolean = false; state: boolean = false;
@Input() @Input()
ignoreClickOutside!: HTMLDivElement[]; ignoreClickOutside!: HTMLDivElement[];
@Output() @Output()
stateChange = new EventEmitter<boolean>(); stateChange = new EventEmitter<boolean>();
signupForm!: FormGroup; signupForm!: FormGroup;
@@ -36,6 +100,8 @@ export class SignupComponent implements OnInit {
errorMessage!: string | null; errorMessage!: string | null;
isShowErrorMessage = false;
_fullnameIcon = faFingerprint; _fullnameIcon = faFingerprint;
_emailIcon = faEnvelope; _emailIcon = faEnvelope;
@@ -47,15 +113,15 @@ export class SignupComponent implements OnInit {
constructor(private authService: AuthService, constructor(private authService: AuthService,
private matIconRegistry: MatIconRegistry, private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer) { private domSanitizer: DomSanitizer) {
this.matIconRegistry.addSvgIcon( this.matIconRegistry.addSvgIcon(
"google-logo", "google-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG) this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG)
); );
this.matIconRegistry.addSvgIcon( this.matIconRegistry.addSvgIcon(
"github-logo", "github-logo",
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG) this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG)
); );
} }
ngOnInit(): void { ngOnInit(): void {
this.signupForm = new FormGroup({ this.signupForm = new FormGroup({
@@ -110,5 +176,26 @@ export class SignupComponent implements OnInit {
this.signupForm.reset(); this.signupForm.reset();
} }
public showErrorMessage(): string {
if (this.isShowErrorMessage) {
return "show";
}
return "hide";
}
public hideErrorMessage(): string {
if (!!this.errorMessage) {
return "hide";
}
return "show";
}
hideAuthContainer(event: any) {
if (event.toState === "hide") {
event.element.style.display = "none";
this.isShowErrorMessage = true;
}
}
} }