diff --git a/frontend/src/app/components/auth/register/register.component.html b/frontend/src/app/components/auth/register/register.component.html index b077e87..1d894d6 100644 --- a/frontend/src/app/components/auth/register/register.component.html +++ b/frontend/src/app/components/auth/register/register.component.html @@ -10,54 +10,50 @@ To the login } @else { +
-
- @if (!mail.valid && mail.touched) { -

Please enter your email

- } @else { @if (mail.touched && authData.mail.length > 0 && - !isUserEmailValid(authData.mail)) { -

This is not a valid email format

- }} + +
+ @if (form.controls['mail'].touched && form.controls['mail'].invalid) { +
+ @if (form.controls['mail'].errors?.['required']) { +

Please enter your email

+ } @if (form.controls['mail'].errors?.['invalidEmailFormat']) { +

This is not a valid email format

+ } +
+ }
+
-
- @if (!password.valid && password.touched && authData.password.length < - 1) { -

Please enter a password

- } @else { @if (authData.password && authData.password.length < 6 && - password.touched) { -

Password is too short, min 6 characters

- } } + +
+ @if (form.controls['password'].touched && + form.controls['password'].invalid) { +
+ @if (form.controls['password'].errors?.['required']) { +

Please enter a password

+ } @if (form.controls['password'].errors?.['minlength']) { +

Password is too short, min 8 characters

+ } +
+ }
+
-
- @if (authData.password !== authData.passwordConfirm && - passwordConfirm.touched) { -

The passwords do not match

+ +
+ @if ( form.controls['passwordConfirm'].touched && + form.controls['passwordConfirm'].invalid ) { +
+ @if (form.controls['passwordConfirm'].errors?.['required']) { +

Please confirm your password

+ } @if ( form.controls['password'].value !== + form.controls['passwordConfirm'].value && + form.controls['passwordConfirm'].touched ) { +

The passwords do not match

+ } +
}
+
-
+ diff --git a/frontend/src/app/components/auth/register/register.component.ts b/frontend/src/app/components/auth/register/register.component.ts index e3239f4..6fe28a5 100644 --- a/frontend/src/app/components/auth/register/register.component.ts +++ b/frontend/src/app/components/auth/register/register.component.ts @@ -1,34 +1,41 @@ import { Component, OnInit } from '@angular/core'; import { BtnLargeComponent } from '../../../shared/components/buttons/btn-large/btn-large.component'; -import { FormsModule, NgForm } from '@angular/forms'; +import { + FormBuilder, + FormGroup, + FormsModule, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; import { ActivatedRoute, RouterLink } from '@angular/router'; import { CommonModule } from '@angular/common'; import { AuthService } from '../../../services/auth.service'; import { ErrorService } from '../../../services/error.service'; +import { emailFormatValidator } from '../../../validators/email-format.validator'; @Component({ selector: 'app-register', standalone: true, - imports: [CommonModule, BtnLargeComponent, FormsModule, RouterLink], + imports: [ + CommonModule, + BtnLargeComponent, + FormsModule, + ReactiveFormsModule, + RouterLink, + ], templateUrl: './register.component.html', styleUrl: './register.component.scss', }) export class RegisterComponent implements OnInit { registrationSuccess: boolean = false; - - authData = { - mail: '', - password: '', - passwordConfirm: '', - privacyPolicy: false, - send: false, - }; + form: FormGroup = new FormGroup({}); /** - * Initializes the RegisterComponent with ActivatedRoute, AuthService, and ErrorService. + * Initializes the RegisterComponent with ActivatedRoute, FormBuilder, AuthService, and ErrorService. */ constructor( private route: ActivatedRoute, + private fb: FormBuilder, public authService: AuthService, public errorService: ErrorService ) {} @@ -37,68 +44,69 @@ export class RegisterComponent implements OnInit { * Initializes the component by setting up necessary data. */ ngOnInit(): void { + this.createRegisterForm(); this.setEmailFromQueryParams(); } + /** + * Initializes the registration form with required fields and validators. + */ + private createRegisterForm(): void { + this.form = this.fb.group({ + mail: ['', [Validators.required, emailFormatValidator()]], + password: ['', Validators.required], + passwordConfirm: ['', Validators.required], + privacyPolicy: [false, Validators.requiredTrue], + }); + } + /** * Sets the email address from the query parameters in the URL. */ private setEmailFromQueryParams(): void { this.route.queryParams.subscribe((params) => { - this.authData.mail = params['mail'] || ''; + const email = params['mail'] || ''; + this.form.patchValue({ mail: email }); }); } /** - * Validates the given email address. - * Converts to lowercase before checking against the regex. + * Handles the submission of the registration form. * - * @param emailValue The email address to validate. - * @returns True if the email format is valid, false otherwise. + * @returns A Promise that resolves when the registration process is complete. */ - isUserEmailValid(emailValue: string): boolean { - const emailRegex = /^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}$/; - return emailRegex.test(emailValue.toLowerCase()); - } - - /** - * Handles form submission for user registration. - * Sends registration request and handles success/error responses. - * - * @param ngForm The registration form instance. - */ - async onSubmit(ngForm: NgForm): Promise { - if (ngForm.submitted && ngForm.form.valid) { + async onSubmit(): Promise { + if (this.form.valid) { const body = this.createRegistrationRequestBody(); - - this.authData.send = true; + this.form.disable(); try { await this.authService.register(body); - ngForm.resetForm(); + this.form.reset(); this.registrationSuccess = true; this.errorService.clearError(); } catch (error) { - this.authData.send = false; + this.form.enable(); this.errorService.handleError(error); } } } /** - * Creates the request body for the registration API. + * Constructs the registration request payload from form values. * - * @returns The registration request body. + * @returns An object containing the email (lowercased), username (from email), and password. */ private createRegistrationRequestBody(): { email: string; username: string; password: string; } { + const formValue = this.form.value; return { - email: this.authData.mail.toLowerCase(), - username: this.authData.mail.split('@')[0], - password: this.authData.password, + email: formValue.mail.toLowerCase(), + username: formValue.mail.split('@')[0], + password: formValue.password, }; } } diff --git a/frontend/src/app/validators/email-format.validator.ts b/frontend/src/app/validators/email-format.validator.ts new file mode 100644 index 0000000..025ce94 --- /dev/null +++ b/frontend/src/app/validators/email-format.validator.ts @@ -0,0 +1,11 @@ +import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; + +export function emailFormatValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const email = control.value; + const emailRegex = /^[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}$/; + const isValid = emailRegex.test(email?.toLowerCase()); + + return isValid ? null : { invalidEmailFormat: true }; + }; +} diff --git a/frontend/src/assets/style/form.scss b/frontend/src/assets/style/form.scss index 19dcf62..697d863 100644 --- a/frontend/src/assets/style/form.scss +++ b/frontend/src/assets/style/form.scss @@ -47,6 +47,14 @@ form { } } +.error-container { + display: flex; + align-items: center; + justify-content: center; + height: 24px; + padding: 9px; +} + .error-msg { display: flex; align-items: center;