diff --git a/src/app/components/shared-components.module.ts b/src/app/components/shared-components.module.ts index ecb9fe7..eccd5b9 100755 --- a/src/app/components/shared-components.module.ts +++ b/src/app/components/shared-components.module.ts @@ -2,15 +2,12 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IonicModule } from '@ionic/angular'; - - @NgModule({ - declarations: [AccordionComponent], + declarations: [], imports: [ CommonModule, IonicModule ], - exports: [ - ] + exports: [] }) export class SharedComponentsModule { } diff --git a/src/app/pages/contracts/hire/hire.page.html b/src/app/pages/contracts/hire/hire.page.html index eb30799..50c6caa 100755 --- a/src/app/pages/contracts/hire/hire.page.html +++ b/src/app/pages/contracts/hire/hire.page.html @@ -41,7 +41,7 @@ {{'contracts.validate' | translate}} - + {{'cards.card' | translate}} Agregar tarjeta @@ -49,13 +49,18 @@
- + CVV -

+
+ + MODO DE PRUEBA: El pago será simulado + +

{{'contracts.hire_confirm' | translate}}

+
@@ -106,4 +111,5 @@ +
diff --git a/src/app/pages/contracts/hire/hire.page.ts b/src/app/pages/contracts/hire/hire.page.ts index 271a1b1..85d12e6 100755 --- a/src/app/pages/contracts/hire/hire.page.ts +++ b/src/app/pages/contracts/hire/hire.page.ts @@ -33,6 +33,7 @@ export class HirePage implements OnInit { final_amount = null; coupon = null; cards_menu = null; + paymentBypass = false; constructor( private modalController: ModalController, @@ -59,11 +60,14 @@ export class HirePage implements OnInit { } ngOnInit() { - OpenPay.setId(this.env.MERCHANT_ID); - OpenPay.setApiKey(this.env.PUBLIC_API_KEY); - console.log(OpenPay.getSandboxMode()); - var deviceDataId = OpenPay.deviceData.setup("card_form"); - this.getcards(); + this.paymentBypass = this.env.PAYMENT_BYPASS; + if (!this.paymentBypass) { + OpenPay.setId(this.env.MERCHANT_ID); + OpenPay.setApiKey(this.env.PUBLIC_API_KEY); + console.log(OpenPay.getSandboxMode()); + var deviceDataId = OpenPay.deviceData.setup("card_form"); + this.getcards(); + } } newcard() { @@ -141,6 +145,36 @@ export class HirePage implements OnInit { } createContract(form: NgForm) { + // Si el bypass está activo, enviar con valores dummy + if (this.paymentBypass) { + this.loadingCtrl.create().then((overlay) => { + this.loading = overlay; + this.loading.present(); + }); + this.ichambaService.createContract(this.postulation_id, this.supplier_id, 'BYPASS', this.coupon, '000', 'BYPASS').subscribe( + data => { + if (data['type'] == "error") { + this.loading.dismiss(); + this.alertService.presentToast(data['message']); + } else if (data['name'] == "used") { + this.loading.dismiss(); + this.alertService.presentToast(this.translateService.instant('contracts.coupon_used')); + } else if (data['name'] == "expired") { + this.loading.dismiss(); + this.alertService.presentToast(this.translateService.instant('contracts.coupon_expired')); + } else { + this.loading.dismiss(); + this.events.publish('refreshpcontracts', 'data'); + this.navCtrl.navigateRoot('/contracts/contracted'); + this.alertService.presentToast(this.translateService.instant('alerts.hire')); + } + }, error => { + this.loading.dismiss(); + this.alertService.presentToast(this.translateService.instant('alerts.error') + error['status']); + }); + return; + } + if (this.card_id != "Agregar tarjeta") { if (this.code_check) { let code = form.value.code; diff --git a/src/app/pages/dashboard/dashboard.page.html b/src/app/pages/dashboard/dashboard.page.html index 9b609ad..8f04515 100755 --- a/src/app/pages/dashboard/dashboard.page.html +++ b/src/app/pages/dashboard/dashboard.page.html @@ -56,9 +56,9 @@ ion-item:active:after { -

{{ pcontract.category }}

+

{{'contracts.postulating' | translate}}

{{pcontract.address}}

{{pcontracts_dates[i]}}

diff --git a/src/app/pages/hero/hero.page.html b/src/app/pages/hero/hero.page.html index 2de7fba..cae380c 100755 --- a/src/app/pages/hero/hero.page.html +++ b/src/app/pages/hero/hero.page.html @@ -16,17 +16,45 @@

+ + {{'hero.categories' | translate}} +
+ + {{cat}} + + +
- {{'hero.categories' | translate}} - - {{category}} - + + + + + {{category}} + +
+ + {{'hero.keywords' | translate}} +
+ + {{keyword}} + + +
- {{'hero.keywords' | translate}} - + + {{'hero.keywords_hint' | translate}} diff --git a/src/app/pages/hero/hero.page.scss b/src/app/pages/hero/hero.page.scss index e69de29..9a2f64f 100755 --- a/src/app/pages/hero/hero.page.scss +++ b/src/app/pages/hero/hero.page.scss @@ -0,0 +1,59 @@ +.chip-label { + display: block; + padding: 10px 16px 5px; + font-size: 14px; + font-weight: 500; + color: var(--ion-color-medium); +} + +.chips-container { + display: flex; + flex-wrap: wrap; + padding: 5px 10px; + min-height: 20px; + gap: 5px; + + ion-chip { + margin: 2px; + height: 32px; + + ion-label { + font-size: 13px; + } + + ion-icon { + cursor: pointer; + font-size: 18px; + } + } +} + +.dropdown-list { + max-height: 200px; + overflow-y: auto; + border: 1px solid var(--ion-color-light-shade); + border-radius: 8px; + margin: 0 16px; + background: var(--ion-background-color); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + + ion-item { + --min-height: 40px; + font-size: 14px; + cursor: pointer; + + &:hover { + --background: var(--ion-color-light); + } + } +} + +ion-chip[color="primary"] { + --background: var(--ion-color-primary); + --color: var(--ion-color-primary-contrast); +} + +ion-chip[color="secondary"] { + --background: var(--ion-color-secondary); + --color: var(--ion-color-secondary-contrast); +} diff --git a/src/app/pages/hero/hero.page.ts b/src/app/pages/hero/hero.page.ts index e55ab05..0d7e71b 100755 --- a/src/app/pages/hero/hero.page.ts +++ b/src/app/pages/hero/hero.page.ts @@ -17,10 +17,11 @@ export class HeroPage implements OnInit { categories: any[] = []; categories_input: any[] = []; categories_rearranged: any[] = []; - keywords: any[] = []; - keywords_string: any[] = []; - keywords_text: string = ''; - aux_categories: any[] = []; + filteredCategories: any[] = []; + categorySearchText: string = ''; + showCategoryDropdown: boolean = false; + keywords: string[] = []; + keywordInput: string = ''; myPosition: any = {}; myAddress: string | null = null; myIntnumber: string | null = null; @@ -42,23 +43,85 @@ export class HeroPage implements OnInit { ) { } ngOnInit() { - /*this.categories = ["carpintero","jardinero","abogado","administrador","agente inmobiliario","agente de seguros","albañil", - "arquitecto","asistente personal","becario","cerrajero","chef","chofer","contratista","contador","diseñador de interiores", - "cantante","diseñador grafico","edecan","electricista","estilista","servicios financieros","fontanero","fotografo","produccion de videos", - "hostess","lavado de tapicerias","aire acondicionado","almacenista","ayudante","azulejero","cerrajero automotriz","cortinas metalicas", - "electrico automotriz","entretenimiento","fisioterapeuta","grua","herrero","ingeniero civil","laminado automotriz","limpieza","limpieza del hogar", - "mantenimiento","mariachi","masajista","marmolero","mecanico","mercadotecnia","mesero","modelo","musico","niñera","pintor","pintura automotriz", - "plomero","programador","publicista","recepcionista","remodelacion","repartidor","reparacion de celulares","reparacion de electronicos","soldador", - "tabla roquero","tapicero","tecnico en gas","tuneame la nave","traductor","tutor","vendedor","veterinario","vidrio y aluminio","reparacion de computadoras", - "mantenimiento de camiones","consultor","capacitacion","maestro","barbero","agencia de colocacion","agencia de viajes","paseador de perros","banquete", - "almacenaje","impermeabilizacion","redes de internet"];*/ this.ichambaService.getCategories() .subscribe( categories => { this.categories = categories; - this.aux_categories = categories; + this.filteredCategories = categories; }) } + // ========== CATEGORÍAS CON CHIPS ========== + filterCategories(event: any) { + const searchTerm = (event.detail?.value || event.target?.value || '').toLowerCase(); + this.categorySearchText = searchTerm; + if (searchTerm.length > 0) { + this.filteredCategories = this.categories.filter(cat => + cat.toLowerCase().includes(searchTerm) && !this.categories_input.includes(cat) + ); + this.showCategoryDropdown = true; + } else { + this.filteredCategories = this.categories.filter(cat => !this.categories_input.includes(cat)); + this.showCategoryDropdown = false; + } + } + + selectCategory(category: string) { + if (!this.categories_input.includes(category)) { + this.categories_input.push(category); + } + this.categorySearchText = ''; + this.showCategoryDropdown = false; + this.filteredCategories = this.categories.filter(cat => !this.categories_input.includes(cat)); + } + + removeCategory(category: string) { + const index = this.categories_input.indexOf(category); + if (index > -1) { + this.categories_input.splice(index, 1); + } + this.filteredCategories = this.categories.filter(cat => !this.categories_input.includes(cat)); + } + + showCategoryList() { + this.filteredCategories = this.categories.filter(cat => !this.categories_input.includes(cat)); + this.showCategoryDropdown = true; + } + + hideCategoryList() { + setTimeout(() => { + this.showCategoryDropdown = false; + }, 200); + } + + // ========== PALABRAS CLAVE CON CHIPS ========== + addKeyword(event?: any) { + const value = this.keywordInput?.trim(); + if (value && value.length > 0) { + // Separar por comas si hay varias palabras + const newKeywords = value.split(',').map((k: string) => k.trim()).filter((k: string) => k.length > 0); + newKeywords.forEach((keyword: string) => { + if (!this.keywords.includes(keyword)) { + this.keywords.push(keyword); + } + }); + this.keywordInput = ''; + } + } + + onKeywordKeydown(event: KeyboardEvent) { + if (event.key === 'Enter' || event.key === ',') { + event.preventDefault(); + this.addKeyword(); + } + } + + removeKeyword(keyword: string) { + const index = this.keywords.indexOf(keyword); + if (index > -1) { + this.keywords.splice(index, 1); + } + } + dismissHero() { this.navCtrl.navigateRoot('/landing'); } @@ -103,22 +166,18 @@ export class HeroPage implements OnInit { } addHero(){ - // categories_input is now an array of values directly from ion-select - this.categories_rearranged = this.categories_input.slice(); + // Preparar categorías y keywords + const categoriesString = this.categories_input.join(','); + const keywordsString = this.keywords.length > 0 ? this.keywords.join(', ') : null; - // keywords_text is now a string, split by comma - if (this.keywords_text && this.keywords_text.trim().length > 0) { - this.keywords_string = this.keywords_text.split(',').map(k => k.trim()).filter(k => k.length > 0); - } - - if (this.name && this.categories_input && this.myAddress && this.myPosition.latitude && this.myPosition.longitude && this.selectedReference){ + if (this.name && this.categories_input.length > 0 && this.myAddress && this.myPosition.latitude && this.myPosition.longitude && this.selectedReference){ if (this.selectedReference == 5 && this.reference) { this.loadingCtrl.create().then((overlay) => { this.loading = overlay; this.loading.present(); }); - this.ichambaService.addHero(this.name, this.categories_rearranged.join(','), (this.keywords_string.join(', ') == "" ? null : this.keywords_string.join(', ')), this.myAddress, this.myPosition.latitude, this.myPosition.longitude, this.selectedReference, this.reference).subscribe( + this.ichambaService.addHero(this.name, categoriesString, keywordsString, this.myAddress, this.myPosition.latitude, this.myPosition.longitude, this.selectedReference, this.reference).subscribe( data => { this.loading.dismiss(); this.alertService.presentToast(data['message']); @@ -133,7 +192,7 @@ export class HeroPage implements OnInit { this.loading.present(); }); - this.ichambaService.addHero(this.name, this.categories_rearranged.join(','), (this.keywords_string.join(', ') == "" ? null : this.keywords_string.join(', ')), this.myAddress, this.myPosition.latitude, this.myPosition.longitude, this.selectedReference, this.reference).subscribe( + this.ichambaService.addHero(this.name, categoriesString, keywordsString, this.myAddress, this.myPosition.latitude, this.myPosition.longitude, this.selectedReference, this.reference).subscribe( data => { this.loading.dismiss(); this.alertService.presentToast(data['message']); diff --git a/src/app/services/env.service.ts b/src/app/services/env.service.ts index 044ac95..c1bd33a 100755 --- a/src/app/services/env.service.ts +++ b/src/app/services/env.service.ts @@ -10,5 +10,8 @@ export class EnvService { PUBLIC_API_KEY = 'pk_9465179493384689a8d2da9adc825411'; ONESIGNAL_APP_ID = 'c854ae89-7ff7-4216-a70e-5fdff0cd8e10'; + // Bypass de pago para pruebas (cambiar a false para producción) + PAYMENT_BYPASS = true; + constructor() { } }