- Sistema de propiedades: modal add-property con autocomplete y selector de ícono - category.page rediseñado: selector de propiedad, fotos (Capacitor Camera), sin fecha/precio - Modal postulate-offer: proveedor propone 2 fechas requeridas + monto con validación de cuota mínima - viewsuppliers: chips de ordenamiento frontend (fecha, precio, certificados) - hire.page: selección de fecha (date_1/date_2) antes de contratar; selected_date en contracts/create y contracts/coupon - Modal contract-discussion: chat de burbujas para contratos activos - contracted.page: botón de chat por contrato - pending.page: botones cancelar y repostular por postulación - Modal repostulate: pre-llena categoría/propiedad, archiva original como perdido y crea nueva con related_postulation_id - current.page: temporizador de expiración basado en time_created (1000 min), oculta expiradas - ichamba.service: nuevos métodos properties, cancelPostulation, contractDiscussion, updated signatures Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
130 lines
4.5 KiB
TypeScript
Executable File
130 lines
4.5 KiB
TypeScript
Executable File
import { Component, ChangeDetectorRef } from '@angular/core';
|
|
import { AlertController, ModalController, MenuController, NavController } from '@ionic/angular';
|
|
import { EventService } from '../../../services/event.service';
|
|
import { EnvService } from 'src/app/services/env.service';
|
|
import { AuthService } from 'src/app/services/auth.service';
|
|
import { IchambaService } from 'src/app/services/ichamba.service';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { LanguageService } from 'src/app/services/language.service';
|
|
import { AlertService } from 'src/app/services/alert.service';
|
|
import { RepostulateePage } from '../../postulations/repostulate/repostulate.page';
|
|
|
|
@Component({
|
|
selector: 'app-pending',
|
|
templateUrl: './pending.page.html',
|
|
styleUrls: ['./pending.page.scss'],
|
|
standalone: false
|
|
})
|
|
export class PendingPage {
|
|
|
|
pcontracts: any[] = [];
|
|
pcontracts_dates: any[] = [];
|
|
lang: boolean = false;
|
|
loading = true;
|
|
|
|
constructor(
|
|
private modalController: ModalController,
|
|
private alertController: AlertController,
|
|
private menu: MenuController,
|
|
private navCtrl: NavController,
|
|
private events: EventService,
|
|
private authService: AuthService,
|
|
private alertService: AlertService,
|
|
private ichambaService: IchambaService,
|
|
private translateService: TranslateService,
|
|
private languageService: LanguageService,
|
|
private env: EnvService,
|
|
private cdr: ChangeDetectorRef,
|
|
) {
|
|
this.events.subscribe('refreshpcontracts', (data) => {
|
|
this.getpcontracts();
|
|
});
|
|
}
|
|
|
|
ionViewWillEnter() {
|
|
this.lang = this.languageService.getDefaultLanguage() === 'es';
|
|
this.loading = true;
|
|
this.getpcontracts();
|
|
}
|
|
|
|
refresh(event: any) {
|
|
this.ichambaService.getPendingcontracts().subscribe(
|
|
data => {
|
|
this.pcontracts = data;
|
|
this.pcontracts_dates = [];
|
|
for (var i of this.pcontracts) {
|
|
const locale = this.lang ? 'es-US' : 'en-US';
|
|
this.pcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString(locale, { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'long' }));
|
|
}
|
|
this.cdr.detectChanges();
|
|
event.target.complete();
|
|
}, error => {
|
|
this.alertService.presentToast(this.translateService.instant('alerts.error') + error['status']);
|
|
event.target.complete();
|
|
});
|
|
}
|
|
|
|
getpcontracts() {
|
|
this.ichambaService.getPendingcontracts().subscribe(
|
|
data => {
|
|
this.pcontracts = data;
|
|
this.pcontracts_dates = [];
|
|
for (var i of this.pcontracts) {
|
|
const locale = this.lang ? 'es-US' : 'en-US';
|
|
this.pcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString(locale, { 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(this.translateService.instant('alerts.error') + error['status']);
|
|
});
|
|
}
|
|
|
|
viewsuppliers(postulation_id: String) {
|
|
this.navCtrl.navigateForward(['/viewsuppliers/', postulation_id]);
|
|
}
|
|
|
|
async confirmCancel(postulation: any) {
|
|
const alert = await this.alertController.create({
|
|
header: 'Cancelar postulación',
|
|
message: ' ',
|
|
buttons: [
|
|
{ text: 'No', role: 'cancel' },
|
|
{
|
|
text: 'Sí, cancelar',
|
|
role: 'destructive',
|
|
handler: () => this.doCancel(postulation.id)
|
|
}
|
|
]
|
|
});
|
|
await alert.present();
|
|
alert.querySelector('.alert-message')!.innerHTML = '¿Estás seguro de que deseas cancelar esta postulación de <strong>' + postulation.category + '</strong>?';
|
|
}
|
|
|
|
private doCancel(id: any) {
|
|
this.ichambaService.cancelPostulation(id).subscribe({
|
|
next: () => {
|
|
this.alertService.presentToast('Postulación cancelada.');
|
|
this.getpcontracts();
|
|
},
|
|
error: (error: any) => {
|
|
this.alertService.presentToast('Error al cancelar: ' + error['status']);
|
|
}
|
|
});
|
|
}
|
|
|
|
async openRepostulate(postulation: any) {
|
|
const modal = await this.modalController.create({
|
|
component: RepostulateePage,
|
|
componentProps: { postulation },
|
|
});
|
|
await modal.present();
|
|
const { data } = await modal.onDidDismiss();
|
|
if (data?.reposted) {
|
|
this.getpcontracts();
|
|
}
|
|
}
|
|
|
|
}
|