From 48d68d10050115951f05241e929819a6b3f89713 Mon Sep 17 00:00:00 2001
From: Hugo <hugo.cubino@estudiantes.uva.es>
Date: Fri, 22 Nov 2024 15:32:17 +0100
Subject: [PATCH 1/5] =?UTF-8?q?A=C3=B1adidos=20componentes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 angular/RestClient/src/app/app.routes.ts      |   5 +
 .../features/auth/login/login.component.css   | 131 ++++++++++++++++++
 .../features/auth/login/login.component.html  |  23 +++
 .../auth/login/login.component.spec.ts        |  23 +++
 .../features/auth/login/login.component.ts    |  28 ++++
 .../auth/register/register.component.css      | 131 ++++++++++++++++++
 .../auth/register/register.component.html     |  31 +++++
 .../auth/register/register.component.spec.ts  |  23 +++
 .../auth/register/register.component.ts       |  31 +++++
 9 files changed, 426 insertions(+)
 create mode 100644 angular/RestClient/src/app/core/features/auth/login/login.component.css
 create mode 100644 angular/RestClient/src/app/core/features/auth/login/login.component.html
 create mode 100644 angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts
 create mode 100644 angular/RestClient/src/app/core/features/auth/login/login.component.ts
 create mode 100644 angular/RestClient/src/app/core/features/auth/register/register.component.css
 create mode 100644 angular/RestClient/src/app/core/features/auth/register/register.component.html
 create mode 100644 angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts
 create mode 100644 angular/RestClient/src/app/core/features/auth/register/register.component.ts

diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index b8ee77b..dc45a08 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -5,6 +5,7 @@ import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hot
 import { MainPageComponent } from './core/features/user/main-page/main-page.component';
 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';
 
 export const routes: Routes = [
   {
@@ -35,6 +36,10 @@ export const routes: Routes = [
     path: 'hotels/:id',
     component: HotelRegisterComponent,
   },
+  {
+    path: 'auth/login',
+    component: LoginComponent,
+  },
   {
     path: '**',
     redirectTo: '',
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.css b/angular/RestClient/src/app/core/features/auth/login/login.component.css
new file mode 100644
index 0000000..8fdfb8e
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/login/login.component.css
@@ -0,0 +1,131 @@
+/* General container styles */
+.container {
+    max-width: 400px;
+    margin: 50px auto;
+    padding: 30px;
+    background: linear-gradient(135deg, #1e1e2f, #2a2a45);
+    border-radius: 12px;
+    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
+    color: #fff;
+    font-family: 'Roboto', sans-serif;
+  }
+  
+  h2 {
+    text-align: center;
+    font-size: 1.8em;
+    font-weight: bold;
+    margin-bottom: 20px;
+    color: #fff;
+    letter-spacing: 1px;
+    text-transform: uppercase;
+    background: linear-gradient(90deg, #7f7fd5, #86a8e7, #91eae4);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+  }
+  
+  /* Form fields */
+  form div {
+    margin-bottom: 20px;
+  }
+  
+  label {
+    font-size: 0.9em;
+    font-weight: bold;
+    margin-bottom: 8px;
+    display: block;
+    letter-spacing: 0.5px;
+    color: #b3b3d1;
+  }
+  
+  input {
+    width: 100%;
+    padding: 12px 15px;
+    font-size: 0.95em;
+    border: 1px solid #3e3e5e;
+    border-radius: 8px;
+    background: #252540;
+    color: #fff;
+    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
+    transition: all 0.3s ease-in-out;
+  }
+  
+  input:focus {
+    outline: none;
+    border-color: #7f7fd5;
+    background: #2e2e50;
+    box-shadow: 0 0 8px rgba(127, 127, 213, 0.8);
+  }
+  
+  /* Buttons */
+  button {
+    width: 100%;
+    padding: 12px;
+    font-size: 1em;
+    font-weight: bold;
+    color: #fff;
+    background: linear-gradient(90deg, #7f7fd5, #86a8e7, #91eae4);
+    border: none;
+    border-radius: 8px;
+    cursor: pointer;
+    text-transform: uppercase;
+    transition: transform 0.2s, box-shadow 0.2s;
+  }
+  
+  button:hover {
+    transform: translateY(-3px);
+    box-shadow: 0 8px 15px rgba(127, 127, 213, 0.5);
+  }
+  
+  button:disabled {
+    background: #3e3e5e;
+    cursor: not-allowed;
+    opacity: 0.7;
+    box-shadow: none;
+  }
+  
+  /* Small error messages */
+  small {
+    display: block;
+    margin-top: 5px;
+    font-size: 0.85em;
+    color: #ff6b6b;
+  }
+  
+  /* Extra animations and effects */
+  .container::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: linear-gradient(120deg, rgba(127, 127, 213, 0.2), rgba(86, 168, 231, 0.1));
+    z-index: -1;
+    filter: blur(20px);
+  }
+  
+  input::placeholder {
+    color: #b3b3d1;
+  }
+  
+  form div:last-child {
+    margin-top: 30px;
+  }
+  
+  /* Responsiveness */
+  @media (max-width: 768px) {
+    .container {
+      padding: 20px;
+      margin: 20px;
+    }
+  
+    h2 {
+      font-size: 1.5em;
+    }
+  
+    input,
+    button {
+      font-size: 0.9em;
+    }
+  }
+  
\ No newline at end of file
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.html b/angular/RestClient/src/app/core/features/auth/login/login.component.html
new file mode 100644
index 0000000..45790ed
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/login/login.component.html
@@ -0,0 +1,23 @@
+<div class="login-container">
+    <h2>Login</h2>
+    <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
+      <div>
+        <label for="email">Email:</label>
+        <input id="email" type="email" formControlName="email" />
+        <div *ngIf="loginForm.get('email')?.invalid && loginForm.get('email')?.touched">
+          <small>Email is required and must be valid.</small>
+        </div>
+      </div>
+  
+      <div>
+        <label for="password">Password:</label>
+        <input id="password" type="password" formControlName="password" />
+        <div *ngIf="loginForm.get('password')?.invalid && loginForm.get('password')?.touched">
+          <small>Password is required.</small>
+        </div>
+      </div>
+  
+      <button type="submit" [disabled]="loginForm.invalid">Login</button>
+    </form>
+  </div>
+  
diff --git a/angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts b/angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts
new file mode 100644
index 0000000..18f3685
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/login/login.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoginComponent } from './login.component';
+
+describe('LoginComponent', () => {
+  let component: LoginComponent;
+  let fixture: ComponentFixture<LoginComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [LoginComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(LoginComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
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
new file mode 100644
index 0000000..b58031c
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/login/login.component.ts
@@ -0,0 +1,28 @@
+import { Component } from '@angular/core';
+import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
+
+@Component({
+  standalone: true,
+  selector: 'app-login',
+  templateUrl: './login.component.html',
+  styleUrls: ['./login.component.css'],
+  imports: [ReactiveFormsModule]
+})
+export class LoginComponent {
+  loginForm: FormGroup;
+
+  constructor(private fb: FormBuilder) {
+    this.loginForm = this.fb.group({
+      email: ['', [Validators.required, Validators.email]],
+      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
+    }
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.css b/angular/RestClient/src/app/core/features/auth/register/register.component.css
new file mode 100644
index 0000000..8fdfb8e
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/register/register.component.css
@@ -0,0 +1,131 @@
+/* General container styles */
+.container {
+    max-width: 400px;
+    margin: 50px auto;
+    padding: 30px;
+    background: linear-gradient(135deg, #1e1e2f, #2a2a45);
+    border-radius: 12px;
+    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
+    color: #fff;
+    font-family: 'Roboto', sans-serif;
+  }
+  
+  h2 {
+    text-align: center;
+    font-size: 1.8em;
+    font-weight: bold;
+    margin-bottom: 20px;
+    color: #fff;
+    letter-spacing: 1px;
+    text-transform: uppercase;
+    background: linear-gradient(90deg, #7f7fd5, #86a8e7, #91eae4);
+    -webkit-background-clip: text;
+    -webkit-text-fill-color: transparent;
+  }
+  
+  /* Form fields */
+  form div {
+    margin-bottom: 20px;
+  }
+  
+  label {
+    font-size: 0.9em;
+    font-weight: bold;
+    margin-bottom: 8px;
+    display: block;
+    letter-spacing: 0.5px;
+    color: #b3b3d1;
+  }
+  
+  input {
+    width: 100%;
+    padding: 12px 15px;
+    font-size: 0.95em;
+    border: 1px solid #3e3e5e;
+    border-radius: 8px;
+    background: #252540;
+    color: #fff;
+    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
+    transition: all 0.3s ease-in-out;
+  }
+  
+  input:focus {
+    outline: none;
+    border-color: #7f7fd5;
+    background: #2e2e50;
+    box-shadow: 0 0 8px rgba(127, 127, 213, 0.8);
+  }
+  
+  /* Buttons */
+  button {
+    width: 100%;
+    padding: 12px;
+    font-size: 1em;
+    font-weight: bold;
+    color: #fff;
+    background: linear-gradient(90deg, #7f7fd5, #86a8e7, #91eae4);
+    border: none;
+    border-radius: 8px;
+    cursor: pointer;
+    text-transform: uppercase;
+    transition: transform 0.2s, box-shadow 0.2s;
+  }
+  
+  button:hover {
+    transform: translateY(-3px);
+    box-shadow: 0 8px 15px rgba(127, 127, 213, 0.5);
+  }
+  
+  button:disabled {
+    background: #3e3e5e;
+    cursor: not-allowed;
+    opacity: 0.7;
+    box-shadow: none;
+  }
+  
+  /* Small error messages */
+  small {
+    display: block;
+    margin-top: 5px;
+    font-size: 0.85em;
+    color: #ff6b6b;
+  }
+  
+  /* Extra animations and effects */
+  .container::before {
+    content: '';
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: linear-gradient(120deg, rgba(127, 127, 213, 0.2), rgba(86, 168, 231, 0.1));
+    z-index: -1;
+    filter: blur(20px);
+  }
+  
+  input::placeholder {
+    color: #b3b3d1;
+  }
+  
+  form div:last-child {
+    margin-top: 30px;
+  }
+  
+  /* Responsiveness */
+  @media (max-width: 768px) {
+    .container {
+      padding: 20px;
+      margin: 20px;
+    }
+  
+    h2 {
+      font-size: 1.5em;
+    }
+  
+    input,
+    button {
+      font-size: 0.9em;
+    }
+  }
+  
\ No newline at end of file
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
new file mode 100644
index 0000000..8f54cfe
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/register/register.component.html
@@ -0,0 +1,31 @@
+<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>
+      </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>
+        <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>
+  
+      <button type="submit" [disabled]="registerForm.invalid">Register</button>
+    </form>
+  </div>
+  
\ No newline at end of file
diff --git a/angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts b/angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts
new file mode 100644
index 0000000..757b895
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/register/register.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RegisterComponent } from './register.component';
+
+describe('RegisterComponent', () => {
+  let component: RegisterComponent;
+  let fixture: ComponentFixture<RegisterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [RegisterComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(RegisterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
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
new file mode 100644
index 0000000..586790f
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/auth/register/register.component.ts
@@ -0,0 +1,31 @@
+import { Component } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+  selector: 'app-register',
+  templateUrl: './register.component.html',
+  styleUrls: ['./register.component.css']
+})
+export class RegisterComponent {
+  registerForm: FormGroup;
+
+  constructor(private fb: FormBuilder) {
+    this.registerForm = this.fb.group({
+      email: ['', [Validators.required, Validators.email]],
+      password: ['', Validators.required],
+      confirmPassword: ['', Validators.required]
+    });
+  }
+
+  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.');
+      }
+    }
+  }
+}
-- 
GitLab


From 471c0d620e55babdb329c4c0a6ec4b816d6844f7 Mon Sep 17 00:00:00 2001
From: Hugo <hugo.cubino@estudiantes.uva.es>
Date: Fri, 22 Nov 2024 16:17:56 +0100
Subject: [PATCH 2/5] Funciona register

---
 angular/RestClient/src/app/app.routes.ts      |  5 ++
 .../features/auth/login/login.component.ts    | 35 +++++++--
 .../auth/register/register.component.html     | 74 ++++++++++++-------
 .../auth/register/register.component.ts       | 46 +++++++++---
 .../java/com/uva/roomBooking/Models/User.java | 14 +++-
 5 files changed, 129 insertions(+), 45 deletions(-)

diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index dc45a08..cbb0feb 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 b58031c..530355d 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 8f54cfe..0661bf2 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 586790f..4b9f198 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 c5373df..71b8bdf 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;
+  }
 }
-- 
GitLab


From 2cf098312e79339ec89f0065e0f339c9f71d4495 Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Fri, 29 Nov 2024 23:09:34 +0100
Subject: [PATCH 3/5] =?UTF-8?q?Resoluci=C3=B3n=20de=20conflictos?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/uva/authentication/Models/User.java   | 34 +++++++++----------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/java/services/auth/src/main/java/com/uva/authentication/Models/User.java b/java/services/auth/src/main/java/com/uva/authentication/Models/User.java
index eff82ac..9f56935 100644
--- a/java/services/auth/src/main/java/com/uva/authentication/Models/User.java
+++ b/java/services/auth/src/main/java/com/uva/authentication/Models/User.java
@@ -5,47 +5,55 @@ import java.util.List;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
 import jakarta.persistence.Basic;
-import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
 import jakarta.persistence.Entity;
 import jakarta.persistence.EnumType;
 import jakarta.persistence.Enumerated;
-import jakarta.persistence.FetchType;
 import jakarta.persistence.GeneratedValue;
 import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
-import jakarta.persistence.OneToMany;
+import jakarta.persistence.Inheritance;
+import jakarta.persistence.InheritanceType;
 import jakarta.persistence.Table;
 
 @Entity
+@Inheritance(strategy = InheritanceType.JOINED)
 @Table(name = "users")
 public class User {
+
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Basic(optional = false)
+  @Column(nullable = false)
   private int id;
 
   @Basic(optional = false)
+  @Column(nullable = false)
   private String name;
 
   @Basic(optional = false)
+  @Column(nullable = false, unique = true)
   private String email;
 
+  @JsonIgnore
   @Basic(optional = false)
-  @Enumerated(EnumType.STRING)
-  private UserStatus status = UserStatus.NO_BOOKINGS;
-
+  @Column(nullable = false)
   private String password;
 
-
+  @Basic(optional = false)
+  @Column(nullable = false)
+  @Enumerated(EnumType.STRING)
+  private UserRol rol = UserRol.CLIENT;
 
   public User() {
   }
 
-  public User(int id, String name, String email, UserStatus status, String password) {
+  public User(int id, String name, String email, String password, UserRol rol) {
     setId(id);
+    setName(name);
     setEmail(email);
-    setStatus(status);
     setPassword(password);
+    setRol(rol);
   }
 
   public int getId() {
@@ -72,14 +80,6 @@ public class User {
     this.email = email;
   }
 
-  public UserStatus getStatus() {
-    return this.status;
-  }
-
-  public void setStatus(UserStatus status) {
-    this.status = status;
-  }
-
   public String getPassword() {
     return this.password;
   }
-- 
GitLab


From b07374845f950a58b9c700ba2a599fc85c690f33 Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Fri, 29 Nov 2024 23:14:09 +0100
Subject: [PATCH 4/5] Revert "Funciona register"

This reverts commit 471c0d620e55babdb329c4c0a6ec4b816d6844f7.
---
 angular/RestClient/src/app/app.routes.ts      |  5 --
 .../features/auth/login/login.component.ts    | 35 ++-------
 .../auth/register/register.component.html     | 74 +++++++------------
 .../auth/register/register.component.ts       | 46 +++---------
 .../java/com/uva/roomBooking/Models/User.java | 14 +---
 5 files changed, 45 insertions(+), 129 deletions(-)

diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index cbb0feb..dc45a08 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -6,7 +6,6 @@ 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 = [
   {
@@ -41,10 +40,6 @@ 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 530355d..b58031c 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,53 +1,28 @@
 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: [CommonModule, ReactiveFormsModule]
+  imports: [ReactiveFormsModule]
 })
-
-
 export class LoginComponent {
   loginForm: FormGroup;
 
-  constructor(
-    private fb: FormBuilder,
-    private http: HttpClient,
-    private router: Router
-  ) {
+  constructor(private fb: FormBuilder) {
     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;
-
-      // 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);
-        },
-      });
+      console.log('Login data:', { email, password });
+      // Aquí iría el llamado al servicio de login con JWT
     }
   }
-
-  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 0661bf2..8f54cfe 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,51 +1,31 @@
 <div class="register-container">
-  <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>
+    <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>
       </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>
+        <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>
-
-    <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>
+        <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>
-
-    <button type="submit" [disabled]="registerForm.invalid">Registrarse</button>
-    <div *ngIf="errorMessage" class="error-message">
-      {{ errorMessage }}
-    </div>
-  </form>
-</div>
+  
+      <button type="submit" [disabled]="registerForm.invalid">Register</button>
+    </form>
+  </div>
+  
\ No newline at end of file
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 4b9f198..586790f 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,53 +1,31 @@
-import { CommonModule } from '@angular/common';
-import { HttpClient } from '@angular/common/http';
 import { Component } from '@angular/core';
-import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
-import { Router } from '@angular/router';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 
 @Component({
-  standalone: true,
   selector: 'app-register',
   templateUrl: './register.component.html',
-  styleUrls: ['./register.component.css'],
-  imports: [ReactiveFormsModule, CommonModule]
+  styleUrls: ['./register.component.css']
 })
-
 export class RegisterComponent {
   registerForm: FormGroup;
-  errorMessage: string | null = null;
 
-  constructor(
-    private fb: FormBuilder,
-    private http: HttpClient,
-    private router: Router
-  ) {
+  constructor(private fb: FormBuilder) {
     this.registerForm = this.fb.group({
-      name: ['', [Validators.required, Validators.minLength(3)]],
       email: ['', [Validators.required, Validators.email]],
-      password: ['', [Validators.required, Validators.minLength(6)]],
+      password: ['', Validators.required],
+      confirmPassword: ['', Validators.required]
     });
   }
 
   onSubmit() {
     if (this.registerForm.valid) {
-      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.';
-          }
-        }
-        
-      });
+      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.');
+      }
     }
   }
 }
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 71b8bdf..c5373df 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,9 +34,6 @@ 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;
@@ -44,12 +41,11 @@ public class User {
   public User() {
   }
 
-  public User(int id, String name, String email, UserStatus status, List<Booking> bookings, String password) {
+  public User(int id, String name, String email, UserStatus status, List<Booking> bookings) {
     setId(id);
     setEmail(email);
     setStatus(status);
     setBookings(bookings);
-    setPassword(password);
   }
 
   public int getId() {
@@ -91,12 +87,4 @@ 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;
-  }
 }
-- 
GitLab


From f7fc6df0b21021b38ba8443a48fc03ace34fa341 Mon Sep 17 00:00:00 2001
From: migudel <miguel.moras@estudiantes.uva.es>
Date: Fri, 29 Nov 2024 23:19:45 +0100
Subject: [PATCH 5/5] Conflictos II

---
 angular/RestClient/src/app/app.routes.ts      | 107 +++++++++++++++---
 .../authentication/models/remote/User.java    |  95 ++++++++++++++++
 2 files changed, 188 insertions(+), 14 deletions(-)
 create mode 100644 java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java

diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index dc45a08..435147a 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -5,41 +5,120 @@ import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hot
 import { MainPageComponent } from './core/features/user/main-page/main-page.component';
 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 { UserFormComponent } from './core/features/user/user-form/user-form.component';
 
 export const routes: Routes = [
   {
     path: '', // Ruta principal
-    component: MainPageComponent, // Componente de la página principal
+    component: MainPageComponent,
   },
+  // auth
   {
-    path: 'bookings/search',
-    component: BookingListComponent,
+    path: 'login',
+    component: LoginComponent,
   },
   {
-    path: 'bookings/new',
-    component: BookingComponent,
+    path: 'register',
   },
+  // Hoteles
   {
-    path: 'users/:id/bookings',
-    component: UserBookingListComponent,
+    path: 'hotels', // Ruta para la lista de hoteles
   },
   {
-    path: 'hotels',
-    component: HotelListComponent,
+    path: 'hotels/register', // Registrar nuevo hotel
   },
   {
-    path: 'hotels/new',
-    component: HotelRegisterComponent,
+    path: 'hotels/:id', // Hotel concreto
   },
   {
-    path: 'hotels/:id',
-    component: HotelRegisterComponent,
+    path: 'hotels/:id/edit', // Modificar hotel
+  },
+  // Usuario
+  {
+    path: 'me', // Main
+  },
+  {
+    path: 'me/edit', // Main
+  },
+  // Usuario HOTEL admin
+  {
+    path: 'me/hotels',
+  },
+  {
+    path: 'me/hotels/:id',
   },
   {
     path: 'auth/login',
-    component: LoginComponent,
   },
+  {
+    path: 'me/hotels/:id/bookings',
+  },
+  {
+    path: 'me/hotels/:id/rooms',
+  },
+  {
+    path: 'me/hotels/:id/rooms/:id',
+  },
+  {
+    path: 'me/hotels/:id/rooms/:id/bookings',
+  },
+  // Usuario Cliente
+  {
+    path: 'me/bookings',
+  },
+  {
+    path: 'me/bookings/:id',
+  },
+  {
+    path: 'me/bookings/new',
+  },
+  // Administrador
+  {
+    path: 'admin', // Main
+  },
+  {
+    path: 'admin/users', // Main
+  },
+  {
+    path: 'admin/users/:id', // Main
+  },
+
+  // ! OTRO // NO MIRAR
+
+  // {
+  //   path: 'bookings/search',
+  //   component: BookingListComponent,
+  // },
+  // {
+  //   path: 'bookings/new',
+  //   component: BookingComponent,
+  // },
+  // {
+  //   path: 'users/:id/bookings',
+  //   component: UserBookingListComponent,
+  // },
+  // {
+  //   path: 'hotels',
+  //   component: HotelListComponent,
+  // },
+  // {
+  //   path: 'hotels/new',
+  //   component: HotelRegisterComponent,
+  // },
+  // {
+  //   path: 'hotels/:id',
+  //   component: HotelRegisterComponent,
+  // },
+  // {
+  //   path: 'users/:id',
+  //   component: UserFormComponent,
+  // },
+  // {
+  //   path: 'register',
+  //   component: UserFormComponent,
+  // },
   {
     path: '**',
     redirectTo: '',
diff --git a/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
new file mode 100644
index 0000000..a72ecfa
--- /dev/null
+++ b/java/services/auth/src/main/java/com/uva/authentication/models/remote/User.java
@@ -0,0 +1,95 @@
+package com.uva.authentication.models.remote;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Inheritance;
+import jakarta.persistence.InheritanceType;
+import jakarta.persistence.Table;
+
+@Entity
+@Inheritance(strategy = InheritanceType.JOINED)
+@Table(name = "users")
+public class User {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Basic(optional = false)
+  @Column(nullable = false)
+  private int id;
+
+  @Basic(optional = false)
+  @Column(nullable = false)
+  private String name;
+
+  @Basic(optional = false)
+  @Column(nullable = false, unique = true)
+  private String email;
+
+  @JsonIgnore
+  @Basic(optional = false)
+  @Column(nullable = false)
+  private String password;
+
+  @Basic(optional = false)
+  @Column(nullable = false)
+  @Enumerated(EnumType.STRING)
+  private UserRol rol = UserRol.CLIENT;
+
+  public User() {
+  }
+
+  public User(int id, String name, String email, String password, UserRol rol) {
+    setId(id);
+    setName(name);
+    setEmail(email);
+    setRol(rol);
+  }
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getEmail() {
+    return this.email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public String getPassword() {
+    return password;
+  }
+
+  public void setPassword(String rawPassword) {
+    this.password = rawPassword;
+  }
+
+  public UserRol getRol() {
+    return this.rol;
+  }
+
+  public void setRol(UserRol rol) {
+    this.rol = rol;
+  }
+}
-- 
GitLab