Skip to content
Snippets Groups Projects
Commit dbcceed9 authored by hugcubi's avatar hugcubi
Browse files

Implementacion de formulario con datos de usuario

parent 39cc475c
No related branches found
No related tags found
2 merge requests!26Revert "Funciona register",!24Implementacion de formulario con datos de usuario
...@@ -5,6 +5,7 @@ import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hot ...@@ -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 { MainPageComponent } from './core/features/user/main-page/main-page.component';
import { BookingListComponent } from './core/features/bookings/booking-list/booking-list.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 { UserBookingListComponent } from './core/features/user/user-booking-list/user-booking-list.component';
import { UserFormComponent} from './core/features/user/user-form/user-form.component';
export const routes: Routes = [ export const routes: Routes = [
{ {
...@@ -35,6 +36,10 @@ export const routes: Routes = [ ...@@ -35,6 +36,10 @@ export const routes: Routes = [
path: 'hotels/:id', path: 'hotels/:id',
component: HotelRegisterComponent, component: HotelRegisterComponent,
}, },
{
path: 'users/:id',
component: UserFormComponent,
},
{ {
path: '**', path: '**',
redirectTo: '', redirectTo: '',
......
.form-container {
width: 100%;
max-width: 500px;
margin: 0 auto;
padding: 20px;
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 8px;
}
h2 {
text-align: center;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}
input {
width: 100%;
padding: 10px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[readonly] {
background-color: #f5f5f5;
cursor: not-allowed;
}
.button-group {
display: flex;
gap: 10px;
justify-content: center;
}
button {
padding: 10px 20px;
font-size: 16px;
border-radius: 4px;
border: none;
cursor: pointer;
}
.btn-primary {
background-color: #007bff;
color: #fff;
}
.btn-secondary {
background-color: #6c757d;
color: #fff;
}
.btn-success {
background-color: #28a745;
color: #fff;
}
\ No newline at end of file
<div class="form-container">
<h2>Perfil de Usuario</h2>
<form [formGroup]="userForm">
<div class="form-group">
<label for="name">Nombre:</label>
<input
id="name"
type="text"
class="form-control"
formControlName="name"
[readonly]="!isEditing"
/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input
id="email"
type="email"
class="form-control"
formControlName="email"
[readonly]="!isEditing"
/>
</div>
<div class="form-group" *ngIf="isEditing">
<label for="currentPassword">Contraseña actual:</label>
<input
id="currentPassword"
type="password"
class="form-control"
formControlName="currentPassword"
placeholder="Introduce tu contraseña actual"
/>
</div>
<div class="form-group" *ngIf="isEditing">
<label for="newPassword">Nueva contraseña:</label>
<input
id="newPassword"
type="password"
class="form-control"
formControlName="newPassword"
placeholder="Introduce tu nueva contraseña"
/>
</div>
<div class="button-group">
<button
*ngIf="!isEditing"
type="button"
class="btn btn-primary"
(click)="toggleEdit()"
>
Editar
</button>
<button
*ngIf="isEditing"
type="button"
class="btn btn-secondary"
(click)="cancelEdit()"
>
Cancelar
</button>
<button
*ngIf="isEditing"
type="submit"
class="btn btn-success"
(click)="saveChanges()"
[disabled]="!userForm.valid"
>
Guardar
</button>
</div>
</form>
</div>
\ No newline at end of file
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpResponse } from '@angular/common/http';
import { UserFormComponent } from './user-form.component';
import { UserClientService } from '../../../../shared/user-client.service';
import { of } from 'rxjs';
describe('UserFormComponent', () => {
let component: UserFormComponent;
let fixture: ComponentFixture<UserFormComponent>;
let userService: UserClientService;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ReactiveFormsModule, FormsModule],
declarations: [UserFormComponent],
providers: [UserClientService],
}).compileComponents();
fixture = TestBed.createComponent(UserFormComponent);
component = fixture.componentInstance;
userService = TestBed.inject(UserClientService);
spyOn(userService, 'getCurrentUser').and.returnValue(
of({
id: 1,
name: 'John Doe',
email: 'johndoe@example.com',
rol: 'CONSUMER',
status: 'WITH_ACTIVE_BOOKINGS',
})
);
spyOn(userService, 'updateUser').and.returnValue(of(new HttpResponse({ body: 'User updated successfully' })));
spyOn(userService, 'updatePassword').and.returnValue(of(new HttpResponse({ body: 'Password updated successfully' })));
fixture.detectChanges();
});
it('should create the component', () => {
expect(component).toBeTruthy();
});
it('should load user data on initialization', () => {
expect(component.userForm.value).toEqual({
name: 'John Doe',
email: 'johndoe@example.com',
password: '',
confirmPassword: '',
});
});
it('should call updateUser when saving valid user data', () => {
component.userForm.patchValue({
name: 'Jane Doe',
email: 'janedoe@example.com',
});
component.saveChanges();
expect(userService.updateUser).toHaveBeenCalledWith({
name: 'Jane Doe',
email: 'janedoe@example.com',
});
});
it('should call updatePassword when password is updated and matches confirmPassword', () => {
component.userForm.patchValue({
password: 'newpassword123',
confirmPassword: 'newpassword123',
});
component.saveChanges();
expect(userService.updatePassword).toHaveBeenCalledWith(
'',
'newpassword123'
);
});
it('should not call updatePassword if password and confirmPassword do not match', () => {
component.userForm.patchValue({
password: 'newpassword123',
confirmPassword: 'differentpassword',
});
component.saveChanges();
expect(userService.updatePassword).not.toHaveBeenCalled();
});
});
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UserClientService } from '../../../../shared/user-client.service';
@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html',
styleUrls: ['./user-form.component.css'],
})
export class UserFormComponent implements OnInit {
userForm!: FormGroup;
isEditing = false;
constructor(private fb: FormBuilder, private userService: UserClientService) {}
ngOnInit(): void {
this.initializeForm();
this.loadUserData();
}
private initializeForm(): void {
this.userForm = this.fb.group({
name: [{ value: '', disabled: true }, Validators.required],
email: [{ value: '', disabled: true }, [Validators.required, Validators.email]],
currentPassword: [''], // Solo habilitado en modo edición
newPassword: [''], // Solo habilitado en modo edición
});
}
private loadUserData(): void {
this.userService.getCurrentUser().subscribe((user) => {
this.userForm.patchValue({
name: user.name,
email: user.email,
});
});
}
toggleEdit(): void {
this.isEditing = true;
this.userForm.get('name')?.enable();
this.userForm.get('email')?.enable();
}
cancelEdit(): void {
this.isEditing = false;
this.loadUserData(); // Volver a cargar los datos originales
this.userForm.get('name')?.disable();
this.userForm.get('email')?.disable();
}
saveChanges(): void {
if (this.userForm.valid) {
const updatedData = this.userForm.value;
this.userService.updateUser(updatedData).subscribe(() => {
this.isEditing = false;
this.loadUserData();
});
}
}
}
...@@ -8,18 +8,22 @@ import { User, UserState } from '../../types'; ...@@ -8,18 +8,22 @@ import { User, UserState } from '../../types';
}) })
export class UserClientService { export class UserClientService {
private readonly URI = environment.userAPI; private readonly URI = environment.userAPI;
constructor(private http: HttpClient) {} constructor(private http: HttpClient) {}
// Obtener un usuario por ID
getUser(userId: number) { getUser(userId: number) {
return this.http.get<User>(`${this.URI}/${userId}`); return this.http.get<User>(`${this.URI}/${userId}`);
} }
// Obtener todos los usuarios
getAllUsers() { getAllUsers() {
return this.http.get<User[]>(this.URI, { return this.http.get<User[]>(this.URI, {
observe: 'body', observe: 'body',
}); });
} }
// Cambiar estado de un usuario
alterUserStatus(userId: number, status: UserState) { alterUserStatus(userId: number, status: UserState) {
return this.http.patch( return this.http.patch(
`${this.URI}/${userId}`, `${this.URI}/${userId}`,
...@@ -32,4 +36,29 @@ export class UserClientService { ...@@ -32,4 +36,29 @@ export class UserClientService {
} }
); );
} }
// Obtener el usuario actual (autenticado)
getCurrentUser() {
return this.http.get<User>(`${this.URI}/me`);
}
// Actualizar los datos del usuario
updateUser(user: Partial<User>) {
return this.http.patch(`${this.URI}/me`, user, {
observe: 'response',
responseType: 'text',
});
}
// Cambiar la contraseña del usuario
updatePassword(currentPassword: string, newPassword: string) {
return this.http.patch(
`${this.URI}/me/password`,
{ currentPassword, newPassword },
{
observe: 'response',
responseType: 'text',
}
);
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment