diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index f5788453e7e148b54e4c11a1b5a5a4b6e028413b..356e1de28b07be63564b341fa3cfc7006ffc41eb 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -20,16 +20,16 @@ lint: disabled: - git-diff-check enabled: - - checkov@3.2.341 + - checkov@3.2.344 - dotenv-linter@3.3.0 - hadolint@2.12.1-beta - markdownlint@0.43.0 - - osv-scanner@1.9.1 + - osv-scanner@1.9.2 - prettier@3.4.2 - shellcheck@0.10.0 - shfmt@3.6.0 - svgo@3.3.2 - - trufflehog@3.86.1 + - trufflehog@3.88.0 - yamllint@1.35.1 actions: disabled: diff --git a/angular/RestClient/src/app/app.component.spec.ts b/angular/RestClient/src/app/app.component.spec.ts deleted file mode 100644 index 360bd69b802b5865ce5bb94b3a5ed758dbc09b26..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/app.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; -import { ReactiveFormsModule } from '@angular/forms'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent, ReactiveFormsModule], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'RestClient' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('RestClient'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, RestClient'); - }); -}); diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts index 2853c5e2d788dcaa89454b0004ca0fcf1b86e8e0..0f07bf5d33e5b14813864374cd668f79b77e95d7 100644 --- a/angular/RestClient/src/app/app.routes.ts +++ b/angular/RestClient/src/app/app.routes.ts @@ -1,13 +1,6 @@ -import { HotelListComponent } from './features/hotels/hotel-list/hotel-list.component'; -import { BookingComponent } from './features/bookings/booking/booking.component'; -import { HotelRegisterComponent } from './features/hotels/hotel-register/hotel-register.component'; -import { MainPageComponent } from './features/users/main-page/main-page.component'; -import { UserBookingListComponent } from './features/bookings/user-booking-list/user-booking-list.component'; -import { UserFormComponent } from './features/users/user-form/user-form.component'; import { UnauthorizedComponent } from './page/unauthorized/unauthorized.component'; -import { AppRoute, UserRolesArray } from './core/models'; +import { AppRoute } from './core/models'; import { rolGuard, rolGuardChild } from '@core/guards'; - export const routes: AppRoute[] = [ // Auth { @@ -40,9 +33,9 @@ export const routes: AppRoute[] = [ path: 'unauthorized', component: UnauthorizedComponent, }, - { - path: '**', - redirectTo: '/login', - pathMatch: 'full', - }, + // { + // path: '**', + // redirectTo: '/login', + // pathMatch: 'full', + // }, ]; diff --git a/angular/RestClient/src/app/core/guards/rol.guard.spec.ts b/angular/RestClient/src/app/core/guards/rol.guard.spec.ts deleted file mode 100644 index 0086470eb8061f59d7eea03aed354b751b725743..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/guards/rol.guard.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { CanActivateFn } from '@angular/router'; - -import { rolGuard } from './rol.guard'; - -describe('rolGuard', () => { - const executeGuard: CanActivateFn = (...guardParameters) => - TestBed.runInInjectionContext(() => rolGuard(...guardParameters)); - - beforeEach(() => { - TestBed.configureTestingModule({}); - }); - - it('should be created', () => { - expect(executeGuard).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/guards/rol.guard.ts b/angular/RestClient/src/app/core/guards/rol.guard.ts index 39aca9bb6fe82f1a6dc9abe6e7d92eb0bccb9944..b6d67d26e00fbc996fd96b90742a3bddf974a3c1 100644 --- a/angular/RestClient/src/app/core/guards/rol.guard.ts +++ b/angular/RestClient/src/app/core/guards/rol.guard.ts @@ -36,21 +36,27 @@ function verifyRol(expectedRole: UserRol) { router.navigate(['/login']); return false; } + + if (!expectedRole) { + console.log('any rol required'); + return true; + } + return sessionService.getSession().pipe( map((session: Session | null) => { if (!session) return false; if ( Array.isArray(expectedRole) && - (expectedRole as UserRol[]).includes(session.rol) + !(expectedRole as UserRol[]).includes(session.rol) ) { - console.log('Rol in Rol arry'); + console.log('Rol in Rol array'); return true; } else if (session.rol === expectedRole) { console.log('Rol valido'); return true; } - console.log('Unautorizado'); + console.log('Unauthorized'); // Redirige si el usuario no tiene el rol necesario router.navigate(['/unauthorized']); diff --git a/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts b/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts deleted file mode 100644 index 50f38c8abbeb5059524cfd0077b10a09260936d7..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { HttpInterceptorFn } from '@angular/common/http'; - -import { authInterceptor } from './auth.interceptor'; - -describe('authInterceptor', () => { - const interceptor: HttpInterceptorFn = (req, next) => - TestBed.runInInjectionContext(() => authInterceptor(req, next)); - - beforeEach(() => { - TestBed.configureTestingModule({}); - }); - - it('should be created', () => { - expect(interceptor).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/models/Booking.interface.ts b/angular/RestClient/src/app/core/models/Booking.interface.ts index e18c7467f930fb9b2410fb8e377c1d3faa4cdf71..e4b65d2d1c8718b6dcb3860446cd9451a5f025c2 100644 --- a/angular/RestClient/src/app/core/models/Booking.interface.ts +++ b/angular/RestClient/src/app/core/models/Booking.interface.ts @@ -3,8 +3,8 @@ import { User } from './User.interface'; export interface Booking { id: number; - startDate: Date; - endDate: Date; + start: Date; + end: Date; userId: User; roomId: Room; } diff --git a/angular/RestClient/src/app/core/models/Route.interface.ts b/angular/RestClient/src/app/core/models/Route.interface.ts index 4653cda109a68fd4945cd14e81a1b65ccb5eef26..ad601f7779b195c132a1cde2f711fc27b9622ab8 100644 --- a/angular/RestClient/src/app/core/models/Route.interface.ts +++ b/angular/RestClient/src/app/core/models/Route.interface.ts @@ -1,10 +1,10 @@ import { Route } from '@angular/router'; import { UserRol } from './User.interface'; -interface RouteData { - expectedRole: UserRol | UserRol[]; -} +type RolledRoute = { + expectedRole?: UserRol | UserRol[]; +}; -export type AppRoute = Omit<Route, 'data'> & { - data?: RouteData; +export type AppRoute<T = {}> = Omit<Route, 'data'> & { + data?: RolledRoute & T; }; diff --git a/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts deleted file mode 100644 index 74e8f4811bfa8256bdccee865e2b86389b9c25f5..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { AuthClientService } from './auth-client.service'; -import { Session } from '@core/models'; - -describe('AuthClientService', () => { - let service: AuthClientService; - let s: Session; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(AuthClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts deleted file mode 100644 index 7155f3c6a365fd8f46220cabbf90d2889eeaa05a..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { BookingClientService } from './booking-client.service'; - -describe('BookingClientService', () => { - let service: BookingClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(BookingClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts index e5046766faeb5e6998ba18683852f0aa4046ea6f..ec7237002b22ad9edcc14cb608019b4c26dd0bb0 100644 --- a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts +++ b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts @@ -14,9 +14,9 @@ export class BookingClientService { // Método para crear una nueva reserva createBooking(bookingRequest: Booking): Observable<Booking> { - const { startDate, endDate } = bookingRequest; - const end = endDate.toISOString(); - console.log({ bookingRequest, end }); + const { start, end } = bookingRequest; + const endDate = end.toISOString(); + console.log({ bookingRequest, end: endDate }); return this.http.post<Booking>(this.URI, bookingRequest); } diff --git a/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts deleted file mode 100644 index 5d32879cfc481ef393ffba104889798d7d982863..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { HotelClientService } from './hotel-client.service'; - -describe('HotelClientService', () => { - let service: HotelClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(HotelClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts deleted file mode 100644 index 3af6ef2803edf936358c39133305278bb689dd4c..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { UserClientService } from './user-client.service'; - -describe('UserClientService', () => { - let service: UserClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(UserClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/session/session.service.spec.ts b/angular/RestClient/src/app/core/services/session/session.service.spec.ts deleted file mode 100644 index 4238e142b07aad273072a64a6df73c7960707501..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/session/session.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { SessionService } from './session.service'; - -describe('SessionService', () => { - let service: SessionService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(SessionService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/session/session.service.ts b/angular/RestClient/src/app/core/services/session/session.service.ts index 743250250b2b302a5cc7fe2f491debf70c7145fb..10e7ae81e92debafb7018a558ab3bcac3fa70deb 100644 --- a/angular/RestClient/src/app/core/services/session/session.service.ts +++ b/angular/RestClient/src/app/core/services/session/session.service.ts @@ -8,7 +8,7 @@ import { AuthClientService } from '../api/auth/auth-client.service'; import { Router } from '@angular/router'; interface JWTDecoded { - userId: number; + id: number; rol: UserRol; name: string; email: string; @@ -41,7 +41,8 @@ export class SessionService { private setSession(resp: any) { const decoded = jwtDecode<JWTDecoded>(resp.token); - const user: Session = { ...decoded, id: decoded.userId }; + const user: Session = { ...decoded }; + console.log({ user, decoded, resp }); this.session$.next(user); this.storage.save(this.tokenKey, { ...resp, session: user }); const mainPage = this.getMainPage(user.rol as UserRol); diff --git a/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts b/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts deleted file mode 100644 index ba1dbd4362ebcfddcd262fc30de07f4beeb466e3..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LocalStorageService } from './local-storage.service'; - -describe('LocalStorageService', () => { - let service: LocalStorageService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(LocalStorageService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/admin/admin.module.ts b/angular/RestClient/src/app/features/admin/admin.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..f1b4844ad31582d72f6c9f50ad441483c3ea8bea --- /dev/null +++ b/angular/RestClient/src/app/features/admin/admin.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + + + +@NgModule({ + declarations: [], + imports: [ + CommonModule + ] +}) +export class AdminModule { } diff --git a/angular/RestClient/src/app/features/auth/auth.routes.ts b/angular/RestClient/src/app/features/auth/auth.routes.ts index 86d8183271d8f149246cffcce0128561545a52cb..25eea2cc25153d022df991d8341974e8a9810ae9 100644 --- a/angular/RestClient/src/app/features/auth/auth.routes.ts +++ b/angular/RestClient/src/app/features/auth/auth.routes.ts @@ -1,13 +1,23 @@ -import { AppRoute } from '@core/models'; import { UserFormComponent } from 'app/features/users'; +import { UserFormRoute } from 'app/features/users/types/UserFormData'; -export const AUTH_ROUTES: AppRoute[] = [ +export const AUTH_ROUTES: UserFormRoute[] = [ { path: 'login', + data: { + mode: { + formMode: 'LOGIN', + }, + }, component: UserFormComponent, }, { path: 'register', + data: { + mode: { + formMode: 'REGISTER', + }, + }, component: UserFormComponent, }, ]; diff --git a/angular/RestClient/src/app/features/auth/index.ts b/angular/RestClient/src/app/features/auth/index.ts index bb519ed37118e740f94bc05f1a56483aa0cfbe95..358e0c5d209b4b90f9c6ae85f6726cd5851e9a57 100644 --- a/angular/RestClient/src/app/features/auth/index.ts +++ b/angular/RestClient/src/app/features/auth/index.ts @@ -1,3 +1 @@ export * from './auth.routes'; -export * from './login/login.component'; -export * from './register/register.component'; diff --git a/angular/RestClient/src/app/features/auth/login/login.component.css b/angular/RestClient/src/app/features/auth/login/login.component.css deleted file mode 100644 index 79b4834ee543b62f19df182154eeb62fa0911db1..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.css +++ /dev/null @@ -1,21 +0,0 @@ -.container { - max-width: 600px; - margin-top: 2rem; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #f9f9f9; -} - -h2 { - text-align: center; - margin-bottom: 20px; -} - -.form-group { - margin-bottom: 15px; -} - -label { - font-weight: bold; -} diff --git a/angular/RestClient/src/app/features/auth/login/login.component.html b/angular/RestClient/src/app/features/auth/login/login.component.html deleted file mode 100644 index f6fcf96c6ad1294dad508f3a339c7f9f900c4647..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.html +++ /dev/null @@ -1,73 +0,0 @@ -<div class="container"> - <form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> - <mat-card> - <mat-card-title class="flex text-center p-4"> - <strong class="text-5xl">Login</strong> - </mat-card-title> - <mat-card-content> - <div class="form-group"> - <label class="text-2xl" for="email">Email:</label> - <input - id="email" - type="email" - formControlName="email" - class="form-control" - /> - @if (loginForm.get('email')?.invalid && - loginForm.get('email')?.touched) { - <div> - <small class="text-red-500 font-bold" - >Email is required and must be valid.</small - > - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="password">Password:</label> - <input - id="password" - type="password" - formControlName="password" - class="form-control" - /> - @if (loginForm.get('password')?.invalid && - loginForm.get('password')?.touched){ - - <div> - <small class="text-red-500 font-bold">Password is required.</small> - </div> - } - </div> - - <div class="form-group text-2xl"> - <label class="text-2xl" for="rol">Rol:</label> - <mat-form-field class="w-full" formControlName="rol"> - <mat-label class="text-2xl">Seleccione un rol</mat-label> - <mat-select [(value)]="selectedRol" name="rol"> - @for (rol of rolOptions; track rol) { - <mat-option [value]="rol"> - <span class="text-2xl">{{ rol }}</span> - </mat-option> - } - </mat-select> - </mat-form-field> - </div> - <mat-card-actions class="flex justify-center mb-5"> - <button - type="submit" - class="btn btn-success text-4xl" - [disabled]="loginForm.invalid" - > - Login - </button> - </mat-card-actions> - @if (errorMessage) { - <div class="text-red-500 font-bold"> - {{ errorMessage }} - </div> - } - </mat-card-content> - </mat-card> - </form> -</div> diff --git a/angular/RestClient/src/app/features/auth/login/login.component.spec.ts b/angular/RestClient/src/app/features/auth/login/login.component.spec.ts deleted file mode 100644 index 18f3685d74d58daabcc34d3a66be081c6256a69d..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -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/features/auth/login/login.component.ts b/angular/RestClient/src/app/features/auth/login/login.component.ts deleted file mode 100644 index c28e44d79ac016d6848e77571201b86e14c89031..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Component } from '@angular/core'; -import { - FormBuilder, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; -import { CommonModule } from '@angular/common'; -import { MatCardModule } from '@angular/material/card'; -import { MatInputModule } from '@angular/material/input'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { Router } from '@angular/router'; -import { SessionService } from '../../../core/services/session/session.service'; -import { UserRol, UserRolesArray } from '../../../core/models'; - -@Component({ - standalone: true, - selector: 'app-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.css'], - imports: [ - ReactiveFormsModule, - CommonModule, - MatCardModule, - MatInputModule, - MatFormFieldModule, - MatSelectModule, - MatSlideToggleModule, - ], -}) -export class LoginComponent { - loginForm: FormGroup; - selectedRol?: UserRol; - rolOptions: UserRol[] = UserRolesArray; - errorMessage: string | null = null; - - constructor( - private fb: FormBuilder, - private sessionManager: SessionService, - private router: Router - ) { - this.loginForm = this.fb.group({ - email: ['', [Validators.required, Validators.email]], - password: ['', [Validators.required]], - }); - } - - onSubmit() { - if (this.loginForm.valid) { - const { email, password } = this.loginForm.value; - this.sessionManager.login(email, password).subscribe({ - next: (response) => { - this.router.navigateByUrl(response.mainPage); - }, - }); - } - } - - isAuthenticated(): boolean { - return !!localStorage.getItem('authToken'); - } -} diff --git a/angular/RestClient/src/app/features/auth/register/register.component.css b/angular/RestClient/src/app/features/auth/register/register.component.css deleted file mode 100644 index 79b4834ee543b62f19df182154eeb62fa0911db1..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.css +++ /dev/null @@ -1,21 +0,0 @@ -.container { - max-width: 600px; - margin-top: 2rem; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #f9f9f9; -} - -h2 { - text-align: center; - margin-bottom: 20px; -} - -.form-group { - margin-bottom: 15px; -} - -label { - font-weight: bold; -} diff --git a/angular/RestClient/src/app/features/auth/register/register.component.html b/angular/RestClient/src/app/features/auth/register/register.component.html deleted file mode 100644 index 90cc523dc3e5fc2d2a12e9c2f259f5827c0a36ef..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.html +++ /dev/null @@ -1,85 +0,0 @@ -<div class="container"> - <form [formGroup]="registerForm" (ngSubmit)="onSubmit()"> - <mat-card> - <mat-card-title class="flex text-center p-4"> - <strong class="text-5xl">RegÃstrate</strong> - </mat-card-title> - - <mat-card-content> - <div class="form-group"> - <label class="text-2xl" for="name">Nombre</label> - <input - id="name" - class="form-control" - formControlName="name" - placeholder="Introduce tu nombre" - required - /> - @if (registerForm.get('name')?.invalid && - registerForm.get('name')?.touched) { - - <div> - <small class="text-red-500 font-bold"> - El nombre es obligatorio y debe tener al menos 3 caracteres. - </small> - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="email">Correo Electrónico</label> - <input - id="email" - type="email" - class="form-control" - formControlName="email" - placeholder="Introduce tu correo" - required - /> - @if (registerForm.get('email')?.invalid && - registerForm.get('email')?.touched) { - <div> - <small class="text-red-500 font-bold"> - El correo electrónico no es válido. - </small> - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="password">Contraseña</label> - <input - id="password" - type="password" - class="form-control" - formControlName="password" - placeholder="Introduce tu contraseña" - required - /> - @if (registerForm.get('password')?.invalid && - registerForm.get('password')?.touched) { - <div> - <small class="text-red-500 font-bold"> - La contraseña debe tener al menos 6 caracteres. - </small> - </div> - } - </div> - <mat-card-actions class="flex justify-center mb-5"> - <button - type="submit" - class="btn btn-success text-4xl" - [disabled]="registerForm.invalid" - > - Registrarse - </button> - </mat-card-actions> - @if (errorMessage) { - <div class="text-red-500 font-bold"> - {{ errorMessage }} - </div> - } - </mat-card-content> - </mat-card> - </form> -</div> diff --git a/angular/RestClient/src/app/features/auth/register/register.component.spec.ts b/angular/RestClient/src/app/features/auth/register/register.component.spec.ts deleted file mode 100644 index 757b8952cf4bbb851f3b079286c5c711dad73119..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -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/features/auth/register/register.component.ts b/angular/RestClient/src/app/features/auth/register/register.component.ts deleted file mode 100644 index 62d97d6b8697d5e3dbf001929c5be12bbf70cdee..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; -import { - FormBuilder, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; -import { MatCardModule } from '@angular/material/card'; -import { MatInputModule } from '@angular/material/input'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { Router } from '@angular/router'; -import { AuthClientService } from '../../../core/services/api/auth/auth-client.service'; -import { SessionService } from '../../../core/services/session/session.service'; - -// TODO agregar selector de roles - -@Component({ - standalone: true, - selector: 'app-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.css'], - imports: [ - ReactiveFormsModule, - CommonModule, - MatCardModule, - MatInputModule, - MatFormFieldModule, - MatSelectModule, - MatSlideToggleModule, - ], -}) -export class RegisterComponent { - registerForm: FormGroup; - errorMessage: string | null = null; - - constructor( - private fb: FormBuilder, - private authClient: AuthClientService, - private sessionManager: SessionService, - private router: Router - ) { - if (this.sessionManager.isValid()) { - const s = this.sessionManager.getSession(); - console.log({ s }); - } - this.registerForm = this.fb.group({ - name: ['', [Validators.required, Validators.minLength(3)]], - email: ['', [Validators.required, Validators.email]], - password: ['', [Validators.required, Validators.minLength(6)]], - }); - } - - onSubmit() { - if (this.registerForm.valid) { - const { name, email, password } = this.registerForm.value; - - this.authClient.register(name, email, password).subscribe({ - next: (res: any) => { - console.log({ res }); - this.sessionManager.login(res, ''); - alert('Usuario registrado con éxito.'); - this.router.navigate(['/']); // 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/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.css similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.css diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.html similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.html diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.ts similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.ts diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts deleted file mode 100644 index f6b1910a567d3ff00efa491436359519ee52632d..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { BookingListComponent } from './booking-list.component'; - -describe('BookingListComponent', () => { - let component: BookingListComponent; - let fixture: ComponentFixture<BookingListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [BookingListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(BookingListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.html b/angular/RestClient/src/app/features/bookings/booking/booking.component.html index fb7485fc16360e63fe916ee75b1f53f320895776..9cd9a6176e0307730b4e760e95699ca2a07e5910 100644 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.html +++ b/angular/RestClient/src/app/features/bookings/booking/booking.component.html @@ -26,23 +26,13 @@ </div> <div class="form-group"> - <label for="startDate">Fecha de Inicio (mm/dd/yyyy):</label> - <input - type="date" - id="startDate" - formControlName="startDate" - class="form-control" - /> + <label for="start">Fecha de Inicio (dd/mm/yyyy):</label> + <input id="start" formControlName="start" class="form-control" /> </div> <div class="form-group"> - <label for="endDate">Fecha de Fin (mm/dd/yyyy):</label> - <input - type="date" - id="endDate" - formControlName="endDate" - class="form-control" - /> + <label for="end">Fecha de Fin (dd/mm/yyyy):</label> + <input id="end" formControlName="end" class="form-control" /> </div> <button type="submit" class="btn btn-primary">Reservar</button> diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts deleted file mode 100644 index 5cfaef60aecb9a8a1c93f2b210c55e336ba27684..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { BookingComponent } from './booking.component'; -import { BookingService } from '../../../../shared/booking.service'; -import { of } from 'rxjs'; - -class MockBookingService { - createBooking() { - return of({}); // Simula una respuesta exitosa - } -} - -describe('BookingComponent', () => { - let component: BookingComponent; - let fixture: ComponentFixture<BookingComponent>; - let bookingService: BookingService; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [BookingComponent], - imports: [ReactiveFormsModule], - providers: [{ provide: BookingService, useClass: MockBookingService }], - }).compileComponents(); - - fixture = TestBed.createComponent(BookingComponent); - component = fixture.componentInstance; - bookingService = TestBed.inject(BookingService); - fixture.detectChanges(); - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - it('should have a valid form when all fields are filled', () => { - component.bookingForm.controls['userId'].setValue(1); - component.bookingForm.controls['hotelId'].setValue(1); - component.bookingForm.controls['roomType'].setValue('single'); - component.bookingForm.controls['startDate'].setValue('2024-10-01'); - component.bookingForm.controls['endDate'].setValue('2024-10-05'); - - expect(component.bookingForm.valid).toBeTrue(); - }); - - it('should submit booking when form is valid', () => { - spyOn(bookingService, 'createBooking').and.callThrough(); - component.bookingForm.controls['userId'].setValue(1); - component.bookingForm.controls['hotelId'].setValue(1); - component.bookingForm.controls['roomType'].setValue('single'); - component.bookingForm.controls['startDate'].setValue('2024-10-01'); - component.bookingForm.controls['endDate'].setValue('2024-10-05'); - - component.submitBooking(); - expect(bookingService.createBooking).toHaveBeenCalled(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts index f37e6576c13158c3bcdcca482c179c82b03904bb..d8c08a935b3a7917ba6fd59f763979b07bab4543 100644 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.ts +++ b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts @@ -15,8 +15,8 @@ import { SessionService } from '../../../core/services/session/session.service'; type communication = { roomId: number; - startDate: Date; - endDate: Date; + start: Date; + end: Date; }; @Component({ @@ -29,10 +29,10 @@ type communication = { export class BookingComponent { user: User = { id: 0, email: '', name: '', rol: 'CLIENT' }; bookingForm: FormGroup; - bookingLocal: { roomId: number; startDate: Date; endDate: Date } = { + bookingLocal: { roomId: number; start: Date; end: Date } = { roomId: 0, - endDate: new Date(), - startDate: new Date(), + end: new Date(), + start: new Date(), }; roomId: number = 0; @@ -48,8 +48,8 @@ export class BookingComponent { // Inicialización del formulario con validaciones this.bookingForm = this.fb.group({ roomId: [{ value: '', disabled: true }, Validators.required], - startDate: [{ value: '', disabled: true }, Validators.required], - endDate: [{ value: '', disabled: true }, Validators.required], + start: [{ value: '', disabled: true }, Validators.required], + end: [{ value: '', disabled: true }, Validators.required], }); const localBooking = storage.read<communication | null>('booking-data'); if (localBooking === null) { @@ -66,8 +66,8 @@ export class BookingComponent { } this.bookingLocal = { ...this.bookingLocal, - startDate: new Date(this.bookingLocal.startDate), - endDate: new Date(this.bookingLocal.endDate), + start: new Date(this.bookingLocal.start), + end: new Date(this.bookingLocal.end), }; this.loadBooking(); }); @@ -78,15 +78,22 @@ export class BookingComponent { }); } + private formatDate(date: Date) { + console.log(date); + return date.toISOString().split('T')[0].split('-').reverse().join('-'); + } + loadBooking() { const booking = this.bookingLocal; if (!booking) return; - const start = new Date(booking.startDate).toISOString(); - const end = new Date(booking.endDate).toISOString(); + const start = this.formatDate(booking.start); + const end = this.formatDate(booking.end); + console.log({ start, end }); + this.bookingForm = this.fb.group({ roomId: [{ value: booking.roomId, disabled: true }, Validators.required], - startDate: [{ value: start, disabled: true }, Validators.required], - endDate: [{ value: end, disabled: true }, Validators.required], + start: [{ value: start, disabled: true }, Validators.required], + end: [{ value: end, disabled: true }, Validators.required], }); } @@ -94,11 +101,13 @@ export class BookingComponent { const { id } = this.user; const bookingRequest: any = { ...this.bookingLocal, - userId: { id }, - roomId: { id: this.roomId }, + userId: id, + roomId: this.roomId, }; // Llama al servicio para crear una nueva reserva + console.log(bookingRequest); + this.bookingClient.createBooking(bookingRequest).subscribe({ next: (response) => { console.log('Reserva creada con éxito', response); diff --git a/angular/RestClient/src/app/features/bookings/index.ts b/angular/RestClient/src/app/features/bookings/index.ts index aa2b48a8a5e51016f6fb70658f3bbe0ab78aad8a..295ef468572fd100710157a4e23dd9efe537a2bc 100644 --- a/angular/RestClient/src/app/features/bookings/index.ts +++ b/angular/RestClient/src/app/features/bookings/index.ts @@ -1,4 +1,4 @@ export * from './bookings.routes'; export * from './booking/booking.component'; -export * from './booking-list/booking-list.component'; +export * from './[DEL] booking-list/booking-list.component'; export * from './user-booking-list/user-booking-list.component'; diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html index 6a845bc703fc7e279909d96f39e55c2f387e33c5..69a3dac63c1dde6bd1f2da787ce91d801bce3096 100644 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html +++ b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html @@ -25,8 +25,8 @@ <li class="booking-item"> <span class="booking-id">Reserva #{{ booking.id }}</span> - <span class="booking-start">{{ booking.startDate }}</span> - <span class="booking-end">{{ booking.endDate }}</span> + <span class="booking-start">{{ booking.start }}</span> + <span class="booking-end">{{ booking.end }}</span> <span class="booking-status">{{ genBookingState(booking) }}</span> <span class="booking-delete"> <button (click)="deleteBooking(booking.id)">Eliminar</button> diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts deleted file mode 100644 index aae5d913c76b3f160908b0f5302bd80e29e94082..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { UserBookingListComponent } from './user-booking-list.component'; - -describe('UserBookingListComponent', () => { - let component: UserBookingListComponent; - let fixture: ComponentFixture<UserBookingListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [UserBookingListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(UserBookingListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts index a76d5b38b9face0358016a6088f8c4e8bf8349d1..c3059d8127adc9a55e855d19730f8f9623314253 100644 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts +++ b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts @@ -76,8 +76,7 @@ export class UserBookingListComponent { } genBookingState(booking: Booking) { - return new Date().setHours(0, 0, 0, 0) <= - new Date(booking.endDate).getTime() + return new Date().setHours(0, 0, 0, 0) <= new Date(booking.end).getTime() ? 'Reserva activa' : 'Reserva inactiva'; } diff --git a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts deleted file mode 100644 index ecc47151bf323959f0871b28bf1a09980e6b6702..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { HotelListComponent } from './hotel-list.component'; - -describe('HotelListComponent', () => { - let component: HotelListComponent; - let fixture: ComponentFixture<HotelListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [HotelListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(HotelListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts index 4cf5d5c40b4d5931eb994a05befe425ec0d20fc1..9ec062a6bb28ff8af281e96356b1200094f0a351 100644 --- a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts +++ b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts @@ -76,8 +76,11 @@ export class HotelListComponent { private storage: LocalStorageService, private sessionService: SessionService ) { - const isHotelManger = this.route.snapshot.url[0].path === 'me'; - const isAdmin = this.route.snapshot.url[0].path === 'admin'; + const url = this.router.url; + const baseUrl = getBasePath(url).split('/')[1]; + const isHotelManger = url.split('/')[1] === 'me'; + const isAdmin = baseUrl === 'admin'; + console.log({ isHotelManger, isAdmin, baseUrl }); this.isManaging = isHotelManger || isAdmin; const today = new Date(); @@ -91,6 +94,7 @@ export class HotelListComponent { this.sessionService.getSession().subscribe({ next: (session) => { + console.log({ session }); if (session && session.rol !== 'CLIENT') { this.isEditing = true; this.userId = isHotelManger @@ -116,12 +120,14 @@ export class HotelListComponent { ) .map((h) => { h = { ...h, rooms: [...h.rooms] }; - h.rooms = h.rooms.filter( - (r) => - r.available && - (this.roomTypeSelected === 'All' || - (r.type as SelectableRoomType) === this.roomTypeSelected) - ); + if (!this.isManaging) { + h.rooms = h.rooms.filter( + (r) => + r.available && + (this.roomTypeSelected === 'All' || + (r.type as SelectableRoomType) === this.roomTypeSelected) + ); + } return h; }) .filter((h) => h.rooms.length > 0); @@ -148,9 +154,10 @@ export class HotelListComponent { const { start, end } = this.dateRangeForm.value.dateRange; const observable = this.isManaging - ? this.hotelClient.getAllHotelsByUser(this.userId, start, end) + ? this.hotelClient.getAllHotelsByUser(this.userId) : this.hotelClient.getAllHotels(start, end); - console.log({ ...this }); + console.log('a', this.isManaging); + observable.subscribe({ next: (resp) => { if (!!resp && (resp as never[]).length >= 0) { @@ -201,7 +208,8 @@ export class HotelListComponent { getHotelUri(hotelId: number) { var base; try { - base = getBasePath(this.route) + '/'; + // TODO revisar + base = getBasePath(this.router.url) + '/'; } catch (error) { base = ''; } @@ -215,8 +223,8 @@ export class HotelListComponent { }; this.storage.save('booking-data', { roomId, - startDate: start.toString(), - endDate: end.toString(), + start: start.toString(), + end: end.toString(), }); this.router.navigate(['/me', 'bookings', 'new'], { queryParams: { roomId, startDate: start.toLocaleDateString() }, diff --git a/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts deleted file mode 100644 index 7c085a3a8e7f1451e531f12d96d0049bb6b8a319..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { HotelRegisterComponent } from './hotel-register.component'; - -describe('HotelRegisterComponent', () => { - let component: HotelRegisterComponent; - let fixture: ComponentFixture<HotelRegisterComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [HotelRegisterComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(HotelRegisterComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/hotels/hotels.routes.ts b/angular/RestClient/src/app/features/hotels/hotels.routes.ts index 9e000411a9680f7e8c0e8242d2f819e41bc959d6..d054f0ab51aa1b583477e30a22ef1e1949fb1e6e 100644 --- a/angular/RestClient/src/app/features/hotels/hotels.routes.ts +++ b/angular/RestClient/src/app/features/hotels/hotels.routes.ts @@ -22,24 +22,19 @@ export const HOTELS_ROUTES: AppRoute[] = [ export const MANAGERS_ROUTES: AppRoute[] = [ { - path: 'hotels', - children: [ - { - path: '', - component: HotelListComponent, - }, - { - path: ':id', - component: HotelRegisterComponent, - }, - // { - // path: ':id/bookings', - // component: BookingListComponent, - // }, - // { - // path: ':id/rooms/:id/bookings', - // component: BookingListComponent, - // }, - ], + path: '', + component: HotelListComponent, + }, + { + path: ':id', + component: HotelRegisterComponent, }, + // { + // path: ':id/bookings', + // component: BookingListComponent, + // }, + // { + // path: ':id/rooms/:id/bookings', + // component: BookingListComponent, + // }, ]; diff --git a/angular/RestClient/src/app/features/users/admin.routes.ts b/angular/RestClient/src/app/features/users/admin.routes.ts index ff360470360e7b4b7d1d88192cf6cc1275500a8c..fdd9b4a24933b7331c8f47394076eb3d15686398 100644 --- a/angular/RestClient/src/app/features/users/admin.routes.ts +++ b/angular/RestClient/src/app/features/users/admin.routes.ts @@ -1,23 +1,36 @@ import { AppRoute } from '@core/models'; import { MainPageComponent } from 'app/features/users/main-page/main-page.component'; +import { UserFormRoute } from 'app/features/users/types/UserFormData'; import { UserFormComponent } from 'app/features/users/user-form/user-form.component'; import { USERS_ROUTES } from 'app/features/users/users.routes'; -function getRoutesWithoutRol(routes: AppRoute[]) { +function changeToAdminScope(routes: UserFormRoute[]) { return routes.map((r) => { - if (r.data?.expectedRole) { + if (r.data) { const { data, ...rest } = r; - return { ...rest }; + data.expectedRole = undefined; + if (data.mode) { + data.mode.admin = true; + } + return { data, ...rest }; } return r; }); } -export const ADMIN_ROUTES: AppRoute[] = [ - { - path: '', // Main - component: UserFormComponent, +const mainRoute: UserFormRoute = { + path: '', // Main + data: { + mode: { + formMode: 'VIEW', + admin: true, + }, }, + component: UserFormComponent, +}; + +export const ADMIN_ROUTES: AppRoute[] = [ + mainRoute, { path: 'users', children: [ @@ -27,7 +40,7 @@ export const ADMIN_ROUTES: AppRoute[] = [ }, { path: ':id', - children: getRoutesWithoutRol(USERS_ROUTES), + children: changeToAdminScope(USERS_ROUTES), }, ], }, diff --git a/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts b/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts deleted file mode 100644 index 40d589a21205dbd8b271cf4f441e0dfd44ed37ca..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -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/features/users/types/UserFormData.d.ts b/angular/RestClient/src/app/features/users/types/UserFormData.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..2796c6000dbf309e50e0fa670a2995896a8be6e9 --- /dev/null +++ b/angular/RestClient/src/app/features/users/types/UserFormData.d.ts @@ -0,0 +1,15 @@ +import { AppRoute } from '@core/models'; + +export type UserFormMode = + | 'REGISTER' + | 'LOGIN' + | 'PASSWORD' + | 'VIEW' + | 'EDIT' + | 'OTHER'; +export type ModeType = { + formMode: UserFormMode; + admin?: boolean; +}; + +export type UserFormRoute = AppRoute<{ mode?: ModeType }>; diff --git a/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts deleted file mode 100644 index b2c1c438bf3079058be1e1c81ec8f81130cc75c8..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts +++ /dev/null @@ -1,95 +0,0 @@ -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 '../../../core/services/api/users/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(); - }); -}); diff --git a/angular/RestClient/src/app/features/users/user-form/user-form.component.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts index c57800fc59228402d653658462be49b380d40be3..8be92348239bcc0eaa9fe16265d8ff6b4dd22c7f 100644 --- a/angular/RestClient/src/app/features/users/user-form/user-form.component.ts +++ b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts @@ -16,16 +16,12 @@ import { SessionService } from '../../../core/services/session/session.service'; import { Session, UserRol, UserRolesArray } from '../../../core/models'; import { MatSelectModule } from '@angular/material/select'; import { Observable } from 'rxjs'; -import { getBasePath } from '../../../utils/utils'; -import { environment } from '../../../../environments/environment'; +import { + UserFormMode, + UserFormRoute, +} from 'app/features/users/types/UserFormData'; +import { getBasePath } from '@utils/utils'; -type EditMode = - | 'Login' - | 'Register' - | 'ViewUser' - | 'EditUser' - | 'ChangePassword' - | 'Other'; const defaultUser: Session = { id: 0, name: 'test', @@ -52,7 +48,7 @@ const defaultUser: Session = { export class UserFormComponent implements OnInit { userForm!: FormGroup; rolOptions: UserRol[] = UserRolesArray; - mode: EditMode = 'Other'; + mode: UserFormMode = 'OTHER'; isMeRoute = false; /** is editing the user data */ @@ -84,29 +80,6 @@ export class UserFormComponent implements OnInit { private router: Router ) {} - isEditRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length >= 2 && urlSegments[1].path === 'edit' - : urlSegments.length >= 4 && urlSegments[3].path === 'edit'; - } - - isChangePasswordRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length >= 2 && urlSegments[1].path === 'change-passwd' - : urlSegments.length >= 4 && urlSegments[3].path === 'change-passwd'; - } - - isViewUserRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length === 1 - : (urlSegments.length === 1 && urlSegments[0].path === 'admin') || - urlSegments.length === 3; - } - - isAuthRoute(urlSegments: any[], route: string): boolean { - return urlSegments.length === 1 && urlSegments[0].path === route; - } - ngOnInit(): void { this.setUp(); @@ -167,47 +140,50 @@ export class UserFormComponent implements OnInit { } setUp() { - const urlSeg = this.route.snapshot.url; - if (this.isAuthRoute(urlSeg, 'login')) { - // Login - this.isAuth = true; - this.isLogin = true; - this.mode = 'Login'; - this.currentPasswordText = 'Contraseña'; - this.submitButtonText = 'Login'; - this.titleText = 'Login'; - } else if (this.isAuthRoute(urlSeg, 'register')) { - // Register - this.isAuth = true; - this.isRegister = true; - this.mode = 'Register'; - this.currentPasswordText = 'Contraseña'; - this.submitButtonText = 'Create'; - this.titleText = 'Register'; - } else { - // Identificar si estamos usando /me o /users/:id - getBasePath(this.route); - const isMeRoute = urlSeg[0].path === 'me'; - this.isMeRoute = isMeRoute; - - if (this.isEditRoute(urlSeg, isMeRoute)) { - this.isEditing = true; - this.mode = 'EditUser'; - this.titleText = 'Editar mis datos'; - } else if (this.isChangePasswordRoute(urlSeg, isMeRoute)) { - this.mode = 'ChangePassword'; + const snapshot = this.route.snapshot; + const urlSeg = snapshot.url; + const { data } = snapshot as UserFormRoute; + const mode = data!.mode!; + + console.log(mode); + + switch (mode.formMode) { + case 'REGISTER': + this.isAuth = true; + this.isRegister = true; + this.currentPasswordText = 'Contraseña'; + this.submitButtonText = 'Create'; + this.titleText = 'Register'; + break; + case 'LOGIN': + this.isAuth = true; + this.isLogin = true; + this.currentPasswordText = 'Contraseña'; + this.submitButtonText = 'Login'; + this.titleText = 'Login'; + break; + case 'PASSWORD': this.isEditing = true; this.isChangePassword = true; this.currentPasswordText = 'Contraseña actual'; this.titleText = 'Cambiar mi contraseña'; - } else if (this.isViewUserRoute(urlSeg, isMeRoute)) { - this.mode = 'ViewUser'; + this.submitButtonText = 'Update password'; + break; + case 'VIEW': this.isViewUser = true; this.titleText = 'Mis datos'; - } - - this.submitButtonText = 'Update'; + break; + case 'EDIT': + this.isEditing = true; + this.titleText = 'Editar mis datos'; + this.submitButtonText = 'Update'; + break; + case 'OTHER': + default: + break; } + this.isAdmin = !!mode.admin; + this.mode = mode.formMode; this.initializeForm(); if (!this.isAuth) { @@ -226,31 +202,31 @@ export class UserFormComponent implements OnInit { } getHotelsUri() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' return `${basePath}/hotels`; } getBookingsUri() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' return `${basePath}/bookings`; } togglePassword() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' - - if (this.mode === 'EditUser') { + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' + console.log('->', basePath); + if (this.mode === 'EDIT') { this.router.navigateByUrl(`${basePath}/change-passwd`); - } else if (this.mode === 'ChangePassword') { + } else if (this.mode === 'PASSWORD') { this.router.navigateByUrl(`${basePath}/edit`); } } switchMode() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' - console.log({ ...this }); - if (this.mode === 'EditUser') { + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' + console.log('->', { basePath }); + if (this.mode === 'EDIT' || this.mode === 'PASSWORD') { this.router.navigateByUrl(basePath); - } else if (this.mode === 'ViewUser') { + } else if (this.mode === 'VIEW') { this.router.navigateByUrl(`${basePath}/edit`); } } @@ -320,17 +296,17 @@ export class UserFormComponent implements OnInit { console.log({ data }); switch (this.mode) { - case 'Login': + case 'LOGIN': this.login(data.email, data.currentPassword); break; - case 'Register': + case 'REGISTER': this.register(data.name, data.email, data.currentPassword, data.rol); break; - case 'EditUser': + case 'EDIT': this.updateUser(data.name, data.email); break; - case 'ChangePassword': - this.changePassword(data.currentPassword, data.newPassword); + case 'PASSWORD': + this.updatePassword(data.currentPassword, data.newPassword); break; default: break; @@ -370,7 +346,7 @@ export class UserFormComponent implements OnInit { private updateUser(name: string, email: string) { this.userService.updateUser(this.user.id, { name, email }).subscribe({ next: () => { - this.router.navigateByUrl(getBasePath(this.route)); + this.router.navigateByUrl(getBasePath(this.router.url)); }, error: (error) => { console.error(error); @@ -379,7 +355,7 @@ export class UserFormComponent implements OnInit { }); } - private changePassword(password: string | undefined, newPassword: string) { + private updatePassword(password: string | undefined, newPassword: string) { alert('Unimplemented yet'); } } diff --git a/angular/RestClient/src/app/features/users/users.routes.ts b/angular/RestClient/src/app/features/users/users.routes.ts index 84c240ff1e34363caf5c9d69c643b30a9ccb38ef..aca2079caf16f9eb0010ac50ac872673ab659781 100644 --- a/angular/RestClient/src/app/features/users/users.routes.ts +++ b/angular/RestClient/src/app/features/users/users.routes.ts @@ -1,22 +1,34 @@ -import { AppRoute, UserRolesArray } from '@core/models'; import { UserFormComponent } from './user-form/user-form.component'; +import { UserFormRoute } from './types/UserFormData'; -export const USERS_ROUTES: AppRoute[] = [ +export const USERS_ROUTES: UserFormRoute[] = [ // Common { path: '', - data: { expectedRole: UserRolesArray }, + data: { + mode: { + formMode: 'VIEW', + }, + }, component: UserFormComponent, }, { path: 'edit', + data: { + mode: { + formMode: 'EDIT', + }, + }, component: UserFormComponent, - data: { expectedRole: UserRolesArray }, }, { path: 'change-passwd', + data: { + mode: { + formMode: 'PASSWORD', + }, + }, component: UserFormComponent, - data: { expectedRole: UserRolesArray }, }, { // Usuario administrador de hoteles diff --git a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts b/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts deleted file mode 100644 index bab5ad8d9e3b005c4068dffa26dacb9de7417c15..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { UnauthorizedComponent } from './unauthorized.component'; - -describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture<UnauthorizedComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [UnauthorizedComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts b/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts deleted file mode 100644 index a161d3121330b48782b4b9f80a5060f1b5ab7c53..0000000000000000000000000000000000000000 --- a/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NavigationComponent } from './navigation.component'; - -describe('NavigationComponent', () => { - let component: NavigationComponent; - let fixture: ComponentFixture<NavigationComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [NavigationComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(NavigationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/utils/utils.ts b/angular/RestClient/src/app/utils/utils.ts index 1c97d18b18ba30a2588acf79ecddb5a0f9747146..a32f785ba732d2701656497706f176319d000cbc 100644 --- a/angular/RestClient/src/app/utils/utils.ts +++ b/angular/RestClient/src/app/utils/utils.ts @@ -1,18 +1,20 @@ -import { ActivatedRoute } from '@angular/router'; - -export function getBasePath(route: ActivatedRoute): string { - const urlSegments = route.snapshot.url; - if (urlSegments[0].path === 'me') { - return '/me'; - } else if ( - urlSegments.length >= 3 && - urlSegments[0].path === 'admin' && - urlSegments[1].path === 'users' && - urlSegments[2] - ) { - return `/admin/users/${urlSegments[2]}`; // Devuelve la ruta con el ID del usuario - } else if (urlSegments[0].path === 'admin') { - return '/me'; +export function getBasePath(route: string) { + const url = route.split('/').slice(1); + const me = '/me'; + let base = me; + if (url.length > 0 && url[0] === me) { + base = url[0]; + } else if (url.length > 0 && url[0] === 'admin') { + const i = url.indexOf('users'); + const j = url.indexOf('hotels'); + base = + i !== -1 + ? url.slice(0, i + 2).join('/') + : j !== -1 + ? url.slice(0, i + 2).join('/') + : me; } - throw new Error('Invalid route structure'); // Manejo de errores si la URL no es válida + + console.log({ url, route, base }); + return base; } diff --git a/angular/RestClient/src/environments/environment.prod.ts b/angular/RestClient/src/environments/environment.prod.ts index db340146972d3c6f6e2ed09dc8821c12d6de1835..88bea49ff46a558605e6e2c0408f24bb0eb52d91 100644 --- a/angular/RestClient/src/environments/environment.prod.ts +++ b/angular/RestClient/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ -const gateWayUrl = 'localhost:8000'; // kong +const gateWayUrl = 'localhost:8000/api'; // kong export const environment = { production: true, diff --git a/angular/RestClient/src/environments/environment.ts b/angular/RestClient/src/environments/environment.ts index 27e99150c7a58f272a3099a5b5fe98f31f2c901f..0d80152f74dd186e2deb5a7d90bfc7fc01d3de46 100644 --- a/angular/RestClient/src/environments/environment.ts +++ b/angular/RestClient/src/environments/environment.ts @@ -1,8 +1,8 @@ const developmentHost = 'localhost'; export const environment = { production: false, - authAPI: `http://${developmentHost}:8101`, - userAPI: `http://${developmentHost}:8080/users`, - hotelAPI: `http://${developmentHost}:8080/hotels`, - bookingAPI: `http://${developmentHost}:8080/bookings`, + authAPI: `http://${developmentHost}:8101/auth`, + userAPI: `http://${developmentHost}:8201/users`, + hotelAPI: `http://${developmentHost}:8301/hotels`, + bookingAPI: `http://${developmentHost}:8401/bookings`, }; diff --git a/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000000000000000000000000000000000000..3b50599492c36017391c0dcabd81573f123a809a --- /dev/null +++ b/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000000000000000000000000000000000000..3b50599492c36017391c0dcabd81573f123a809a --- /dev/null +++ b/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000000000000000000000000000000000000..3b50599492c36017391c0dcabd81573f123a809a --- /dev/null +++ b/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000000000000000000000000000000000000..3b50599492c36017391c0dcabd81573f123a809a --- /dev/null +++ b/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +}