diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..2a90537 --- /dev/null +++ b/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index be874e5..130b104 100755 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -13,6 +13,8 @@ false true @null + #FFFFFF + true diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d2fc54d..bca6972 100755 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -27,7 +27,6 @@ const routes: Routes = [ { path: 'start', loadChildren: () => import('./pages/contracts/start/start.module').then(m => m.StartPageModule), canActivate: [AuthGuard]}, { path: 'review/:contract_id', loadChildren: () => import('./pages/contracts/review/review.module').then(m => m.ReviewPageModule), canActivate: [AuthGuard] }, { path: 'report/:contract_id', loadChildren: () => import('./pages/contracts/report/report.module').then(m => m.ReportPageModule), canActivate: [AuthGuard] }, - { path: 'reports', loadChildren: () => import('./pages/reports/reports.module').then(m => m.ReportsPageModule), canActivate: [AuthGuard]}, { path: 'nohome/:contract_id', loadChildren: () => import('./pages/contracts/nohome/nohome.module').then(m => m.NohomePageModule), canActivate: [AuthGuard] }, { path: 'extra', loadChildren: () => import('./pages/contracts/extra/extra.module').then(m => m.ExtraPageModule), canActivate: [AuthGuard] }, { path: 'ended', loadChildren: () => import('./pages/postulations/ended/ended.module').then(m => m.EndedPageModule), canActivate: [AuthGuard] }, diff --git a/src/app/pages/contracts/contracted/contracted.page.html b/src/app/pages/contracts/contracted/contracted.page.html index 21f8586..4446181 100755 --- a/src/app/pages/contracts/contracted/contracted.page.html +++ b/src/app/pages/contracts/contracted/contracted.page.html @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + @@ -29,4 +47,5 @@ {{'contracts.cancel_1.1' | translate}}
{{'contracts.cancel_1.2' | translate}}
+
diff --git a/src/app/pages/contracts/contracted/contracted.page.ts b/src/app/pages/contracts/contracted/contracted.page.ts index 4525af3..c2f9e2a 100755 --- a/src/app/pages/contracts/contracted/contracted.page.ts +++ b/src/app/pages/contracts/contracted/contracted.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; import { ModalController, MenuController, NavController } from '@ionic/angular'; import { EventService } from '../../../services/event.service'; import { EnvService } from 'src/app/services/env.service'; @@ -15,11 +15,12 @@ import { AlertController } from '@ionic/angular'; styleUrls: ['./contracted.page.scss'], standalone: false }) -export class ContractedPage implements OnInit { +export class ContractedPage { ccontracts: any[] = []; ccontracts_dates: any[] = []; lang: boolean = false; + loading = true; constructor( private modalController: ModalController, @@ -33,32 +34,29 @@ export class ContractedPage implements OnInit { private translateService: TranslateService, private languageService: LanguageService, private env: EnvService, + private cdr: ChangeDetectorRef, ) { this.events.subscribe('refreshccontracts', (data) => { this.getccontracts(); }); } - ngOnInit() { + ionViewWillEnter() { + this.lang = this.languageService.getDefaultLanguage() === 'es'; + this.loading = true; this.getccontracts(); - if (this.languageService.getDefaultLanguage() == 'es') { - this.lang = true; - } else { - this.lang = false - } } refresh(event: any) { this.ichambaService.getCurrentcontracts().subscribe( data => { this.ccontracts = data; + this.ccontracts_dates = []; for (var i of this.ccontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.ccontracts_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'})); - } else { - this.ccontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + const locale = this.lang ? 'es-US' : 'en-US'; + this.ccontracts_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']); @@ -70,14 +68,15 @@ export class ContractedPage implements OnInit { this.ichambaService.getCurrentcontracts().subscribe( data => { this.ccontracts = data; + this.ccontracts_dates = []; for (var i of this.ccontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.ccontracts_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'})); - } else { - this.ccontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + const locale = this.lang ? 'es-US' : 'en-US'; + this.ccontracts_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']); }); } diff --git a/src/app/pages/contracts/contracts.module.ts b/src/app/pages/contracts/contracts.module.ts index 12a917f..91473ba 100755 --- a/src/app/pages/contracts/contracts.module.ts +++ b/src/app/pages/contracts/contracts.module.ts @@ -33,6 +33,10 @@ const routes: Routes = [ { path: 'finished', loadChildren: () => import('./finished/finished.module').then(m => m.FinishedPageModule) + }, + { + path: 'reported', + loadChildren: () => import('../reports/reports.module').then(m => m.ReportsPageModule) } ] } diff --git a/src/app/pages/contracts/contracts.page.html b/src/app/pages/contracts/contracts.page.html index bc85864..7787d7b 100755 --- a/src/app/pages/contracts/contracts.page.html +++ b/src/app/pages/contracts/contracts.page.html @@ -24,5 +24,10 @@ {{'contracts.header_3' | translate}} + + + {{'contracts.header_4' | translate}} + + diff --git a/src/app/pages/contracts/finished/finished.page.html b/src/app/pages/contracts/finished/finished.page.html index 6bfb336..02837fd 100755 --- a/src/app/pages/contracts/finished/finished.page.html +++ b/src/app/pages/contracts/finished/finished.page.html @@ -3,7 +3,7 @@ - {{'contract.header' | translate}} + {{'contracts.header' | translate}} @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + @@ -35,4 +53,5 @@ + diff --git a/src/app/pages/contracts/finished/finished.page.ts b/src/app/pages/contracts/finished/finished.page.ts index d6c33e5..102101d 100755 --- a/src/app/pages/contracts/finished/finished.page.ts +++ b/src/app/pages/contracts/finished/finished.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; import { ReviewPage } from '../review/review.page'; import { ModalController, MenuController, NavController } from '@ionic/angular'; import { EventService } from '../../../services/event.service'; @@ -17,11 +17,12 @@ import { AlertController } from '@ionic/angular'; styleUrls: ['./finished.page.scss'], standalone: false }) -export class FinishedPage implements OnInit { +export class FinishedPage { fcontracts: any[] = []; fcontracts_dates: any[] = []; lang: boolean = false; + loading = true; constructor( private modalController: ModalController, @@ -37,32 +38,29 @@ export class FinishedPage implements OnInit { private translateService: TranslateService, private languageService: LanguageService, private env: EnvService, + private cdr: ChangeDetectorRef, ) { this.events.subscribe('refreshccontracts', (data) => { this.getfcontracts(); }); } - ngOnInit() { + ionViewWillEnter() { + this.lang = this.languageService.getDefaultLanguage() === 'es'; + this.loading = true; this.getfcontracts(); - if (this.languageService.getDefaultLanguage() == 'es') { - this.lang = true; - } else { - this.lang = false - } } refresh(event: any) { this.ichambaService.getFinishedcontracts().subscribe( data => { this.fcontracts = data; + this.fcontracts_dates = []; for (var i of this.fcontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.fcontracts_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'})); - } else { - this.fcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + const locale = this.lang ? 'es-US' : 'en-US'; + this.fcontracts_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']); @@ -74,14 +72,15 @@ export class FinishedPage implements OnInit { this.ichambaService.getFinishedcontracts().subscribe( data => { this.fcontracts = data; + this.fcontracts_dates = []; for (var i of this.fcontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.fcontracts_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'})); - } else { - this.fcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + const locale = this.lang ? 'es-US' : 'en-US'; + this.fcontracts_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']); }); } diff --git a/src/app/pages/contracts/pending/pending.page.html b/src/app/pages/contracts/pending/pending.page.html index cddee30..75d7df1 100755 --- a/src/app/pages/contracts/pending/pending.page.html +++ b/src/app/pages/contracts/pending/pending.page.html @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + @@ -22,4 +40,5 @@ {{'contracts.viewsuppliers_1.1' | translate}}
{{'contracts.viewsuppliers_1.2' | translate}}
+
diff --git a/src/app/pages/contracts/pending/pending.page.ts b/src/app/pages/contracts/pending/pending.page.ts index 0bd0931..fcd3e53 100755 --- a/src/app/pages/contracts/pending/pending.page.ts +++ b/src/app/pages/contracts/pending/pending.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; import { ModalController, MenuController, NavController } from '@ionic/angular'; import { EventService } from '../../../services/event.service'; import { EnvService } from 'src/app/services/env.service'; @@ -14,11 +14,12 @@ import { AlertService } from 'src/app/services/alert.service'; styleUrls: ['./pending.page.scss'], standalone: false }) -export class PendingPage implements OnInit { +export class PendingPage { pcontracts: any[] = []; pcontracts_dates: any[] = []; lang: boolean = false; + loading = true; constructor( private modalController: ModalController, @@ -31,32 +32,29 @@ export class PendingPage implements OnInit { private translateService: TranslateService, private languageService: LanguageService, private env: EnvService, + private cdr: ChangeDetectorRef, ) { this.events.subscribe('refreshpcontracts', (data) => { this.getpcontracts(); }); } - ngOnInit() { + ionViewWillEnter() { + this.lang = this.languageService.getDefaultLanguage() === 'es'; + this.loading = true; this.getpcontracts(); - if (this.languageService.getDefaultLanguage() == 'es') { - this.lang = true; - } else { - this.lang = false - } } - refresh (event: any) { + refresh(event: any) { this.ichambaService.getPendingcontracts().subscribe( data => { this.pcontracts = data; + this.pcontracts_dates = []; for (var i of this.pcontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.pcontracts_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'})); - } else { - this.pcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + 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']); @@ -68,14 +66,15 @@ export class PendingPage implements OnInit { this.ichambaService.getPendingcontracts().subscribe( data => { this.pcontracts = data; + this.pcontracts_dates = []; for (var i of this.pcontracts) { - if (this.languageService.getDefaultLanguage() == 'es') { - this.pcontracts_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'})); - } else { - this.pcontracts_dates.push(new Date((new Date(i.date).toLocaleString('en-US') + ' UTC').replace("," ,"")).toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute:'numeric', timeZoneName: 'long'})); - } + 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']); }); } diff --git a/src/app/pages/postulations/already/already.page.html b/src/app/pages/postulations/already/already.page.html index dd6e331..501c536 100755 --- a/src/app/pages/postulations/already/already.page.html +++ b/src/app/pages/postulations/already/already.page.html @@ -11,19 +11,38 @@ - - - + + + + -

{{ postulation.category }}

-

{{postulation.address}}

-

Télefono: {{ postulation.phone }}

-

Referencias: {{postulation.references}}

-

{{postulations_dates[i]}}

-

Monto: {{postulation.amount}}

-

Detalles: {{postulation.details}}

+ + + + + + +
+ + + + + + +

{{ postulation.category }}

+

{{postulation.address}}

+

Télefono: {{ postulation.phone }}

+

Referencias: {{postulation.references}}

+

{{postulations_dates[i]}}

+

Monto: {{postulation.amount}}

+

Detalles: {{postulation.details}}

+
+
+
+
+
diff --git a/src/app/pages/postulations/already/already.page.ts b/src/app/pages/postulations/already/already.page.ts index 4fdc8d9..015c803 100755 --- a/src/app/pages/postulations/already/already.page.ts +++ b/src/app/pages/postulations/already/already.page.ts @@ -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']); }); } diff --git a/src/app/pages/postulations/current/current.page.html b/src/app/pages/postulations/current/current.page.html index 56f18f0..33f63d6 100755 --- a/src/app/pages/postulations/current/current.page.html +++ b/src/app/pages/postulations/current/current.page.html @@ -11,19 +11,38 @@ - - - + + + + -

{{ postulation.category }}

-

{{postulation.address}}

-

Referencias: {{postulation.references}}

-

{{postulations_dates[i]}}

-

Detalles: {{postulation.details}}

-

Tiempo restante: {{postulation.time_limit}} minutos

+ + + + + +
- Postularse +
+ + + + + + +

{{ postulation.category }}

+

{{postulation.address}}

+

Referencias: {{postulation.references}}

+

{{postulations_dates[i]}}

+

Detalles: {{postulation.details}}

+

Tiempo restante: {{postulation.time_limit}} minutos

+
+ Postularse +
+
+
+
diff --git a/src/app/pages/postulations/current/current.page.ts b/src/app/pages/postulations/current/current.page.ts index d620f90..dcbe3e4 100755 --- a/src/app/pages/postulations/current/current.page.ts +++ b/src/app/pages/postulations/current/current.page.ts @@ -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: ['./current.page.scss'], standalone: false }) -export class CurrentPage implements OnInit { +export class CurrentPage { postulations: any[] = []; postulations_dates: any[] = []; + loading = true; constructor( private menu: MenuController, @@ -26,13 +27,15 @@ export class CurrentPage 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 CurrentPage implements OnInit { this.ichambaService.getPostulation().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 CurrentPage implements OnInit { this.ichambaService.getPostulation().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']); }); } diff --git a/src/app/pages/postulations/ended/ended.page.html b/src/app/pages/postulations/ended/ended.page.html index 8760520..4adbd18 100755 --- a/src/app/pages/postulations/ended/ended.page.html +++ b/src/app/pages/postulations/ended/ended.page.html @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + @@ -24,4 +42,5 @@ + diff --git a/src/app/pages/postulations/ended/ended.page.ts b/src/app/pages/postulations/ended/ended.page.ts index 8caf989..9c37784 100755 --- a/src/app/pages/postulations/ended/ended.page.ts +++ b/src/app/pages/postulations/ended/ended.page.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; import { ModalController, MenuController, NavController } from '@ionic/angular'; import { EventService } from '../../../services/event.service'; import { EnvService } from 'src/app/services/env.service'; @@ -12,10 +12,11 @@ import { AlertService } from 'src/app/services/alert.service'; styleUrls: ['./ended.page.scss'], standalone: false }) -export class EndedPage implements OnInit { +export class EndedPage { postulations: any[] = []; postulations_dates: any[] = []; + loading = true; constructor( private modalController: ModalController, @@ -26,13 +27,15 @@ export class EndedPage implements OnInit { private alertService: AlertService, private ichambaService: IchambaService, private env: EnvService, + private cdr: ChangeDetectorRef, ) { this.events.subscribe('refreshpostulations', (data) => { this.getfinishedpostulations(); }); } - ngOnInit() { + ionViewWillEnter() { + this.loading = true; this.getfinishedpostulations(); } @@ -40,9 +43,11 @@ export class EndedPage implements OnInit { this.ichambaService.getFinishedPostulation().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 EndedPage implements OnInit { this.ichambaService.getFinishedPostulation().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']); }); } diff --git a/src/app/pages/postulations/postulations.module.ts b/src/app/pages/postulations/postulations.module.ts index 14c8f47..3daa02b 100755 --- a/src/app/pages/postulations/postulations.module.ts +++ b/src/app/pages/postulations/postulations.module.ts @@ -28,6 +28,10 @@ const routes: Routes = [ { path: 'ended', loadChildren: () => import('./ended/ended.module').then(m => m.EndedPageModule) + }, + { + path: 'reported', + loadChildren: () => import('./reported/reported.module').then(m => m.PostulationReportedPageModule) } ] } diff --git a/src/app/pages/postulations/postulations.page.html b/src/app/pages/postulations/postulations.page.html index accc9fe..42744be 100755 --- a/src/app/pages/postulations/postulations.page.html +++ b/src/app/pages/postulations/postulations.page.html @@ -24,5 +24,10 @@ Finalizadas + + + Reportadas + + diff --git a/src/app/pages/postulations/reported/reported.module.ts b/src/app/pages/postulations/reported/reported.module.ts new file mode 100644 index 0000000..76fa828 --- /dev/null +++ b/src/app/pages/postulations/reported/reported.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { Routes, RouterModule } from '@angular/router'; +import { IonicModule } from '@ionic/angular'; +import { PostulationReportedPage } from './reported.page'; +import { ReportDiscussionPageModule } from '../../report-discussion/report-discussion.module'; + +const routes: Routes = [ + { + path: '', + component: PostulationReportedPage + } +]; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + RouterModule.forChild(routes), + ReportDiscussionPageModule + ], + declarations: [PostulationReportedPage] +}) +export class PostulationReportedPageModule {} diff --git a/src/app/pages/postulations/reported/reported.page.html b/src/app/pages/postulations/reported/reported.page.html new file mode 100644 index 0000000..c5332f6 --- /dev/null +++ b/src/app/pages/postulations/reported/reported.page.html @@ -0,0 +1,53 @@ + + + + + + Postulaciones + + + + +

Reportadas

+ + + + + + + + + + + + + + + + + + + + +

+ No tienes postulaciones reportadas +

+ + + + + +

{{ report.category }}

+

Cliente: {{ report.client }}

+

{{ report.address }}

+

{{ reports_dates[i] }}

+

Monto: ${{ report.amount }}

+
+ + + +
+
+
+
+
diff --git a/src/app/pages/postulations/reported/reported.page.scss b/src/app/pages/postulations/reported/reported.page.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/postulations/reported/reported.page.ts b/src/app/pages/postulations/reported/reported.page.ts new file mode 100644 index 0000000..5c208b1 --- /dev/null +++ b/src/app/pages/postulations/reported/reported.page.ts @@ -0,0 +1,77 @@ +import { Component, ChangeDetectorRef } from '@angular/core'; +import { ModalController } from '@ionic/angular'; +import { IchambaService } from 'src/app/services/ichamba.service'; +import { AlertService } from 'src/app/services/alert.service'; +import { ReportDiscussionPage } from '../../report-discussion/report-discussion.page'; + +@Component({ + selector: 'app-postulation-reported', + templateUrl: './reported.page.html', + styleUrls: ['./reported.page.scss'], + standalone: false +}) +export class PostulationReportedPage { + + reports: any[] = []; + reports_dates: string[] = []; + loading = true; + + constructor( + private alertService: AlertService, + private ichambaService: IchambaService, + private cdr: ChangeDetectorRef, + private modalCtrl: ModalController, + ) { } + + ionViewWillEnter() { + this.loading = true; + this.loadReports(); + } + + refresh(event: any) { + this.ichambaService.getPostulationReports().subscribe({ + next: data => { + this.reports = data; + this.buildDates(); + this.cdr.detectChanges(); + event.target.complete(); + }, + error: error => { + this.alertService.presentToast('Por favor contacte a soporte técnico, Estatus:' + error['status']); + event.target.complete(); + } + }); + } + + loadReports() { + this.ichambaService.getPostulationReports().subscribe({ + next: data => { + this.reports = data; + this.buildDates(); + this.loading = false; + this.cdr.detectChanges(); + }, + error: error => { + this.loading = false; + this.alertService.presentToast('Por favor contacte a soporte técnico, Estatus:' + error['status']); + } + }); + } + + async viewDiscussion(reportId: any) { + const modal = await this.modalCtrl.create({ + component: ReportDiscussionPage, + componentProps: { reportId }, + }); + await modal.present(); + } + + private buildDates() { + this.reports_dates = this.reports.map(r => + new Date((new Date(r.appointment).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString('es-US', { + weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', + hour: 'numeric', minute: 'numeric', timeZoneName: 'long' + }) + ); + } +} diff --git a/src/app/pages/report-discussion/report-discussion.module.ts b/src/app/pages/report-discussion/report-discussion.module.ts new file mode 100644 index 0000000..1705fa1 --- /dev/null +++ b/src/app/pages/report-discussion/report-discussion.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; +import { ReportDiscussionPage } from './report-discussion.page'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + IonicModule, + ], + declarations: [ReportDiscussionPage], + exports: [ReportDiscussionPage] +}) +export class ReportDiscussionPageModule {} diff --git a/src/app/pages/report-discussion/report-discussion.page.html b/src/app/pages/report-discussion/report-discussion.page.html new file mode 100644 index 0000000..de4144b --- /dev/null +++ b/src/app/pages/report-discussion/report-discussion.page.html @@ -0,0 +1,94 @@ + + + + + + + + Discusión del Reporte + + + + +
+ + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +

No hay mensajes aún.

+
+ + + + + +
+
+ Moderador +

{{ msg.comment }}

+ {{ msg.created_at | date:'d MMM, HH:mm' }} +
+
+ + +
+
+

{{ msg.comment }}

+ {{ msg.created_at | date:'d MMM, HH:mm' }} +
+
+ + +
+
+ {{ msg.sender_name }} +

{{ msg.comment }}

+ {{ msg.created_at | date:'d MMM, HH:mm' }} +
+
+ +
+
+ +
+
+ + +
+ + + + + + + +
+
diff --git a/src/app/pages/report-discussion/report-discussion.page.scss b/src/app/pages/report-discussion/report-discussion.page.scss new file mode 100644 index 0000000..b1b06ed --- /dev/null +++ b/src/app/pages/report-discussion/report-discussion.page.scss @@ -0,0 +1,117 @@ +.messages-container { + display: flex; + flex-direction: column; + padding: 16px; + min-height: 100%; +} + +.message-wrapper { + display: flex; + margin-bottom: 10px; + + &.right { justify-content: flex-end; } + &.left { justify-content: flex-start; } + &.center { justify-content: center; } +} + +.message-bubble { + max-width: 72%; + padding: 10px 14px; + border-radius: 18px; + word-break: break-word; + + p { + margin: 0 0 4px 0; + font-size: 0.95rem; + line-height: 1.4; + } + + .sender-name { + display: block; + font-size: 0.72rem; + font-weight: 600; + margin-bottom: 4px; + opacity: 0.75; + } + + .timestamp { + display: block; + font-size: 0.68rem; + margin-top: 4px; + opacity: 0.65; + text-align: right; + } + + &.mine { + background: var(--ion-color-primary); + color: #fff; + border-bottom-right-radius: 4px; + } + + &.other { + background: var(--ion-color-light); + color: var(--ion-color-dark); + border-bottom-left-radius: 4px; + } + + &.moderator { + background: var(--ion-color-medium); + color: #fff; + max-width: 80%; + text-align: center; + border-radius: 10px; + font-style: italic; + + .sender-name { + text-align: center; + font-weight: 700; + opacity: 1; + } + + .timestamp { + text-align: center; + } + } +} + +.empty-state { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 60px 16px; + color: var(--ion-color-medium); + + p { + margin: 0; + font-size: 0.95rem; + } +} + +.input-bar { + display: flex; + align-items: flex-end; + padding: 6px 6px; + gap: 2px; + background: var(--ion-background-color, #fff); + border-top: 1px solid var(--ion-color-light-shade); + + ion-textarea { + flex: 1; + --padding-start: 14px; + --padding-end: 14px; + --padding-top: 8px; + --padding-bottom: 8px; + background: var(--ion-color-light); + border-radius: 20px; + margin: 0; + max-height: 120px; + } + + ion-button { + --padding-start: 6px; + --padding-end: 6px; + min-height: 40px; + } +} diff --git a/src/app/pages/report-discussion/report-discussion.page.ts b/src/app/pages/report-discussion/report-discussion.page.ts new file mode 100644 index 0000000..a408f1e --- /dev/null +++ b/src/app/pages/report-discussion/report-discussion.page.ts @@ -0,0 +1,80 @@ +import { Component, Input, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core'; +import { IonContent, ModalController } from '@ionic/angular'; +import { IchambaService } from 'src/app/services/ichamba.service'; +import { AuthService } from 'src/app/services/auth.service'; +import { AlertService } from 'src/app/services/alert.service'; + +@Component({ + selector: 'app-report-discussion', + templateUrl: './report-discussion.page.html', + styleUrls: ['./report-discussion.page.scss'], + standalone: false +}) +export class ReportDiscussionPage implements OnInit { + + @Input() reportId: any; + + @ViewChild('content') content!: IonContent; + + messages: any[] = []; + newMessage: string = ''; + currentUserId: any; + loading = true; + sending = false; + + constructor( + private modalCtrl: ModalController, + private ichambaService: IchambaService, + private authService: AuthService, + private alertService: AlertService, + private cdr: ChangeDetectorRef, + ) {} + + ngOnInit() { + this.currentUserId = this.authService.userId; + this.loadMessages(); + } + + loadMessages() { + this.loading = true; + this.ichambaService.getReportDiscussion(this.reportId).subscribe({ + next: data => { + this.messages = data; + this.loading = false; + this.cdr.detectChanges(); + setTimeout(() => this.content.scrollToBottom(300), 100); + }, + error: () => { + this.loading = false; + this.cdr.detectChanges(); + } + }); + } + + sendMessage() { + const text = this.newMessage.trim(); + if (!text || this.sending) return; + this.newMessage = ''; + this.sending = true; + this.ichambaService.sendReportMessage(this.reportId, text).subscribe({ + next: (msg: any) => { + this.messages.push(msg); + this.sending = false; + this.cdr.detectChanges(); + setTimeout(() => this.content.scrollToBottom(300), 100); + }, + error: () => { + this.sending = false; + this.alertService.presentToast('No se pudo enviar el mensaje.'); + } + }); + } + + attachPhoto() { + // TODO: implementar captura y envío de foto + } + + dismiss() { + this.modalCtrl.dismiss(); + } +} diff --git a/src/app/pages/reports/reports.module.ts b/src/app/pages/reports/reports.module.ts index aad9698..23d198c 100755 --- a/src/app/pages/reports/reports.module.ts +++ b/src/app/pages/reports/reports.module.ts @@ -4,8 +4,10 @@ import { FormsModule } from '@angular/forms'; import { Routes, RouterModule } from '@angular/router'; import { IonicModule } from '@ionic/angular'; +import { TranslateModule } from '@ngx-translate/core'; import { ReportsPage } from './reports.page'; +import { ReportDiscussionPageModule } from '../report-discussion/report-discussion.module'; const routes: Routes = [ { @@ -19,7 +21,9 @@ const routes: Routes = [ CommonModule, FormsModule, IonicModule, - RouterModule.forChild(routes) + RouterModule.forChild(routes), + TranslateModule, + ReportDiscussionPageModule ], declarations: [ReportsPage] }) diff --git a/src/app/pages/reports/reports.page.html b/src/app/pages/reports/reports.page.html index 9e24926..b5692f5 100755 --- a/src/app/pages/reports/reports.page.html +++ b/src/app/pages/reports/reports.page.html @@ -1,9 +1,53 @@ - - reports + + + + + {{'contracts.header' | translate}} - + +

{{'contracts.header_4' | translate}}

+ + + + + + + + + + + + + + + + + + + + + + + + + +

{{ report.category }}

+

{{ report.en_category }}

+

{{'contracts.supplier' | translate}}: {{ report.supplier }}

+

{{'reports.company' | translate}}: {{ report.company }}

+

{{ report.address }}

+

{{ reports_dates[i] }}

+

{{'contracts.amount' | translate}}: ${{ report.amount }}

+
+ + + +
+
+
+
diff --git a/src/app/pages/reports/reports.page.ts b/src/app/pages/reports/reports.page.ts index 9bf2074..ec16cd0 100755 --- a/src/app/pages/reports/reports.page.ts +++ b/src/app/pages/reports/reports.page.ts @@ -1,4 +1,10 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, ChangeDetectorRef } from '@angular/core'; +import { ModalController } from '@ionic/angular'; +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 { ReportDiscussionPage } from '../report-discussion/report-discussion.page'; @Component({ selector: 'app-reports', @@ -6,11 +12,80 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./reports.page.scss'], standalone: false }) -export class ReportsPage implements OnInit { +export class ReportsPage { - constructor() { } + reports: any[] = []; + reports_dates: string[] = []; + lang: boolean = false; + loading = true; - ngOnInit() { + constructor( + private alertService: AlertService, + private ichambaService: IchambaService, + private translateService: TranslateService, + private languageService: LanguageService, + private cdr: ChangeDetectorRef, + private modalCtrl: ModalController, + ) { } + + ionViewWillEnter() { + this.lang = this.languageService.getDefaultLanguage() === 'es'; + this.loading = true; + this.loadReports(); } + refresh(event: any) { + this.reports = []; + this.reports_dates = []; + this.ichambaService.getReports().subscribe({ + next: data => { + this.reports = data; + this.buildDates(); + event.target.complete(); + }, + error: error => { + this.alertService.presentToast(this.translateService.instant('alerts.error') + error['status']); + event.target.complete(); + } + }); + } + + loadReports() { + this.ichambaService.getReports().subscribe({ + next: data => { + this.reports = data; + this.buildDates(); + this.loading = false; + this.cdr.detectChanges(); + }, + error: error => { + this.loading = false; + this.alertService.presentToast(this.translateService.instant('alerts.error') + error['status']); + } + }); + } + + async viewDiscussion(reportId: any) { + const modal = await this.modalCtrl.create({ + component: ReportDiscussionPage, + componentProps: { reportId }, + }); + await modal.present(); + } + + getStatusColor(status: string): string { + if (status === 'resuelto') return 'success'; + if (status === 'en revision' || status === 'en revisión') return 'primary'; + return 'warning'; + } + + private buildDates() { + const locale = this.lang ? 'es-US' : 'en-US'; + this.reports_dates = this.reports.map(r => + new Date((new Date(r.appointment).toLocaleString('en-US') + ' UTC').replace(',', '')).toLocaleDateString(locale, { + weekday: 'long', year: 'numeric', month: 'short', day: 'numeric', + hour: 'numeric', minute: 'numeric', timeZoneName: 'long' + }) + ); + } } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 9afd89b..d802948 100755 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -20,6 +20,7 @@ export class AuthService { isReported = false; userName: string = ''; userRole: number = 0; + userId: any = null; role: any; token: any; userInfo: any; @@ -140,6 +141,7 @@ export class AuthService { } this.userName = user['name'] ?? ''; this.userRole = user['role_id'] ?? 0; + this.userId = user['id'] ?? null; this.events.publish('set_role', user['role_id']); console.log("after login:", user); }) diff --git a/src/app/services/ichamba.service.ts b/src/app/services/ichamba.service.ts index 1adda21..3c811fc 100755 --- a/src/app/services/ichamba.service.ts +++ b/src/app/services/ichamba.service.ts @@ -181,6 +181,34 @@ export class IchambaService { { contract_id: contract_id, comment: comment }, { headers: headers }); } + getReports() { + const headers = new HttpHeaders({ + 'Authorization': this.authService.token["token_type"]+" "+this.authService.token["access_token"] + }); + return this.http.get(this.env.API_URL + 'contracts/reports', { headers: headers }); + } + + getPostulationReports() { + const headers = new HttpHeaders({ + 'Authorization': this.authService.token["token_type"]+" "+this.authService.token["access_token"] + }); + return this.http.get(this.env.API_URL + 'postulations/reports', { headers: headers }); + } + + getReportDiscussion(reportId: any) { + const headers = new HttpHeaders({ + 'Authorization': this.authService.token["token_type"]+" "+this.authService.token["access_token"] + }); + return this.http.get(this.env.API_URL + 'contracts/reports/' + reportId + '/comments', { headers }); + } + + sendReportMessage(reportId: any, comment: string) { + const headers = new HttpHeaders({ + 'Authorization': this.authService.token["token_type"]+" "+this.authService.token["access_token"] + }); + return this.http.post(this.env.API_URL + 'contracts/reports/' + reportId + '/comments', { comment: comment }, { headers }); + } + noHomeCheck() { const headers = new HttpHeaders({ 'Authorization': this.authService.token["token_type"]+" "+this.authService.token["access_token"] diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 56770d4..f8bed08 100755 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -44,7 +44,7 @@ "dashboard": { "header": "Find services", "searchbox_placeholder": "Enter the service you are looking for", - "slogan": "Everything begins with a search", + "slogan": "It all starts with a search", "welcome": "Welcome" }, @@ -62,6 +62,7 @@ "header_1": "Postulated", "header_2": "Confirmed", "header_3": "Finished", + "header_4": "Reported", "parent": "Extra charge from service: ", "status": "Status", "rate": "Rate", @@ -73,7 +74,7 @@ "validate": "Validate", "hire_info_1": "You are about to hire", "hire_info_2": "to provide the service you have requested.", - "hire_pay": "Please select with which card do you want to pay the service and enter the CVV of the card to continue.", + "hire_pay": "Please select which card do you want to pay the service with, and enter the CVV of the card to continue.", "hire_confirm": "Hire service", "coupon": "Coupon", "no_home": "Not at home", @@ -178,6 +179,12 @@ "faq_9.1": "Phone numbers so you can contact each other and the user names." }, + "reports": { + "header": "My Reports", + "company": "Company", + "empty": "You have no reports registered" + }, + "alerts": { "login": "Logged In", "login_error": "Wrong email or password", diff --git a/src/assets/i18n/es.json b/src/assets/i18n/es.json index d8e829d..1108390 100755 --- a/src/assets/i18n/es.json +++ b/src/assets/i18n/es.json @@ -62,6 +62,7 @@ "header_1": "Postulados", "header_2": "Confirmados", "header_3": "Finalizados", + "header_4": "Reportados", "parent": "Fondo extra del servicio: ", "status": "Estado", "rate": "Calificar", @@ -178,6 +179,12 @@ "faq_9.1": "El celular para que puedan contactarse y el nombre de usuario." }, + "reports": { + "header": "Mis Reportes", + "company": "Empresa", + "empty": "No tienes reportes registrados" + }, + "alerts": { "login": "Sesión iniciada", "login_error": "Email o contraseña incorrectos",