feat: Reportes, chat de discusión y mejoras de navegación

- Tab "Reportados" en Contratos (cliente) y tab "Reportadas" en Postulaciones (proveedor) con skeleton loading e ionViewWillEnter
- Modal de chat para discusión de reportes: burbujas por rol (propio/otro/moderador), skeleton, input con cámara y envío
- Endpoints GET/POST contracts/reports/{id}/comments en ichamba.service
- userId guardado en AuthService desde auth/user para identificar mensajes propios
- Botón "Postularse" corregido con slot=end en ion-item
- Todas las secciones de tabs migradas de ngOnInit a ionViewWillEnter + ChangeDetectorRef.detectChanges()
- Android navigation bar reactiva al tema del sistema vía values/values-night styles.xml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 21:05:24 -06:00
parent aa8b0061c9
commit c677fdcb59
34 changed files with 901 additions and 102 deletions

View File

@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, ChangeDetectorRef } from '@angular/core';
import { MenuController, NavController } from '@ionic/angular';
import { EventService } from '../../../services/event.service';
import { EnvService } from 'src/app/services/env.service';
@@ -13,10 +13,11 @@ import { Browser } from '@capacitor/browser';
styleUrls: ['./already.page.scss'],
standalone: false
})
export class AlreadyPage implements OnInit {
export class AlreadyPage {
postulations: any[] = [];
postulations_dates: any[] = [];
loading = true;
constructor(
private menu: MenuController,
@@ -26,13 +27,15 @@ export class AlreadyPage implements OnInit {
private alertService: AlertService,
private ichambaService: IchambaService,
private env: EnvService,
private cdr: ChangeDetectorRef,
) {
this.events.subscribe('refreshpostulations', (data) => {
this.getpostulations();
});
}
ngOnInit() {
ionViewWillEnter() {
this.loading = true;
this.getpostulations();
}
@@ -40,9 +43,11 @@ export class AlreadyPage implements OnInit {
this.ichambaService.getContractedPostulation().subscribe(
data => {
this.postulations = data;
this.postulations_dates = [];
for (var i of this.postulations) {
this.postulations_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('es-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'}));
this.postulations_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString('es-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'long' }));
}
this.cdr.detectChanges();
event.target.complete();
}, error => {
this.alertService.presentToast("Por favor contacte a soporte técnico, Estatus:" + error['status']);
@@ -54,10 +59,14 @@ export class AlreadyPage implements OnInit {
this.ichambaService.getContractedPostulation().subscribe(
data => {
this.postulations = data;
this.postulations_dates = [];
for (var i of this.postulations) {
this.postulations_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('es-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'}));
this.postulations_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString('es-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'long' }));
}
this.loading = false;
this.cdr.detectChanges();
}, error => {
this.loading = false;
this.alertService.presentToast("Por favor contacte a soporte técnico, Estatus:" + error['status']);
});
}