diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts index dc45a08aa11a13a097f916862e2154cc28aec616..cbb0feb56ebbd90850995dd1c55b028a39483371 100644 --- a/angular/RestClient/src/app/app.routes.ts +++ b/angular/RestClient/src/app/app.routes.ts @@ -6,6 +6,7 @@ import { MainPageComponent } from './core/features/user/main-page/main-page.comp import { BookingListComponent } from './core/features/bookings/booking-list/booking-list.component'; import { UserBookingListComponent } from './core/features/user/user-booking-list/user-booking-list.component'; import { LoginComponent } from './core/features/auth/login/login.component'; +import { RegisterComponent } from './core/features/auth/register/register.component'; export const routes: Routes = [ { @@ -40,6 +41,10 @@ export const routes: Routes = [ path: 'auth/login', component: LoginComponent, }, + { + path: 'auth/register', + component: RegisterComponent, + }, { path: '**', redirectTo: '', diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.ts b/angular/RestClient/src/app/core/features/auth/login/login.component.ts index b58031ce3fef6f2d9c5dc886019d2faec2c5ead8..530355d020060ddf2c4133e0dd9e7c203eeea2aa 100644 --- a/angular/RestClient/src/app/core/features/auth/login/login.component.ts +++ b/angular/RestClient/src/app/core/features/auth/login/login.component.ts @@ -1,28 +1,53 @@ import { Component } from '@angular/core'; import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { HttpClient } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { CommonModule } from '@angular/common'; @Component({ standalone: true, selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'], - imports: [ReactiveFormsModule] + imports: [CommonModule, ReactiveFormsModule] }) + + export class LoginComponent { loginForm: FormGroup; - constructor(private fb: FormBuilder) { + constructor( + private fb: FormBuilder, + private http: HttpClient, + private router: Router + ) { this.loginForm = this.fb.group({ email: ['', [Validators.required, Validators.email]], - password: ['', Validators.required] + password: ['', [Validators.required]], }); } onSubmit() { if (this.loginForm.valid) { const { email, password } = this.loginForm.value; - console.log('Login data:', { email, password }); - // Aquí iría el llamado al servicio de login con JWT + + // Realizar la solicitud al backend + this.http.post('http://localhost:8101', { email, password }).subscribe({ + next: (response: any) => { + // Guardar el token en localStorage + localStorage.setItem('authToken', response.token); + + // Redirigir al dashboard + this.router.navigate(['/']); + }, + error: (err) => { + console.error('Error en el login:', err); + }, + }); } } + + isAuthenticated(): boolean { + return !!localStorage.getItem('authToken'); + } } diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.html b/angular/RestClient/src/app/core/features/auth/register/register.component.html index 8f54cfe88e9dc8c5d3babb878e5ddb0a4165fb4e..0661bf200edfaf1cc9e7751ad15070fbcee9d40c 100644 --- a/angular/RestClient/src/app/core/features/auth/register/register.component.html +++ b/angular/RestClient/src/app/core/features/auth/register/register.component.html @@ -1,31 +1,51 @@ <div class="register-container"> - <h2>Register</h2> - <form [formGroup]="registerForm" (ngSubmit)="onSubmit()"> - <div> - <label for="email">Email:</label> - <input id="email" type="email" formControlName="email" /> - <div *ngIf="registerForm.get('email')?.invalid && registerForm.get('email')?.touched"> - <small>Email is required and must be valid.</small> - </div> + <h2>Regístrate</h2> + <form [formGroup]="registerForm" (ngSubmit)="onSubmit()"> + <div class="form-group"> + <label for="name">Nombre</label> + <input + id="name" + type="text" + formControlName="name" + placeholder="Introduce tu nombre" + required + /> + <div *ngIf="registerForm.get('name')?.invalid && registerForm.get('name')?.touched"> + <small>El nombre es obligatorio y debe tener al menos 3 caracteres.</small> </div> - - <div> - <label for="password">Password:</label> - <input id="password" type="password" formControlName="password" /> - <div *ngIf="registerForm.get('password')?.invalid && registerForm.get('password')?.touched"> - <small>Password is required.</small> - </div> + </div> + + <div class="form-group"> + <label for="email">Correo Electrónico</label> + <input + id="email" + type="email" + formControlName="email" + placeholder="Introduce tu correo" + required + /> + <div *ngIf="registerForm.get('email')?.invalid && registerForm.get('email')?.touched"> + <small>El correo electrónico no es válido.</small> </div> - - <div> - <label for="confirmPassword">Confirm Password:</label> - <input id="confirmPassword" type="password" formControlName="confirmPassword" /> - <div *ngIf="registerForm.get('confirmPassword')?.invalid && registerForm.get('confirmPassword')?.touched"> - <small>Passwords must match.</small> - </div> + </div> + + <div class="form-group"> + <label for="password">Contraseña</label> + <input + id="password" + type="password" + formControlName="password" + placeholder="Introduce tu contraseña" + required + /> + <div *ngIf="registerForm.get('password')?.invalid && registerForm.get('password')?.touched"> + <small>La contraseña debe tener al menos 6 caracteres.</small> </div> - - <button type="submit" [disabled]="registerForm.invalid">Register</button> - </form> - </div> - \ No newline at end of file + </div> + + <button type="submit" [disabled]="registerForm.invalid">Registrarse</button> + <div *ngIf="errorMessage" class="error-message"> + {{ errorMessage }} + </div> + </form> +</div> diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.ts b/angular/RestClient/src/app/core/features/auth/register/register.component.ts index 586790f70598414db832d76e7c05d0851a38076c..4b9f198515b82e12467e43696a06cfc1b4cbdad3 100644 --- a/angular/RestClient/src/app/core/features/auth/register/register.component.ts +++ b/angular/RestClient/src/app/core/features/auth/register/register.component.ts @@ -1,31 +1,53 @@ +import { CommonModule } from '@angular/common'; +import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; -import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; @Component({ + standalone: true, selector: 'app-register', templateUrl: './register.component.html', - styleUrls: ['./register.component.css'] + styleUrls: ['./register.component.css'], + imports: [ReactiveFormsModule, CommonModule] }) + export class RegisterComponent { registerForm: FormGroup; + errorMessage: string | null = null; - constructor(private fb: FormBuilder) { + constructor( + private fb: FormBuilder, + private http: HttpClient, + private router: Router + ) { this.registerForm = this.fb.group({ + name: ['', [Validators.required, Validators.minLength(3)]], email: ['', [Validators.required, Validators.email]], - password: ['', Validators.required], - confirmPassword: ['', Validators.required] + password: ['', [Validators.required, Validators.minLength(6)]], }); } onSubmit() { if (this.registerForm.valid) { - const { email, password, confirmPassword } = this.registerForm.value; - if (password === confirmPassword) { - console.log('Register data:', { email, password }); - // Aquí iría el llamado al servicio de register con JWT - } else { - console.error('Passwords do not match.'); - } + const { name, email, password } = this.registerForm.value; + + // Enviar solicitud al backend + this.http.post('http://localhost:8080/users', { name, email, password }).subscribe({ + next: () => { + alert('Usuario registrado con éxito.'); + this.router.navigate(['/auth/login']); // Redirigir al login + }, + error: (err) => { + if (err.error instanceof ErrorEvent) { + this.errorMessage = `Error: ${err.error.message}`; + } else { + // Si el backend devuelve un objeto de error + this.errorMessage = err.error.message || 'Ocurrió un error al registrar el usuario.'; + } + } + + }); } } } diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java index c5373df6edc5e936d9c94f794ae36d3289d173d5..71b8bdf0bf12686b914f67f1fe9db0011e52d699 100644 --- a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java +++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java @@ -34,6 +34,9 @@ public class User { @Enumerated(EnumType.STRING) private UserStatus status = UserStatus.NO_BOOKINGS; + @Basic(optional = false) + private String password; + @JsonIgnore @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List<Booking> bookings; @@ -41,11 +44,12 @@ public class User { public User() { } - public User(int id, String name, String email, UserStatus status, List<Booking> bookings) { + public User(int id, String name, String email, UserStatus status, List<Booking> bookings, String password) { setId(id); setEmail(email); setStatus(status); setBookings(bookings); + setPassword(password); } public int getId() { @@ -87,4 +91,12 @@ public class User { public void setBookings(List<Booking> bookings) { this.bookings = bookings; } + + public String getPassword() { + return this.password; + } + + public void setPassword(String password) { + this.password = password; + } }