hosting-frontend/src/app/components/login/login.component.ts
Alexis Bruneteau ae2b3b106a waouh
2025-05-31 02:43:51 +02:00

191 lines
5.2 KiB
TypeScript

import {Component, OnInit, OnDestroy} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {Router, ActivatedRoute} from '@angular/router';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import {ApiService, LoginCredentials} from '../../services/api';
import {NgClass} from '@angular/common';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
imports: [
ReactiveFormsModule,
NgClass
],
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit, OnDestroy {
loginForm: FormGroup;
loading = false;
error = '';
success = '';
showPassword = false;
returnUrl = '';
private destroy$ = new Subject<void>();
constructor(
private formBuilder: FormBuilder,
private apiService: ApiService,
private router: Router,
private route: ActivatedRoute
) {
// Redirect to dashboard if already logged in
if (this.apiService.isAuthenticated) {
this.router.navigate(['/dashboard']);
}
this.loginForm = this.formBuilder.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
rememberMe: [false]
});
}
ngOnInit(): void {
// Get return url from route parameters or default to dashboard
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/dashboard';
// Clear any existing error messages
this.clearMessages();
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
// Getter for easy access to form fields
get f() {
return this.loginForm.controls;
}
// Get specific field error message
getFieldError(fieldName: string): string {
const field = this.loginForm.get(fieldName);
if (field?.errors && field.touched) {
if (field.errors['required']) {
return `${this.capitalizeFirst(fieldName)} is required`;
}
if (field.errors['email']) {
return 'Please enter a valid email address';
}
if (field.errors['minlength']) {
return `${this.capitalizeFirst(fieldName)} must be at least ${field.errors['minlength'].requiredLength} characters`;
}
}
return '';
}
// Check if field has error
hasFieldError(fieldName: string): boolean {
const field = this.loginForm.get(fieldName);
return !!(field?.errors && field.touched);
}
// Capitalize first letter
private capitalizeFirst(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
// Toggle password visibility
togglePasswordVisibility(): void {
this.showPassword = !this.showPassword;
}
// Clear error and success messages
clearMessages(): void {
this.error = '';
this.success = '';
}
// Handle form submission
onSubmit(): void {
this.clearMessages();
// Mark all fields as touched to show validation errors
this.loginForm.markAllAsTouched();
if (this.loginForm.invalid) {
return;
}
this.loading = true;
const credentials: LoginCredentials = {
email: this.f['email'].value,
password: this.f['password'].value
};
this.apiService.login(credentials)
.pipe(takeUntil(this.destroy$))
.subscribe({
next: (response) => {
this.loading = false;
if (response.success) {
this.success = 'Login successful! Redirecting...';
// Store remember me preference if needed
if (this.f['rememberMe'].value) {
localStorage.setItem('rememberMe', 'true');
}
// Redirect after a short delay to show success message
setTimeout(() => {
this.router.navigate([this.returnUrl]);
}, 1000);
} else {
this.error = response.message || 'Login failed. Please try again.';
}
},
error: (error) => {
this.loading = false;
// Handle specific error cases
if (error.status === 422 && error.error?.errors) {
// Validation errors from server
const serverErrors = error.error.errors;
let errorMessages: string[] = [];
Object.keys(serverErrors).forEach(key => {
if (Array.isArray(serverErrors[key])) {
errorMessages = errorMessages.concat(serverErrors[key]);
}
});
this.error = errorMessages.join(', ');
} else if (error.status === 401) {
this.error = 'Invalid email or password. Please try again.';
} else {
this.error = error.userMessage || 'An error occurred. Please try again.';
}
console.error('Login error:', error);
}
});
}
// Navigate to register page
goToRegister(): void {
this.router.navigate(['/register'], {
queryParams: {returnUrl: this.returnUrl}
});
}
// Navigate to forgot password page
goToForgotPassword(): void {
this.router.navigate(['/forgot-password']);
}
// Demo login (optional - for testing)
demoLogin(): void {
this.loginForm.patchValue({
email: 'demo@example.com',
password: 'password123'
});
}
}