From d20150506f453d0e67d4df6105e08fbffbfbae0e Mon Sep 17 00:00:00 2001 From: luis cespedes Date: Wed, 23 Apr 2025 11:57:14 -0400 Subject: [PATCH] cap 4 --- angular.json | 3 +- package-lock.json | 10 ++ package.json | 1 + src/app/app-routing.module.ts | 16 ++ src/app/models/booking.model.ts | 8 + src/app/models/gym-class.model.ts | 12 ++ src/app/models/user.model.ts | 10 ++ .../pages/bookings/bookings-routing.module.ts | 17 ++ src/app/pages/bookings/bookings.module.ts | 20 +++ .../bookings/bookings.page.html} | 8 +- .../bookings/bookings.page.scss} | 0 src/app/pages/bookings/bookings.page.spec.ts | 17 ++ src/app/pages/bookings/bookings.page.ts | 16 ++ .../class-detail-routing.module.ts | 17 ++ .../pages/class-detail/class-detail.module.ts | 17 ++ .../pages/class-detail/class-detail.page.html | 79 +++++++++ .../pages/class-detail/class-detail.page.scss | 9 + .../class-detail/class-detail.page.spec.ts | 17 ++ .../pages/class-detail/class-detail.page.ts | 150 +++++++++++++++++ .../pages/classes/classes-routing.module.ts | 20 +++ src/app/pages/classes/classes.module.ts | 17 ++ src/app/pages/classes/classes.page.html | 57 +++++++ .../classes/classes.page.scss} | 0 src/app/pages/classes/classes.page.spec.ts | 17 ++ src/app/pages/classes/classes.page.ts | 93 +++++++++++ .../pages/profile/profile-routing.module.ts | 17 ++ src/app/pages/profile/profile.module.ts | 20 +++ .../profile/profile.page.html} | 8 +- .../profile/profile.page.scss} | 0 src/app/pages/profile/profile.page.spec.ts | 17 ++ src/app/pages/profile/profile.page.ts | 16 ++ src/app/services/auth.service.spec.ts | 16 ++ src/app/services/auth.service.ts | 66 ++++++++ src/app/services/bookings.service.spec.ts | 16 ++ src/app/services/bookings.service.ts | 124 ++++++++++++++ src/app/services/classes.service.spec.ts | 16 ++ src/app/services/classes.service.ts | 155 ++++++++++++++++++ src/app/services/storage.service.spec.ts | 16 ++ src/app/services/storage.service.ts | 35 ++++ src/app/tab1/tab1-routing.module.ts | 16 -- src/app/tab1/tab1.module.ts | 20 --- src/app/tab1/tab1.page.html | 17 -- src/app/tab1/tab1.page.spec.ts | 26 --- src/app/tab1/tab1.page.ts | 13 -- src/app/tab2/tab2-routing.module.ts | 16 -- src/app/tab2/tab2.module.ts | 20 --- src/app/tab2/tab2.page.spec.ts | 26 --- src/app/tab2/tab2.page.ts | 13 -- src/app/tab3/tab3-routing.module.ts | 16 -- src/app/tab3/tab3.module.ts | 20 --- src/app/tab3/tab3.page.spec.ts | 26 --- src/app/tab3/tab3.page.ts | 13 -- src/app/tabs/tabs-routing.module.ts | 18 +- src/app/tabs/tabs.page.html | 24 ++- 54 files changed, 1160 insertions(+), 277 deletions(-) create mode 100644 src/app/models/booking.model.ts create mode 100644 src/app/models/gym-class.model.ts create mode 100644 src/app/models/user.model.ts create mode 100644 src/app/pages/bookings/bookings-routing.module.ts create mode 100644 src/app/pages/bookings/bookings.module.ts rename src/app/{tab2/tab2.page.html => pages/bookings/bookings.page.html} (57%) rename src/app/{tab1/tab1.page.scss => pages/bookings/bookings.page.scss} (100%) create mode 100644 src/app/pages/bookings/bookings.page.spec.ts create mode 100644 src/app/pages/bookings/bookings.page.ts create mode 100644 src/app/pages/class-detail/class-detail-routing.module.ts create mode 100644 src/app/pages/class-detail/class-detail.module.ts create mode 100644 src/app/pages/class-detail/class-detail.page.html create mode 100644 src/app/pages/class-detail/class-detail.page.scss create mode 100644 src/app/pages/class-detail/class-detail.page.spec.ts create mode 100644 src/app/pages/class-detail/class-detail.page.ts create mode 100644 src/app/pages/classes/classes-routing.module.ts create mode 100644 src/app/pages/classes/classes.module.ts create mode 100644 src/app/pages/classes/classes.page.html rename src/app/{tab2/tab2.page.scss => pages/classes/classes.page.scss} (100%) create mode 100644 src/app/pages/classes/classes.page.spec.ts create mode 100644 src/app/pages/classes/classes.page.ts create mode 100644 src/app/pages/profile/profile-routing.module.ts create mode 100644 src/app/pages/profile/profile.module.ts rename src/app/{tab3/tab3.page.html => pages/profile/profile.page.html} (57%) rename src/app/{tab3/tab3.page.scss => pages/profile/profile.page.scss} (100%) create mode 100644 src/app/pages/profile/profile.page.spec.ts create mode 100644 src/app/pages/profile/profile.page.ts create mode 100644 src/app/services/auth.service.spec.ts create mode 100644 src/app/services/auth.service.ts create mode 100644 src/app/services/bookings.service.spec.ts create mode 100644 src/app/services/bookings.service.ts create mode 100644 src/app/services/classes.service.spec.ts create mode 100644 src/app/services/classes.service.ts create mode 100644 src/app/services/storage.service.spec.ts create mode 100644 src/app/services/storage.service.ts delete mode 100644 src/app/tab1/tab1-routing.module.ts delete mode 100644 src/app/tab1/tab1.module.ts delete mode 100644 src/app/tab1/tab1.page.html delete mode 100644 src/app/tab1/tab1.page.spec.ts delete mode 100644 src/app/tab1/tab1.page.ts delete mode 100644 src/app/tab2/tab2-routing.module.ts delete mode 100644 src/app/tab2/tab2.module.ts delete mode 100644 src/app/tab2/tab2.page.spec.ts delete mode 100644 src/app/tab2/tab2.page.ts delete mode 100644 src/app/tab3/tab3-routing.module.ts delete mode 100644 src/app/tab3/tab3.module.ts delete mode 100644 src/app/tab3/tab3.page.spec.ts delete mode 100644 src/app/tab3/tab3.page.ts diff --git a/angular.json b/angular.json index e7c7b88..cfb5aa0 100644 --- a/angular.json +++ b/angular.json @@ -136,7 +136,8 @@ "cli": { "schematicCollections": [ "@ionic/angular-toolkit" - ] + ], + "analytics": false }, "schematics": { "@ionic/angular-toolkit:component": { diff --git a/package-lock.json b/package-lock.json index 7095fc3..2d73c94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@capacitor/core": "7.2.0", "@capacitor/haptics": "7.0.1", "@capacitor/keyboard": "7.0.1", + "@capacitor/preferences": "^7.0.1", "@capacitor/status-bar": "7.0.1", "@ionic/angular": "^8.0.0", "ionicons": "^7.0.0", @@ -2768,6 +2769,15 @@ "@capacitor/core": ">=7.0.0" } }, + "node_modules/@capacitor/preferences": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@capacitor/preferences/-/preferences-7.0.1.tgz", + "integrity": "sha512-XF9jOHzvoIBZLwZr/EX6aVaUO1d8Mx7TwBLQS33pYHOliCW5knT5KUkFOXNNYxh9qqODYesee9xuQIKNJpQBag==", + "license": "MIT", + "peerDependencies": { + "@capacitor/core": ">=7.0.0" + } + }, "node_modules/@capacitor/status-bar": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@capacitor/status-bar/-/status-bar-7.0.1.tgz", diff --git a/package.json b/package.json index 300c719..d85ea6f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@capacitor/core": "7.2.0", "@capacitor/haptics": "7.0.1", "@capacitor/keyboard": "7.0.1", + "@capacitor/preferences": "^7.0.1", "@capacitor/status-bar": "7.0.1", "@ionic/angular": "^8.0.0", "ionicons": "^7.0.0", diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 48fc28d..e5e70a8 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,6 +5,22 @@ const routes: Routes = [ { path: '', loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule) + }, + { + path: 'classes', + loadChildren: () => import('./pages/classes/classes.module').then( m => m.ClassesPageModule) + }, + { + path: 'class-detail', + loadChildren: () => import('./pages/class-detail/class-detail.module').then( m => m.ClassDetailPageModule) + }, + { + path: 'bookings', + loadChildren: () => import('./pages/bookings/bookings.module').then( m => m.BookingsPageModule) + }, + { + path: 'profile', + loadChildren: () => import('./pages/profile/profile.module').then( m => m.ProfilePageModule) } ]; @NgModule({ diff --git a/src/app/models/booking.model.ts b/src/app/models/booking.model.ts new file mode 100644 index 0000000..f95be65 --- /dev/null +++ b/src/app/models/booking.model.ts @@ -0,0 +1,8 @@ +export interface Booking { + id: string; + userId: string; + classId: string; + className: string; + date: Date; + status: 'confirmed' | 'cancelled' | 'pending'; + } \ No newline at end of file diff --git a/src/app/models/gym-class.model.ts b/src/app/models/gym-class.model.ts new file mode 100644 index 0000000..c284122 --- /dev/null +++ b/src/app/models/gym-class.model.ts @@ -0,0 +1,12 @@ +export interface GymClass { + id: string; + name: string; + description: string; + instructor: string; + startTime: Date; + endTime: Date; + maxCapacity: number; + currentBookings: number; + category?: string; + imageUrl?: string; + } \ No newline at end of file diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts new file mode 100644 index 0000000..5255b78 --- /dev/null +++ b/src/app/models/user.model.ts @@ -0,0 +1,10 @@ +export interface User { + id: string; + name: string; + email: string; + profilePic?: string; + preferences?: { + notifications: boolean; + favoriteClasses?: string[]; + }; + } \ No newline at end of file diff --git a/src/app/pages/bookings/bookings-routing.module.ts b/src/app/pages/bookings/bookings-routing.module.ts new file mode 100644 index 0000000..18ce57c --- /dev/null +++ b/src/app/pages/bookings/bookings-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { BookingsPage } from './bookings.page'; + +const routes: Routes = [ + { + path: '', + component: BookingsPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class BookingsPageRoutingModule {} diff --git a/src/app/pages/bookings/bookings.module.ts b/src/app/pages/bookings/bookings.module.ts new file mode 100644 index 0000000..8836ea7 --- /dev/null +++ b/src/app/pages/bookings/bookings.module.ts @@ -0,0 +1,20 @@ +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { BookingsPageRoutingModule } from './bookings-routing.module'; + +import { BookingsPage } from './bookings.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + BookingsPageRoutingModule + ], + declarations: [BookingsPage], +}) +export class BookingsPageModule {} diff --git a/src/app/tab2/tab2.page.html b/src/app/pages/bookings/bookings.page.html similarity index 57% rename from src/app/tab2/tab2.page.html rename to src/app/pages/bookings/bookings.page.html index 38b153e..9c032fb 100644 --- a/src/app/tab2/tab2.page.html +++ b/src/app/pages/bookings/bookings.page.html @@ -1,17 +1,13 @@ - - Tab 2 - + bookings - Tab 2 + bookings - - diff --git a/src/app/tab1/tab1.page.scss b/src/app/pages/bookings/bookings.page.scss similarity index 100% rename from src/app/tab1/tab1.page.scss rename to src/app/pages/bookings/bookings.page.scss diff --git a/src/app/pages/bookings/bookings.page.spec.ts b/src/app/pages/bookings/bookings.page.spec.ts new file mode 100644 index 0000000..5f0bf1b --- /dev/null +++ b/src/app/pages/bookings/bookings.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BookingsPage } from './bookings.page'; + +describe('BookingsPage', () => { + let component: BookingsPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(BookingsPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/bookings/bookings.page.ts b/src/app/pages/bookings/bookings.page.ts new file mode 100644 index 0000000..350cb2a --- /dev/null +++ b/src/app/pages/bookings/bookings.page.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-bookings', + templateUrl: './bookings.page.html', + styleUrls: ['./bookings.page.scss'], + standalone: false +}) +export class BookingsPage implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/pages/class-detail/class-detail-routing.module.ts b/src/app/pages/class-detail/class-detail-routing.module.ts new file mode 100644 index 0000000..a3ac572 --- /dev/null +++ b/src/app/pages/class-detail/class-detail-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { ClassDetailPage } from './class-detail.page'; + +const routes: Routes = [ + { + path: '', + component: ClassDetailPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ClassDetailPageRoutingModule {} diff --git a/src/app/pages/class-detail/class-detail.module.ts b/src/app/pages/class-detail/class-detail.module.ts new file mode 100644 index 0000000..49d3eb0 --- /dev/null +++ b/src/app/pages/class-detail/class-detail.module.ts @@ -0,0 +1,17 @@ +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; +import { ClassDetailPageRoutingModule } from './class-detail-routing.module'; +import { ClassDetailPage } from './class-detail.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + ClassDetailPageRoutingModule + ], + declarations: [ClassDetailPage], +}) +export class ClassDetailPageModule {} diff --git a/src/app/pages/class-detail/class-detail.page.html b/src/app/pages/class-detail/class-detail.page.html new file mode 100644 index 0000000..2ccb178 --- /dev/null +++ b/src/app/pages/class-detail/class-detail.page.html @@ -0,0 +1,79 @@ + + + + + + Detalle de Clase + + + + +
+ +

Cargando información...

+
+ +
+ + + + + {{ gymClass.category }} + {{ gymClass.name }} + Instructor: {{ gymClass.instructor }} + + + +

{{ gymClass.description }}

+ + + + + +

Horario

+

{{ gymClass.startTime | date:'EEEE, d MMM, h:mm a' }} - {{ gymClass.endTime | date:'h:mm a' }}

+
+
+ + + + +

Capacidad

+

{{ gymClass.currentBookings }}/{{ gymClass.maxCapacity }} plazas ocupadas

+ +
+
+
+
+
+ +
+ + + Reservar Plaza + + + +

Lo sentimos, esta clase está completa.

+
+
+
+ + + + + + + + + + + + + + + + + +
diff --git a/src/app/pages/class-detail/class-detail.page.scss b/src/app/pages/class-detail/class-detail.page.scss new file mode 100644 index 0000000..0a4c698 --- /dev/null +++ b/src/app/pages/class-detail/class-detail.page.scss @@ -0,0 +1,9 @@ +.class-image { + height: 200px; + object-fit: cover; + } + + ion-progress-bar { + margin-top: 8px; + } + \ No newline at end of file diff --git a/src/app/pages/class-detail/class-detail.page.spec.ts b/src/app/pages/class-detail/class-detail.page.spec.ts new file mode 100644 index 0000000..cca4116 --- /dev/null +++ b/src/app/pages/class-detail/class-detail.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ClassDetailPage } from './class-detail.page'; + +describe('ClassDetailPage', () => { + let component: ClassDetailPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(ClassDetailPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/class-detail/class-detail.page.ts b/src/app/pages/class-detail/class-detail.page.ts new file mode 100644 index 0000000..fc73db1 --- /dev/null +++ b/src/app/pages/class-detail/class-detail.page.ts @@ -0,0 +1,150 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { NavController, ToastController, AlertController } from '@ionic/angular'; +import { GymClass } from '../../models/gym-class.model'; +import { ClassesService } from '../../services/classes.service'; +import { BookingsService } from '../../services/bookings.service'; + +@Component({ + selector: 'app-class-detail', + templateUrl: './class-detail.page.html', + styleUrls: ['./class-detail.page.scss'], + standalone: false +}) +export class ClassDetailPage implements OnInit { + gymClass?: GymClass; + cargando = true; + reservando = false; + + constructor( + private route: ActivatedRoute, + private navCtrl: NavController, + private classesService: ClassesService, + private bookingsService: BookingsService, + private toastCtrl: ToastController, + private alertCtrl: AlertController + ) { } + + ngOnInit() { + this.cargarDatosClase(); + } + + ionViewWillEnter() { + this.cargarDatosClase(); + } + + cargarDatosClase() { + const id = this.route.snapshot.paramMap.get('id'); + if (!id) { + this.navCtrl.navigateBack('/tabs/classes'); + return; + } + + this.cargando = true; + this.classesService.getClassById(id).subscribe({ + next: (gymClass) => { + if (gymClass) { + this.gymClass = gymClass; + } else { + this.navCtrl.navigateBack('/tabs/classes'); + this.mostrarToast('Clase no encontrada', 'danger'); + } + this.cargando = false; + }, + error: (error) => { + console.error('Error al cargar clase', error); + this.cargando = false; + this.navCtrl.navigateBack('/tabs/classes'); + this.mostrarToast('Error al cargar la información', 'danger'); + } + }); + } + + isClassFull(): boolean { + if (!this.gymClass) return true; + return this.gymClass.currentBookings >= this.gymClass.maxCapacity; + } + + getCapacityColor(): string { + if (!this.gymClass) return 'primary'; + + const ratio = this.gymClass.currentBookings / this.gymClass.maxCapacity; + + if (ratio >= 0.9) return 'danger'; + if (ratio >= 0.7) return 'warning'; + return 'success'; + } + + async reservarClase() { + if (!this.gymClass || this.isClassFull() || this.reservando) return; + + this.reservando = true; + + this.bookingsService.addBooking(this.gymClass.id, this.gymClass.name).subscribe({ + next: async (booking) => { + this.mostrarToast(`¡Reserva confirmada para ${this.gymClass?.name}!`, 'success'); + + // Actualizar contador de la clase en local para UX + if (this.gymClass) { + this.gymClass.currentBookings++; + } + + this.reservando = false; + + // Mostrar alerta de confirmación + const alert = await this.alertCtrl.create({ + header: '¡Reserva Exitosa!', + message: `Has reservado una plaza para ${this.gymClass?.name}. ¿Deseas ver tus reservas?`, + buttons: [ + { + text: 'No, seguir explorando', + role: 'cancel' + }, + { + text: 'Ver Mis Reservas', + handler: () => { + this.navCtrl.navigateForward('/tabs/bookings'); + } + } + ] + }); + + await alert.present(); + }, + error: (error) => { + console.error('Error al reservar', error); + this.mostrarToast('Error al realizar la reserva', 'danger'); + this.reservando = false; + } + }); + } + + async mostrarToast(mensaje: string, color: string = 'primary') { + const toast = await this.toastCtrl.create({ + message: mensaje, + duration: 2000, + position: 'bottom', + color: color + }); + toast.present(); + } + + compartir(medio: string) { + if (!this.gymClass) return; + + const mensaje = `¡He encontrado una clase de ${this.gymClass.name} con ${this.gymClass.instructor}!`; + + switch (medio) { + case 'whatsapp': + // En una app real, integraríamos con el plugin de Social Sharing + this.mostrarToast('Compartiendo por WhatsApp...', 'success'); + break; + case 'twitter': + this.mostrarToast('Compartiendo por Twitter...', 'success'); + break; + case 'email': + this.mostrarToast('Compartiendo por Email...', 'success'); + break; + } + } +} diff --git a/src/app/pages/classes/classes-routing.module.ts b/src/app/pages/classes/classes-routing.module.ts new file mode 100644 index 0000000..2cea57b --- /dev/null +++ b/src/app/pages/classes/classes-routing.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { ClassesPage } from './classes.page'; + +const routes: Routes = [ + { + path: '', + component: ClassesPage + }, + { + path: ':id', + loadChildren: () => import('../class-detail/class-detail.module').then(m => m.ClassDetailPageModule) + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ClassesPageRoutingModule {} diff --git a/src/app/pages/classes/classes.module.ts b/src/app/pages/classes/classes.module.ts new file mode 100644 index 0000000..4928214 --- /dev/null +++ b/src/app/pages/classes/classes.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; +import { ClassesPageRoutingModule } from './classes-routing.module'; +import { ClassesPage } from './classes.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + ClassesPageRoutingModule + ], + declarations: [ClassesPage], +}) +export class ClassesPageModule {} diff --git a/src/app/pages/classes/classes.page.html b/src/app/pages/classes/classes.page.html new file mode 100644 index 0000000..814e5dc --- /dev/null +++ b/src/app/pages/classes/classes.page.html @@ -0,0 +1,57 @@ + + + Clases Disponibles + + + + + + + + + Todas + + + Mente/Cuerpo + + + Cardio + + + Fuerza + + + +
+ +

Cargando clases...

+
+ + + + + + + +

{{ gymClass.name }}

+

{{ gymClass.startTime | date:'EEE, d MMM, h:mm a' }}

+

{{ gymClass.instructor }}

+ + + {{ gymClass.currentBookings }}/{{ gymClass.maxCapacity }} + +
+ {{ gymClass.category }} +
+
+ + + + + +
+ +

No se encontraron clases

+

Intenta con otros filtros o términos de búsqueda.

+
+
\ No newline at end of file diff --git a/src/app/tab2/tab2.page.scss b/src/app/pages/classes/classes.page.scss similarity index 100% rename from src/app/tab2/tab2.page.scss rename to src/app/pages/classes/classes.page.scss diff --git a/src/app/pages/classes/classes.page.spec.ts b/src/app/pages/classes/classes.page.spec.ts new file mode 100644 index 0000000..2f1db57 --- /dev/null +++ b/src/app/pages/classes/classes.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ClassesPage } from './classes.page'; + +describe('ClassesPage', () => { + let component: ClassesPage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(ClassesPage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/classes/classes.page.ts b/src/app/pages/classes/classes.page.ts new file mode 100644 index 0000000..b0f126d --- /dev/null +++ b/src/app/pages/classes/classes.page.ts @@ -0,0 +1,93 @@ +import { Component, OnInit } from '@angular/core'; +import { GymClass } from '../../models/gym-class.model'; +import { ClassesService } from '../../services/classes.service'; + +@Component({ + selector: 'app-classes', + templateUrl: './classes.page.html', + styleUrls: ['./classes.page.scss'], + standalone: false +}) +export class ClassesPage implements OnInit { + clases: GymClass[] = []; + clasesFiltradas: GymClass[] = []; + cargando = true; + terminoBusqueda = ''; + categoriaSeleccionada = 'todas'; + + constructor(private classesService: ClassesService) { } + + ngOnInit() { + this.cargarClases(); + } + + ionViewWillEnter() { + this.cargarClases(); + } + + cargarClases() { + this.cargando = true; + this.classesService.getClasses().subscribe({ + next: (classes) => { + this.clases = classes; + this.aplicarFiltros(); + this.cargando = false; + }, + error: (error) => { + console.error('Error al cargar clases', error); + this.cargando = false; + } + }); + } + + refrescarClases(event: any) { + this.classesService.getClasses().subscribe({ + next: (classes) => { + this.clases = classes; + this.aplicarFiltros(); + event.target.complete(); + }, + error: (error) => { + console.error('Error al refrescar clases', error); + event.target.complete(); + } + }); + } + + buscarClases(event: any) { + this.terminoBusqueda = event.detail.value.toLowerCase(); + this.aplicarFiltros(); + } + + filtrarPorCategoria(event: any) { + this.categoriaSeleccionada = event.detail.value; + this.aplicarFiltros(); + } + + private aplicarFiltros() { + let resultado = [...this.clases]; + + // Filtrar por término de búsqueda + if (this.terminoBusqueda) { + resultado = resultado.filter(clase => + clase.name.toLowerCase().includes(this.terminoBusqueda) || + clase.instructor.toLowerCase().includes(this.terminoBusqueda) || + clase.description.toLowerCase().includes(this.terminoBusqueda) + ); + } + + // Filtrar por categoría + if (this.categoriaSeleccionada !== 'todas') { + resultado = resultado.filter(clase => + clase.category === this.categoriaSeleccionada + ); + } + + // Ordenar por fecha/hora + resultado.sort((a, b) => { + return a.startTime.getTime() - b.startTime.getTime(); + }); + + this.clasesFiltradas = resultado; + } +} \ No newline at end of file diff --git a/src/app/pages/profile/profile-routing.module.ts b/src/app/pages/profile/profile-routing.module.ts new file mode 100644 index 0000000..a7052f8 --- /dev/null +++ b/src/app/pages/profile/profile-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { ProfilePage } from './profile.page'; + +const routes: Routes = [ + { + path: '', + component: ProfilePage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class ProfilePageRoutingModule {} diff --git a/src/app/pages/profile/profile.module.ts b/src/app/pages/profile/profile.module.ts new file mode 100644 index 0000000..12250e0 --- /dev/null +++ b/src/app/pages/profile/profile.module.ts @@ -0,0 +1,20 @@ +import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { IonicModule } from '@ionic/angular'; + +import { ProfilePageRoutingModule } from './profile-routing.module'; + +import { ProfilePage } from './profile.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + ProfilePageRoutingModule + ], + declarations: [ProfilePage] +}) +export class ProfilePageModule {} diff --git a/src/app/tab3/tab3.page.html b/src/app/pages/profile/profile.page.html similarity index 57% rename from src/app/tab3/tab3.page.html rename to src/app/pages/profile/profile.page.html index 222333d..d5d735e 100644 --- a/src/app/tab3/tab3.page.html +++ b/src/app/pages/profile/profile.page.html @@ -1,17 +1,13 @@ - - Tab 3 - + profile - Tab 3 + profile - - diff --git a/src/app/tab3/tab3.page.scss b/src/app/pages/profile/profile.page.scss similarity index 100% rename from src/app/tab3/tab3.page.scss rename to src/app/pages/profile/profile.page.scss diff --git a/src/app/pages/profile/profile.page.spec.ts b/src/app/pages/profile/profile.page.spec.ts new file mode 100644 index 0000000..052dbe6 --- /dev/null +++ b/src/app/pages/profile/profile.page.spec.ts @@ -0,0 +1,17 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ProfilePage } from './profile.page'; + +describe('ProfilePage', () => { + let component: ProfilePage; + let fixture: ComponentFixture; + + beforeEach(() => { + fixture = TestBed.createComponent(ProfilePage); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/profile/profile.page.ts b/src/app/pages/profile/profile.page.ts new file mode 100644 index 0000000..ef5b2ec --- /dev/null +++ b/src/app/pages/profile/profile.page.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-profile', + templateUrl: './profile.page.html', + styleUrls: ['./profile.page.scss'], + standalone: false +}) +export class ProfilePage implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/services/auth.service.spec.ts b/src/app/services/auth.service.spec.ts new file mode 100644 index 0000000..f1251ca --- /dev/null +++ b/src/app/services/auth.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + let service: AuthService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(AuthService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts new file mode 100644 index 0000000..fac6c5e --- /dev/null +++ b/src/app/services/auth.service.ts @@ -0,0 +1,66 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable, of } from 'rxjs'; +import { delay, tap } from 'rxjs/operators'; +import { User } from '../models/user.model'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + private currentUserSubject = new BehaviorSubject(null); + public currentUser$ = this.currentUserSubject.asObservable(); + + // Usuario de demostración + private demoUser: User = { + id: 'user123', + name: 'Usuario Demo', + email: 'usuario@ejemplo.com', + preferences: { + notifications: true + } + }; + + constructor() { + // Simular usuario ya autenticado para el taller + this.currentUserSubject.next(this.demoUser); + } + + getCurrentUser(): User | null { + return this.currentUserSubject.value; + } + + // Simulación de login + login(email: string, password: string): Observable { + // En una app real, aquí se realizaría la autenticación contra un backend + return of(this.demoUser).pipe( + delay(1000), // Simular latencia de red + tap(user => this.currentUserSubject.next(user)) + ); + } + + // Simulación de logout + logout(): Observable { + return of(true).pipe( + delay(500), // Simular latencia de red + tap(() => this.currentUserSubject.next(null)) + ); + } + + // Simulación de actualización de perfil + updateUserProfile(userData: Partial): Observable { + const currentUser = this.getCurrentUser(); + if (!currentUser) { + return of(this.demoUser); + } + + const updatedUser: User = { + ...currentUser, + ...userData + }; + + return of(updatedUser).pipe( + delay(800), // Simular latencia de red + tap(user => this.currentUserSubject.next(user)) + ); + } +} \ No newline at end of file diff --git a/src/app/services/bookings.service.spec.ts b/src/app/services/bookings.service.spec.ts new file mode 100644 index 0000000..11749a5 --- /dev/null +++ b/src/app/services/bookings.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { BookingsService } from './bookings.service'; + +describe('BookingsService', () => { + let service: BookingsService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(BookingsService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/bookings.service.ts b/src/app/services/bookings.service.ts new file mode 100644 index 0000000..0121379 --- /dev/null +++ b/src/app/services/bookings.service.ts @@ -0,0 +1,124 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable, from, of } from 'rxjs'; +import { map, switchMap, tap } from 'rxjs/operators'; +import { Booking } from '../models/booking.model'; +import { StorageService } from './storage.service'; +import { ClassesService } from './classes.service'; + +@Injectable({ + providedIn: 'root' +}) +export class BookingsService { + private STORAGE_KEY = 'bookings'; + private bookingsSubject = new BehaviorSubject([]); + public bookings$ = this.bookingsSubject.asObservable(); + private initialized = false; + private userId = 'user123'; // En una app real, vendría de la autenticación + + constructor( + private storageService: StorageService, + private classesService: ClassesService + ) { + this.init(); + } + + private async init() { + if (this.initialized) return; + + const storedBookings = await this.storageService.get(this.STORAGE_KEY); + + if (storedBookings) { + // Convertir las fechas de string a objetos Date + const bookings = storedBookings.map((booking: any) => ({ + ...booking, + date: new Date(booking.date) + })); + this.bookingsSubject.next(bookings); + } else { + this.bookingsSubject.next([]); + await this.storageService.set(this.STORAGE_KEY, []); + } + + this.initialized = true; + } + + getUserBookings(): Observable { + return from(this.ensureInitialized()).pipe( + switchMap(() => this.bookings$), + map(bookings => bookings.filter(booking => booking.userId === this.userId)) + ); + } + + addBooking(classId: string, className: string): Observable { + return from(this.ensureInitialized()).pipe( + switchMap(() => { + // Actualizar el contador de reservas de la clase + return this.classesService.updateClassBookings(classId, 1).pipe( + switchMap(success => { + if (!success) { + throw new Error('No se pudo actualizar la clase'); + } + + const newBooking: Booking = { + id: Date.now().toString(), + userId: this.userId, + classId, + className, + date: new Date(), + status: 'confirmed' + }; + + const currentBookings = this.bookingsSubject.value; + const updatedBookings = [...currentBookings, newBooking]; + + return from(this.storageService.set(this.STORAGE_KEY, updatedBookings)).pipe( + tap(() => this.bookingsSubject.next(updatedBookings)), + map(() => newBooking) + ); + }) + ); + }) + ); + } + + cancelBooking(bookingId: string): Observable { + return from(this.ensureInitialized()).pipe( + switchMap(() => { + const currentBookings = this.bookingsSubject.value; + const index = currentBookings.findIndex(b => b.id === bookingId); + + if (index === -1) return of(false); + + const booking = currentBookings[index]; + + // No permitir cancelar reservas ya canceladas + if (booking.status === 'cancelled') return of(false); + + // Crear copia actualizada + const updatedBooking = { ...booking, status: 'cancelled' as 'cancelled' }; + const updatedBookings = [...currentBookings]; + updatedBookings[index] = updatedBooking; + + // Actualizar contador de clase + return this.classesService.updateClassBookings(booking.classId, -1).pipe( + switchMap(success => { + if (!success) { + return of(false); + } + + return from(this.storageService.set(this.STORAGE_KEY, updatedBookings)).pipe( + tap(() => this.bookingsSubject.next(updatedBookings)), + map(() => true) + ); + }) + ); + }) + ); + } + + private async ensureInitialized(): Promise { + if (!this.initialized) { + await this.init(); + } + } +} \ No newline at end of file diff --git a/src/app/services/classes.service.spec.ts b/src/app/services/classes.service.spec.ts new file mode 100644 index 0000000..68ef898 --- /dev/null +++ b/src/app/services/classes.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ClassesService } from './classes.service'; + +describe('ClassesService', () => { + let service: ClassesService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ClassesService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/classes.service.ts b/src/app/services/classes.service.ts new file mode 100644 index 0000000..8023ec4 --- /dev/null +++ b/src/app/services/classes.service.ts @@ -0,0 +1,155 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable, from, of } from 'rxjs'; +import { map, switchMap, tap } from 'rxjs/operators'; +import { GymClass } from '../models/gym-class.model'; +import { StorageService } from './storage.service'; + +@Injectable({ + providedIn: 'root' +}) +export class ClassesService { + private STORAGE_KEY = 'gym_classes'; + private classesSubject = new BehaviorSubject([]); + public classes$ = this.classesSubject.asObservable(); + private initialized = false; + + // Datos iniciales para mock + private initialClasses: GymClass[] = [ + { + id: '1', + name: 'Yoga', + description: 'Clase de yoga para todos los niveles', + instructor: 'María López', + startTime: new Date('2025-04-24T08:00:00'), + endTime: new Date('2025-04-24T09:00:00'), + maxCapacity: 15, + currentBookings: 8, + category: 'Mente y Cuerpo', + imageUrl: 'https://cdn-icons-png.flaticon.com/512/3456/3456464.png' + }, + { + id: '2', + name: 'Spinning', + description: 'Clase de alta intensidad de ciclismo estático', + instructor: 'Juan Pérez', + startTime: new Date('2025-04-24T10:00:00'), + endTime: new Date('2025-04-24T11:00:00'), + maxCapacity: 20, + currentBookings: 15, + category: 'Cardiovascular', + imageUrl: 'https://cdn-icons-png.flaticon.com/512/805/805504.png' + }, + { + id: '3', + name: 'Pilates (Pesas de agarre)', + description: 'Fortalecimiento de core y flexibilidad', + instructor: 'Ana García', + startTime: new Date('2025-04-24T16:00:00'), + endTime: new Date('2025-04-24T17:00:00'), + maxCapacity: 12, + currentBookings: 5, + category: 'Mente y Cuerpo', + imageUrl: 'https://cdn-icons-png.flaticon.com/512/625/625454.png' + }, + { + id: '4', + name: 'Zumba', + description: 'Baile y ejercicio cardiovascular', + instructor: 'Carlos Martínez', + startTime: new Date('2025-04-25T18:00:00'), + endTime: new Date('2025-04-25T19:00:00'), + maxCapacity: 25, + currentBookings: 18, + category: 'Baile', + imageUrl: 'https://cdn-icons-png.flaticon.com/512/5776/5776440.png' + }, + { + id: '5', + name: 'CrossFit', + description: 'Entrenamiento funcional de alta intensidad', + instructor: 'Roberto Sánchez', + startTime: new Date('2025-04-25T09:00:00'), + endTime: new Date('2025-04-25T10:00:00'), + maxCapacity: 15, + currentBookings: 12, + category: 'Fuerza', + imageUrl: 'https://cdn-icons-png.flaticon.com/512/372/372612.png' + } + ]; + + constructor(private storageService: StorageService) { + this.init(); + } + + private async init() { + if (this.initialized) return; + + // Intentar cargar datos desde almacenamiento + const storedClasses = await this.storageService.get(this.STORAGE_KEY); + + if (storedClasses && storedClasses.length > 0) { + // Convertir las fechas de string a objetos Date + const classes = storedClasses.map((cls: any) => ({ + ...cls, + startTime: new Date(cls.startTime), + endTime: new Date(cls.endTime) + })); + this.classesSubject.next(classes); + } else { + // Si no hay datos almacenados, usar datos iniciales + await this.storageService.set(this.STORAGE_KEY, this.initialClasses); + this.classesSubject.next(this.initialClasses); + } + + this.initialized = true; + } + + getClasses(): Observable { + return from(this.ensureInitialized()).pipe( + switchMap(() => this.classes$) + ); + } + + getClassById(id: string): Observable { + return this.getClasses().pipe( + map(classes => classes.find(c => c.id === id)) + ); + } + + updateClassBookings(classId: string, change: number): Observable { + return from(this.ensureInitialized()).pipe( + switchMap(() => { + const currentClasses = this.classesSubject.value; + const index = currentClasses.findIndex(c => c.id === classId); + + if (index === -1) return of(false); + + const updatedClass = { ...currentClasses[index] }; + updatedClass.currentBookings += change; + + // Verificar límites + if (updatedClass.currentBookings < 0) { + updatedClass.currentBookings = 0; + } + + if (updatedClass.currentBookings > updatedClass.maxCapacity) { + return of(false); + } + + const updatedClasses = [...currentClasses]; + updatedClasses[index] = updatedClass; + + return from(this.storageService.set(this.STORAGE_KEY, updatedClasses)).pipe( + tap(() => this.classesSubject.next(updatedClasses)), + map(() => true) + ); + }) + ); + } + + private async ensureInitialized(): Promise { + if (!this.initialized) { + await this.init(); + } + } +} \ No newline at end of file diff --git a/src/app/services/storage.service.spec.ts b/src/app/services/storage.service.spec.ts new file mode 100644 index 0000000..e7fe5b5 --- /dev/null +++ b/src/app/services/storage.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { StorageService } from './storage.service'; + +describe('StorageService', () => { + let service: StorageService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(StorageService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/storage.service.ts b/src/app/services/storage.service.ts new file mode 100644 index 0000000..4b008dc --- /dev/null +++ b/src/app/services/storage.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { Preferences } from '@capacitor/preferences'; + +@Injectable({ + providedIn: 'root' +}) +export class StorageService { + + constructor() { } + + async set(key: string, value: any): Promise { + await Preferences.set({ + key, + value: JSON.stringify(value) + }); + } + + async get(key: string): Promise { + const { value } = await Preferences.get({ key }); + + if (value) { + return JSON.parse(value); + } + + return null; + } + + async remove(key: string): Promise { + await Preferences.remove({ key }); + } + + async clear(): Promise { + await Preferences.clear(); + } +} diff --git a/src/app/tab1/tab1-routing.module.ts b/src/app/tab1/tab1-routing.module.ts deleted file mode 100644 index 8c1cf5b..0000000 --- a/src/app/tab1/tab1-routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { Tab1Page } from './tab1.page'; - -const routes: Routes = [ - { - path: '', - component: Tab1Page, - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class Tab1PageRoutingModule {} diff --git a/src/app/tab1/tab1.module.ts b/src/app/tab1/tab1.module.ts deleted file mode 100644 index 135eeae..0000000 --- a/src/app/tab1/tab1.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IonicModule } from '@ionic/angular'; -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { Tab1Page } from './tab1.page'; -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab1PageRoutingModule } from './tab1-routing.module'; - -@NgModule({ - imports: [ - IonicModule, - CommonModule, - FormsModule, - ExploreContainerComponentModule, - Tab1PageRoutingModule - ], - declarations: [Tab1Page] -}) -export class Tab1PageModule {} diff --git a/src/app/tab1/tab1.page.html b/src/app/tab1/tab1.page.html deleted file mode 100644 index 22e11e4..0000000 --- a/src/app/tab1/tab1.page.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - Tab 1 - - - - - - - - Tab 1 - - - - - diff --git a/src/app/tab1/tab1.page.spec.ts b/src/app/tab1/tab1.page.spec.ts deleted file mode 100644 index 0dbb7c0..0000000 --- a/src/app/tab1/tab1.page.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; - -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab1Page } from './tab1.page'; - -describe('Tab1Page', () => { - let component: Tab1Page; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Tab1Page], - imports: [IonicModule.forRoot(), ExploreContainerComponentModule] - }).compileComponents(); - - fixture = TestBed.createComponent(Tab1Page); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/tab1/tab1.page.ts b/src/app/tab1/tab1.page.ts deleted file mode 100644 index e52fddb..0000000 --- a/src/app/tab1/tab1.page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-tab1', - templateUrl: 'tab1.page.html', - styleUrls: ['tab1.page.scss'], - standalone: false, -}) -export class Tab1Page { - - constructor() {} - -} diff --git a/src/app/tab2/tab2-routing.module.ts b/src/app/tab2/tab2-routing.module.ts deleted file mode 100644 index e96ec09..0000000 --- a/src/app/tab2/tab2-routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { Tab2Page } from './tab2.page'; - -const routes: Routes = [ - { - path: '', - component: Tab2Page, - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class Tab2PageRoutingModule {} diff --git a/src/app/tab2/tab2.module.ts b/src/app/tab2/tab2.module.ts deleted file mode 100644 index 723bac1..0000000 --- a/src/app/tab2/tab2.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IonicModule } from '@ionic/angular'; -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { Tab2Page } from './tab2.page'; -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab2PageRoutingModule } from './tab2-routing.module'; - -@NgModule({ - imports: [ - IonicModule, - CommonModule, - FormsModule, - ExploreContainerComponentModule, - Tab2PageRoutingModule - ], - declarations: [Tab2Page] -}) -export class Tab2PageModule {} diff --git a/src/app/tab2/tab2.page.spec.ts b/src/app/tab2/tab2.page.spec.ts deleted file mode 100644 index 70bd876..0000000 --- a/src/app/tab2/tab2.page.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; - -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab2Page } from './tab2.page'; - -describe('Tab2Page', () => { - let component: Tab2Page; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Tab2Page], - imports: [IonicModule.forRoot(), ExploreContainerComponentModule] - }).compileComponents(); - - fixture = TestBed.createComponent(Tab2Page); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/tab2/tab2.page.ts b/src/app/tab2/tab2.page.ts deleted file mode 100644 index 520c45b..0000000 --- a/src/app/tab2/tab2.page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-tab2', - templateUrl: 'tab2.page.html', - styleUrls: ['tab2.page.scss'], - standalone: false, -}) -export class Tab2Page { - - constructor() {} - -} diff --git a/src/app/tab3/tab3-routing.module.ts b/src/app/tab3/tab3-routing.module.ts deleted file mode 100644 index 5d6abde..0000000 --- a/src/app/tab3/tab3-routing.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { Tab3Page } from './tab3.page'; - -const routes: Routes = [ - { - path: '', - component: Tab3Page, - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class Tab3PageRoutingModule {} diff --git a/src/app/tab3/tab3.module.ts b/src/app/tab3/tab3.module.ts deleted file mode 100644 index 2599fc6..0000000 --- a/src/app/tab3/tab3.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { IonicModule } from '@ionic/angular'; -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { Tab3Page } from './tab3.page'; -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab3PageRoutingModule } from './tab3-routing.module'; - -@NgModule({ - imports: [ - IonicModule, - CommonModule, - FormsModule, - ExploreContainerComponentModule, - Tab3PageRoutingModule - ], - declarations: [Tab3Page] -}) -export class Tab3PageModule {} diff --git a/src/app/tab3/tab3.page.spec.ts b/src/app/tab3/tab3.page.spec.ts deleted file mode 100644 index 28d8619..0000000 --- a/src/app/tab3/tab3.page.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; - -import { ExploreContainerComponentModule } from '../explore-container/explore-container.module'; - -import { Tab3Page } from './tab3.page'; - -describe('Tab3Page', () => { - let component: Tab3Page; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [Tab3Page], - imports: [IonicModule.forRoot(), ExploreContainerComponentModule] - }).compileComponents(); - - fixture = TestBed.createComponent(Tab3Page); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/tab3/tab3.page.ts b/src/app/tab3/tab3.page.ts deleted file mode 100644 index 8c63559..0000000 --- a/src/app/tab3/tab3.page.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'app-tab3', - templateUrl: 'tab3.page.html', - styleUrls: ['tab3.page.scss'], - standalone: false, -}) -export class Tab3Page { - - constructor() {} - -} diff --git a/src/app/tabs/tabs-routing.module.ts b/src/app/tabs/tabs-routing.module.ts index 770e87e..4225b63 100644 --- a/src/app/tabs/tabs-routing.module.ts +++ b/src/app/tabs/tabs-routing.module.ts @@ -8,27 +8,27 @@ const routes: Routes = [ component: TabsPage, children: [ { - path: 'tab1', - loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule) + path: 'classes', + loadChildren: () => import('../pages/classes/classes.module').then(m => m.ClassesPageModule) }, { - path: 'tab2', - loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule) + path: 'bookings', + loadChildren: () => import('../pages/bookings/bookings.module').then(m => m.BookingsPageModule) }, { - path: 'tab3', - loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule) + path: 'profile', + loadChildren: () => import('../pages/profile/profile.module').then(m => m.ProfilePageModule) }, { path: '', - redirectTo: '/tabs/tab1', + redirectTo: '/tabs/classes', pathMatch: 'full' } ] }, { path: '', - redirectTo: '/tabs/tab1', + redirectTo: '/tabs/classes', pathMatch: 'full' } ]; @@ -36,4 +36,4 @@ const routes: Routes = [ @NgModule({ imports: [RouterModule.forChild(routes)], }) -export class TabsPageRoutingModule {} +export class TabsPageRoutingModule {} \ No newline at end of file diff --git a/src/app/tabs/tabs.page.html b/src/app/tabs/tabs.page.html index ae0aceb..1afb0e5 100644 --- a/src/app/tabs/tabs.page.html +++ b/src/app/tabs/tabs.page.html @@ -1,20 +1,18 @@ - - - - Tab 1 + + + Clases - - - - Tab 2 + + + + Mis Reservas - - - - Tab 3 + + + + Perfil -