diff --git a/angular/RestClient/src/app/app.config.ts b/angular/RestClient/src/app/app.config.ts index 4f22ef91221d03c2345431c665993b2683b2c7e5..491a97d6bdb3318413cf9f4e02f91c951b5ca926 100644 --- a/angular/RestClient/src/app/app.config.ts +++ b/angular/RestClient/src/app/app.config.ts @@ -1,16 +1,14 @@ -import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; +import { ApplicationConfig } from '@angular/core'; import { provideRouter } from '@angular/router'; - import { routes } from './app.routes'; -import { provideClientHydration } from '@angular/platform-browser'; import { provideHttpClient, withFetch } from '@angular/common/http'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; - +import { FormsModule } from '@angular/forms'; +import { CommonEngine } from '@angular/ssr'; export const appConfig: ApplicationConfig = { providers: [ - provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), - provideClientHydration(), - provideHttpClient(withFetch()), provideAnimationsAsync(), + provideHttpClient(withFetch()), + provideAnimationsAsync(), ], }; diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts index 1a20159cf83a05e3b4a62a42943c37b05bc09297..449996bbe2ba3359c9b465966cd721bf1acef7e7 100644 --- a/angular/RestClient/src/app/app.routes.ts +++ b/angular/RestClient/src/app/app.routes.ts @@ -1,14 +1,14 @@ import { Routes } from '@angular/router'; -import { HotelListComponent } from './hotel-list/hotel-list.component'; +import { MainPageComponent } from './main-page/main-page.component'; // Asegúrate de que la ruta al componente principal sea correcta export const routes: Routes = [ { - path: 'hotels', - component: HotelListComponent, + path: '', // Ruta principal + component: MainPageComponent, // Componente de la página principal }, { - path: '**', - redirectTo: 'hotels', + path: '**', // Redirección para rutas no encontradas + redirectTo: '', // Redirige a la página principal pathMatch: 'full', }, ]; diff --git a/angular/RestClient/src/app/main-page/main-page.component.css b/angular/RestClient/src/app/main-page/main-page.component.css new file mode 100644 index 0000000000000000000000000000000000000000..6644155f3d26cebd90db044b5019ca17b5665437 --- /dev/null +++ b/angular/RestClient/src/app/main-page/main-page.component.css @@ -0,0 +1,105 @@ +/* Fondo oscuro de la aplicación para un aspecto futurista */ +body { + background-color: #121212; + color: #e0e0e0; + font-family: 'Roboto', sans-serif; +} + +/* Contenedor principal con esquinas redondeadas y sombra sutil */ +.user-container { + max-width: 600px; + margin: 30px auto; + padding: 25px; + background-color: #1f1f1f; + border-radius: 12px; + box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.6); +} + +/* Título centralizado y con un estilo moderno */ +h1 { + text-align: center; + font-size: 2em; + margin-bottom: 25px; + color: #ffffff; + letter-spacing: 1px; +} + +/* Contenedor de filtro centrado y limpio */ +.filter-container { + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; +} + +label { + font-weight: 600; + margin-right: 10px; + color: #a1a1a1; +} + +/* Select estilizado con borde suave y sombras */ +select { + padding: 10px; + font-size: 1em; + border: none; + outline: none; + background-color: #292929; + color: #e0e0e0; + border-radius: 6px; + box-shadow: inset 0px 3px 8px rgba(0, 0, 0, 0.5); + transition: all 0.3s ease; +} + +select:hover { + background-color: #3a3a3a; +} + +/* Lista de usuarios sin puntos y con bordes modernos */ +.user-list { + list-style-type: none; + padding: 0; + margin: 0; +} + +/* Elementos de la lista con espaciado y efecto hover futurista */ +.user-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 15px 20px; + margin-bottom: 8px; + background-color: #2c2c2c; + border-radius: 8px; + transition: transform 0.3s ease, background-color 0.3s ease; + cursor: pointer; +} + +.user-item:hover { + background-color: #333333; + transform: translateY(-2px); + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.3); +} + +/* Estilos de usuario con tipografía clara y futurista */ +.user-name { + flex: 1; + font-weight: 700; + color: #ffffff; +} + +.user-email { + flex: 2; + color: #b0b0b0; + font-style: italic; + text-align: left; + padding-left: 15px; +} + +.user-status { + flex: 1; + font-weight: 500; + color: #76c7c0; + text-transform: uppercase; + text-align: right; +} diff --git a/angular/RestClient/src/app/main-page/main-page.component.html b/angular/RestClient/src/app/main-page/main-page.component.html new file mode 100644 index 0000000000000000000000000000000000000000..35ecb3160c1f96b219142bfb1a673dae651b2679 --- /dev/null +++ b/angular/RestClient/src/app/main-page/main-page.component.html @@ -0,0 +1,21 @@ +<div class="user-container"> + <h1>Listado de Usuarios</h1> + + <div class="filter-container"> + <label for="filter">Filtrar por estado:</label> + <select id="filter" [(ngModel)]="selectedStatus" (change)="filterUsers()"> + <option value="all">Todos</option> + <option value="NO_BOOKINGS">Sin reservas</option> + <option value="WITH_ACTIVE_BOOKINGS">Con reservas activas</option> + <option value="WITH_INACTIVE_BOOKING">Con reservas inactivas</option> + </select> + </div> + + <ul class="user-list"> + <li *ngFor="let user of filteredUsers" class="user-item"> + <span class="user-name">{{ user.name }}</span> + <span class="user-email">{{ user.email }}</span> + <span class="user-status">{{ user.status }}</span> + </li> + </ul> +</div> diff --git a/angular/RestClient/src/app/main-page/main-page.component.spec.ts b/angular/RestClient/src/app/main-page/main-page.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..40d589a21205dbd8b271cf4f441e0dfd44ed37ca --- /dev/null +++ b/angular/RestClient/src/app/main-page/main-page.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MainPageComponent } from './main-page.component'; + +describe('MainPageComponent', () => { + let component: MainPageComponent; + let fixture: ComponentFixture<MainPageComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MainPageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(MainPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular/RestClient/src/app/main-page/main-page.component.ts b/angular/RestClient/src/app/main-page/main-page.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e3433973302fce7f5e7a613ee607b593d7ad776 --- /dev/null +++ b/angular/RestClient/src/app/main-page/main-page.component.ts @@ -0,0 +1,37 @@ +// main-page.component.ts +import { Component, OnInit } from '@angular/core'; +import { ClienteApiRestService } from '../shared/cliente-api-rest.service'; +import { User } from '../../types'; +import { FormsModule } from '@angular/forms'; +import { CommonModule } from '@angular/common'; +import users from '../../mocks/users.json'; +@Component({ + standalone: true, + imports: [FormsModule, CommonModule], + selector: 'app-main-page', + templateUrl: './main-page.component.html', + styleUrls: ['./main-page.component.css'] +}) +export class MainPageComponent implements OnInit { + users: User[] = []; + filteredUsers: User[] = []; + selectedStatus: string = 'all'; + + constructor(private ClienteApiRestService: ClienteApiRestService) {} + + ngOnInit(): void { + this.users = (users as unknown as User[]); + this.ClienteApiRestService.getAllUsers().subscribe((data: User[]) => { + this.users = data; + this.filteredUsers = data; // Inicialmente, muestra todos los usuarios + }); + } + + filterUsers(): void { + if (this.selectedStatus === 'all') { + this.filteredUsers = this.users; + } else { + this.filteredUsers = this.users.filter(user => user.status === this.selectedStatus); + } + } +} diff --git a/angular/RestClient/src/app/shared/cliente-api-rest.service.ts b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts index 1def3e16d28352b9458248b2045a68229d052f57..d44aaa92b955682c20fab81fd38fe560e789dc66 100644 --- a/angular/RestClient/src/app/shared/cliente-api-rest.service.ts +++ b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts @@ -3,6 +3,8 @@ import { Injectable } from '@angular/core'; import hotels from '../../mocks/hotels.json'; import { Hotel } from '../../types'; +import { Observable } from 'rxjs'; +import { User } from '../../types'; @Injectable({ providedIn: 'root', @@ -10,6 +12,7 @@ import { Hotel } from '../../types'; export class ClienteApiRestService { private static readonly BASE_URI = 'http://localhost:8080'; private static readonly HOTEL_URI = `${ClienteApiRestService.BASE_URI}/hotels`; + private static readonly USER_URI = `${ClienteApiRestService.BASE_URI}/users`; constructor(private http: HttpClient) {} getAllHotels() { @@ -45,4 +48,9 @@ export class ClienteApiRestService { } ); } + + getAllUsers(): Observable<User[]> { + return this.http.get<User[]>('http://localhost:8080/users', { observe: 'body' }); + } + } diff --git a/angular/package-lock.json b/angular/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..2e8ea3773995634d5992101777fe05f484f55b9e --- /dev/null +++ b/angular/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "angular", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}