ng-easycommerce-v18 0.3.14-beta.2 → 0.3.15-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/esm2022/lib/classes/filters/filter.mjs +2 -27
- package/esm2022/lib/constants/api.constants.service.mjs +44 -41
- package/esm2022/lib/ec-components/auth-ec/login-form-ec/login-form-ec.component.mjs +5 -1
- package/esm2022/lib/ec-components/auth-ec/register-form-ec/register-form-ec.component.mjs +5 -1
- package/esm2022/lib/ec-components/blocks-ec/block-products-ec/block-products-ec.component.mjs +3 -5
- package/esm2022/lib/ec-components/cart-ec/cart-item-ec/cart-item-ec.component.mjs +6 -2
- package/esm2022/lib/ec-components/checkout-ec/payment-ec/payment-methods/mp-redirect-ec/mp-redirect-ec.component.mjs +79 -9
- package/esm2022/lib/ec-components/header-ec/header-ec.component.mjs +45 -34
- package/esm2022/lib/ec-components/product-ec/product-ec.component.mjs +95 -5
- package/esm2022/lib/ec-components/related-products-ec/related-products-ec.component.mjs +4 -6
- package/esm2022/lib/ec-components/widgets-ec/index.mjs +2 -1
- package/esm2022/lib/ec-components/widgets-ec/magnizoom-ec/magnizoom-ec.component.mjs +2 -4
- package/esm2022/lib/ec-components/widgets-ec/redsys-catch-ec/redsys-catch-ec.component.mjs +246 -0
- package/esm2022/lib/ec-services/analytics/facebook-pixel.service.mjs +2 -4
- package/esm2022/lib/ec-services/analytics/google-analytics.service.mjs +2 -4
- package/esm2022/lib/ec-services/options.service.mjs +3 -27
- package/fesm2022/ng-easycommerce-v18.mjs +536 -173
- package/fesm2022/ng-easycommerce-v18.mjs.map +1 -1
- package/lib/constants/api.constants.service.d.ts +24 -13
- package/lib/ec-components/auth-ec/login-form-ec/login-form-ec.component.d.ts +2 -0
- package/lib/ec-components/auth-ec/register-form-ec/register-form-ec.component.d.ts +2 -0
- package/lib/ec-components/cart-ec/cart-item-ec/cart-item-ec.component.d.ts +5 -0
- package/lib/ec-components/checkout-ec/payment-ec/payment-methods/mp-redirect-ec/mp-redirect-ec.component.d.ts +4 -0
- package/lib/ec-components/header-ec/header-ec.component.d.ts +5 -1
- package/lib/ec-components/product-ec/product-ec.component.d.ts +10 -1
- package/lib/ec-components/widgets-ec/index.d.ts +1 -0
- package/lib/ec-components/widgets-ec/redsys-catch-ec/redsys-catch-ec.component.d.ts +35 -0
- package/lib/ec-services/options.service.d.ts +0 -4
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject,
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, inject, Injectable, PLATFORM_ID, RendererFactory2, afterNextRender, signal, EnvironmentInjector, runInInjectionContext, Component, ChangeDetectorRef, HostListener, CUSTOM_ELEMENTS_SCHEMA, Input, Pipe, Injector, EventEmitter, Output, forwardRef, afterRender, ViewChild, Inject, computed, Renderer2, ChangeDetectionStrategy, Directive } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
|
-
import {
|
|
4
|
+
import { DOCUMENT, isPlatformBrowser, AsyncPipe, CommonModule, TitleCasePipe, JsonPipe, UpperCasePipe, Location } from '@angular/common';
|
|
5
5
|
import { take, BehaviorSubject, shareReplay, map, catchError, of, filter, ReplaySubject, firstValueFrom, concatMap, throwError, switchMap, combineLatest } from 'rxjs';
|
|
6
6
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
|
7
7
|
import * as i1$1 from '@ngx-translate/core';
|
|
@@ -14,7 +14,7 @@ import { ToastrService } from 'ngx-toastr';
|
|
|
14
14
|
import moment from 'moment';
|
|
15
15
|
import { StorageMap } from '@ngx-pwa/local-storage';
|
|
16
16
|
import * as i1$3 from '@angular/forms';
|
|
17
|
-
import { Validators, FormBuilder, NG_VALUE_ACCESSOR, ReactiveFormsModule
|
|
17
|
+
import { Validators, FormsModule, FormBuilder, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
|
|
18
18
|
import { register } from 'swiper/element/bundle';
|
|
19
19
|
import { register as register$1 } from 'swiper/element';
|
|
20
20
|
import * as i1$4 from '@angular/platform-browser';
|
|
@@ -44,82 +44,89 @@ const provideEnvironment = (environment) => {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Servicio que provee de datos
|
|
47
|
+
* Servicio que provee de datos que estan relacionado con las peticiones a la API
|
|
48
|
+
* @export
|
|
49
|
+
* @class ApiConstantsService
|
|
48
50
|
*/
|
|
49
51
|
class ApiConstantsService {
|
|
50
|
-
ssrApiUrl;
|
|
51
52
|
_localStorage = inject(LocalStorageService);
|
|
52
53
|
_translate = inject(TranslateService);
|
|
54
|
+
/**
|
|
55
|
+
* Contiene los datos provisto por el frontend en el archivo environment.ts
|
|
56
|
+
*/
|
|
53
57
|
environment = inject(ENVIRONMENT_TOKEN);
|
|
54
|
-
platformId = inject(PLATFORM_ID);
|
|
55
|
-
_channel;
|
|
56
|
-
LOCALE;
|
|
57
|
-
SHOP_API_URL = 'shop-api/';
|
|
58
|
-
CMS_URL = 'cms/';
|
|
59
|
-
constructor(ssrApiUrl) {
|
|
60
|
-
this.ssrApiUrl = ssrApiUrl;
|
|
61
|
-
this._channel = this.environment.channel;
|
|
62
|
-
this.LOCALE = this.environment.locale;
|
|
63
|
-
}
|
|
64
58
|
/**
|
|
65
59
|
* Canal actual del frontend
|
|
66
60
|
*/
|
|
67
61
|
get CHANNEL() {
|
|
62
|
+
// Verificar si estamos en el navegador (no en SSR)
|
|
68
63
|
if (typeof window !== 'undefined') {
|
|
64
|
+
// Primero intenta leer de window.__env (configurado por Docker)
|
|
69
65
|
const windowEnv = window.__env;
|
|
70
|
-
if (windowEnv?.channel)
|
|
66
|
+
if (windowEnv?.channel) {
|
|
71
67
|
return windowEnv.channel;
|
|
68
|
+
}
|
|
72
69
|
}
|
|
70
|
+
// Fallback al environment
|
|
73
71
|
return this._channel;
|
|
74
72
|
}
|
|
75
73
|
set CHANNEL(value) {
|
|
76
74
|
this._channel = value;
|
|
77
75
|
}
|
|
76
|
+
_channel;
|
|
77
|
+
/**
|
|
78
|
+
* Locale actual del frontend
|
|
79
|
+
*/
|
|
80
|
+
LOCALE;
|
|
81
|
+
/**
|
|
82
|
+
* URL para las peticiones a shop-api
|
|
83
|
+
*/
|
|
84
|
+
SHOP_API_URL = 'shop-api/';
|
|
85
|
+
/**
|
|
86
|
+
* URL para las peticiones a cms
|
|
87
|
+
*/
|
|
88
|
+
CMS_URL = 'cms/';
|
|
89
|
+
constructor() {
|
|
90
|
+
this._channel = this.environment.channel;
|
|
91
|
+
this.LOCALE = this.environment.locale;
|
|
92
|
+
}
|
|
78
93
|
/**
|
|
79
94
|
* URL del backend para realizar las peticiones
|
|
80
95
|
*/
|
|
81
96
|
get API_URL() {
|
|
82
|
-
//
|
|
97
|
+
// Verificar si estamos en el navegador (no en SSR)
|
|
83
98
|
if (typeof window !== 'undefined') {
|
|
99
|
+
// Primero intenta leer de window.__env (configurado por Docker)
|
|
84
100
|
const windowEnv = window.__env;
|
|
85
|
-
if (windowEnv?.
|
|
86
|
-
return windowEnv.
|
|
87
|
-
|
|
88
|
-
// SSR
|
|
89
|
-
if (isPlatformServer(this.platformId)) {
|
|
90
|
-
return this.ssrApiUrl;
|
|
101
|
+
if (windowEnv?.apiUrl) {
|
|
102
|
+
return windowEnv.apiUrl;
|
|
103
|
+
}
|
|
91
104
|
}
|
|
92
|
-
// Fallback environment
|
|
105
|
+
// Fallback al environment (para SSR y como backup)
|
|
93
106
|
return this.environment.apiUrl ?? '';
|
|
94
107
|
}
|
|
95
108
|
/**
|
|
96
|
-
*
|
|
97
|
-
|
|
98
|
-
getShopApiBase() {
|
|
99
|
-
const channel = this.CHANNEL || 'undefined';
|
|
100
|
-
const locale = this.LOCALE || 'undefined';
|
|
101
|
-
return `${this.API_URL}/${this.SHOP_API_URL}${channel}/?locale=${locale}`;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Retorna la url base general (sin shop-api)
|
|
109
|
+
* Retorna la url base
|
|
110
|
+
* @returns {string}
|
|
105
111
|
*/
|
|
106
112
|
getUrlBase() {
|
|
107
113
|
return this.API_URL;
|
|
108
114
|
}
|
|
109
115
|
/**
|
|
110
116
|
* Cambia el canal actual
|
|
117
|
+
* @param code
|
|
118
|
+
* @returns
|
|
111
119
|
*/
|
|
112
|
-
setChannel(code) {
|
|
113
|
-
this.CHANNEL = code;
|
|
114
|
-
}
|
|
120
|
+
setChannel(code) { this.CHANNEL = code; }
|
|
115
121
|
setLocale(locale) {
|
|
116
122
|
this._localStorage.setItem(this.LOCALE_KEY, locale);
|
|
117
123
|
this._translate.use(locale.split('_')[0]);
|
|
118
124
|
this.LOCALE = locale;
|
|
119
125
|
}
|
|
126
|
+
//Storage key
|
|
120
127
|
LOCALE_KEY = 'LOCALE';
|
|
121
128
|
CHANNEL_KEY = 'CHANNEL';
|
|
122
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApiConstantsService, deps: [
|
|
129
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApiConstantsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
123
130
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApiConstantsService, providedIn: 'root' });
|
|
124
131
|
}
|
|
125
132
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ApiConstantsService, decorators: [{
|
|
@@ -127,10 +134,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
127
134
|
args: [{
|
|
128
135
|
providedIn: 'root'
|
|
129
136
|
}]
|
|
130
|
-
}], ctorParameters: () => [
|
|
131
|
-
type: Inject,
|
|
132
|
-
args: ['API_URL']
|
|
133
|
-
}] }] });
|
|
137
|
+
}], ctorParameters: () => [] });
|
|
134
138
|
|
|
135
139
|
/**
|
|
136
140
|
* Servicio que funciona como abstracción para manejar la conexión con la API
|
|
@@ -529,10 +533,6 @@ class OptionsService {
|
|
|
529
533
|
* Maneja las peticiones a la API
|
|
530
534
|
*/
|
|
531
535
|
connection = inject(ConnectionService);
|
|
532
|
-
/**
|
|
533
|
-
* Platform ID para verificar si estamos en el navegador
|
|
534
|
-
*/
|
|
535
|
-
platformId = inject(PLATFORM_ID);
|
|
536
536
|
/**
|
|
537
537
|
* Constantes del core
|
|
538
538
|
*/
|
|
@@ -643,26 +643,7 @@ class OptionsService {
|
|
|
643
643
|
* @returns
|
|
644
644
|
*/
|
|
645
645
|
removeAccents(str) {
|
|
646
|
-
|
|
647
|
-
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
648
|
-
}
|
|
649
|
-
// Fallback para SSR - remover acentos manualmente
|
|
650
|
-
return str.replace(/[àáâãäå]/g, 'a')
|
|
651
|
-
.replace(/[èéêë]/g, 'e')
|
|
652
|
-
.replace(/[ìíîï]/g, 'i')
|
|
653
|
-
.replace(/[òóôõö]/g, 'o')
|
|
654
|
-
.replace(/[ùúûü]/g, 'u')
|
|
655
|
-
.replace(/[ýÿ]/g, 'y')
|
|
656
|
-
.replace(/[ñ]/g, 'n')
|
|
657
|
-
.replace(/[ç]/g, 'c')
|
|
658
|
-
.replace(/[ÀÁÂÃÄÅ]/g, 'A')
|
|
659
|
-
.replace(/[ÈÉÊË]/g, 'E')
|
|
660
|
-
.replace(/[ÌÍÎÏ]/g, 'I')
|
|
661
|
-
.replace(/[ÒÓÔÕÖ]/g, 'O')
|
|
662
|
-
.replace(/[ÙÚÛÜ]/g, 'U')
|
|
663
|
-
.replace(/[ÝŸ]/g, 'Y')
|
|
664
|
-
.replace(/[Ñ]/g, 'N')
|
|
665
|
-
.replace(/[Ç]/g, 'C');
|
|
646
|
+
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
666
647
|
}
|
|
667
648
|
/**
|
|
668
649
|
* Realiza un mapeo de los datos para darle un formato mas entendible a la
|
|
@@ -1045,9 +1026,7 @@ class FacebookPixelService {
|
|
|
1045
1026
|
this.renderer.appendChild(this.document?.body, new_analityc_script);
|
|
1046
1027
|
this.enabled = true;
|
|
1047
1028
|
}
|
|
1048
|
-
|
|
1049
|
-
setTimeout(() => this.callEvent('initialize'), 1000);
|
|
1050
|
-
}
|
|
1029
|
+
setTimeout(() => this.callEvent('initialize'), 1000);
|
|
1051
1030
|
}
|
|
1052
1031
|
/**
|
|
1053
1032
|
* Ejecuta el evento pasado por parametro.
|
|
@@ -1264,9 +1243,7 @@ class GoogleAnalyticsService {
|
|
|
1264
1243
|
this.renderer.appendChild(this.document?.head, declaration);
|
|
1265
1244
|
this.enabled = true;
|
|
1266
1245
|
}
|
|
1267
|
-
|
|
1268
|
-
setTimeout(() => this.startListeningPageViews(gtm_id), 1000);
|
|
1269
|
-
}
|
|
1246
|
+
setTimeout(() => this.startListeningPageViews(gtm_id), 1000);
|
|
1270
1247
|
}
|
|
1271
1248
|
/**
|
|
1272
1249
|
*
|
|
@@ -2667,31 +2644,6 @@ class User {
|
|
|
2667
2644
|
}
|
|
2668
2645
|
}
|
|
2669
2646
|
|
|
2670
|
-
/**
|
|
2671
|
-
* Función auxiliar para remover acentos de forma segura para SSR
|
|
2672
|
-
*/
|
|
2673
|
-
function safeRemoveAccents(str) {
|
|
2674
|
-
if (typeof window !== 'undefined' && typeof String.prototype.normalize === 'function') {
|
|
2675
|
-
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
2676
|
-
}
|
|
2677
|
-
// Fallback para SSR - remover acentos manualmente
|
|
2678
|
-
return str.replace(/[àáâãäå]/g, 'a')
|
|
2679
|
-
.replace(/[èéêë]/g, 'e')
|
|
2680
|
-
.replace(/[ìíîï]/g, 'i')
|
|
2681
|
-
.replace(/[òóôõö]/g, 'o')
|
|
2682
|
-
.replace(/[ùúûü]/g, 'u')
|
|
2683
|
-
.replace(/[ýÿ]/g, 'y')
|
|
2684
|
-
.replace(/[ñ]/g, 'n')
|
|
2685
|
-
.replace(/[ç]/g, 'c')
|
|
2686
|
-
.replace(/[ÀÁÂÃÄÅ]/g, 'A')
|
|
2687
|
-
.replace(/[ÈÉÊË]/g, 'E')
|
|
2688
|
-
.replace(/[ÌÍÎÏ]/g, 'I')
|
|
2689
|
-
.replace(/[ÒÓÔÕÖ]/g, 'O')
|
|
2690
|
-
.replace(/[ÙÚÛÜ]/g, 'U')
|
|
2691
|
-
.replace(/[ÝŸ]/g, 'Y')
|
|
2692
|
-
.replace(/[Ñ]/g, 'N')
|
|
2693
|
-
.replace(/[Ç]/g, 'C');
|
|
2694
|
-
}
|
|
2695
2647
|
class Filter {
|
|
2696
2648
|
data = [];
|
|
2697
2649
|
multi = false;
|
|
@@ -2711,7 +2663,7 @@ class Filter {
|
|
|
2711
2663
|
throw new Error("Method not implemented.");
|
|
2712
2664
|
}
|
|
2713
2665
|
removeAccents = (str) => {
|
|
2714
|
-
return
|
|
2666
|
+
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
2715
2667
|
};
|
|
2716
2668
|
setSelected(element, value) {
|
|
2717
2669
|
//console.log(element, value);
|
|
@@ -6202,6 +6154,11 @@ class HeaderEcComponent extends MenuEcComponent {
|
|
|
6202
6154
|
hidePrices = false;
|
|
6203
6155
|
__authService = inject(AuthService);
|
|
6204
6156
|
_channelService = inject(ChannelService);
|
|
6157
|
+
changeDetector = inject(ChangeDetectorRef);
|
|
6158
|
+
appRouter = inject(Router);
|
|
6159
|
+
platformId = inject(PLATFORM_ID);
|
|
6160
|
+
// Observable del estado de autenticación
|
|
6161
|
+
logged$;
|
|
6205
6162
|
isAuthenticated$ = this.__authService.isAuthenticated();
|
|
6206
6163
|
constructor() {
|
|
6207
6164
|
super();
|
|
@@ -6215,11 +6172,26 @@ class HeaderEcComponent extends MenuEcComponent {
|
|
|
6215
6172
|
coreConstantsService = inject(CoreConstantsService);
|
|
6216
6173
|
router = inject(Router);
|
|
6217
6174
|
cdr = inject(ChangeDetectorRef); // Inyectamos ChangeDetectorRef para forzar la actualización
|
|
6218
|
-
platformId = inject(PLATFORM_ID);
|
|
6219
6175
|
ngOnInit() {
|
|
6220
6176
|
this.channel = this.coreConstantsService.getChannel();
|
|
6221
6177
|
this.onWindowScroll();
|
|
6222
6178
|
this.detectRouteChange(); // Llamamos a la función que detecta el cambio de ruta
|
|
6179
|
+
// Usar el Observable del AuthService
|
|
6180
|
+
this.logged$ = this.__authService.loggedIn$;
|
|
6181
|
+
// Suscribirse al Observable y forzar detección de cambios cuando sea necesario
|
|
6182
|
+
this.logged$.subscribe(isLoggedIn => {
|
|
6183
|
+
this.changeDetector.detectChanges();
|
|
6184
|
+
});
|
|
6185
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
6186
|
+
this.appRouter.events.subscribe(evt => {
|
|
6187
|
+
if (evt instanceof NavigationEnd) {
|
|
6188
|
+
// Forzar detección de cambios después de navegación
|
|
6189
|
+
setTimeout(() => {
|
|
6190
|
+
this.changeDetector.detectChanges();
|
|
6191
|
+
}, 100);
|
|
6192
|
+
}
|
|
6193
|
+
});
|
|
6194
|
+
}
|
|
6223
6195
|
}
|
|
6224
6196
|
ngAfterViewInit() {
|
|
6225
6197
|
this.setupMobileMenu(); // Inicializamos el menú móvil
|
|
@@ -6238,21 +6210,17 @@ class HeaderEcComponent extends MenuEcComponent {
|
|
|
6238
6210
|
});
|
|
6239
6211
|
}
|
|
6240
6212
|
onWindowScroll() {
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
this.isScrolled = scrollTop > 80;
|
|
6244
|
-
}
|
|
6213
|
+
const scrollTop = window.scrollY;
|
|
6214
|
+
this.isScrolled = scrollTop > 80;
|
|
6245
6215
|
}
|
|
6246
6216
|
isHomeFunction() {
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
if (
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
headerElement.classList.remove('show-menu');
|
|
6255
|
-
}
|
|
6217
|
+
const headerElement = document.querySelector('header');
|
|
6218
|
+
if (headerElement) {
|
|
6219
|
+
if (this.router.url !== '/home') {
|
|
6220
|
+
headerElement.classList.add('show-menu');
|
|
6221
|
+
}
|
|
6222
|
+
else {
|
|
6223
|
+
headerElement.classList.remove('show-menu');
|
|
6256
6224
|
}
|
|
6257
6225
|
}
|
|
6258
6226
|
}
|
|
@@ -6276,30 +6244,26 @@ class HeaderEcComponent extends MenuEcComponent {
|
|
|
6276
6244
|
}
|
|
6277
6245
|
};
|
|
6278
6246
|
borrarInput(inputId) {
|
|
6279
|
-
if (
|
|
6280
|
-
|
|
6281
|
-
|
|
6247
|
+
if (inputId) {
|
|
6248
|
+
const input = document.getElementById(inputId);
|
|
6249
|
+
if (input) {
|
|
6250
|
+
input.value = '';
|
|
6251
|
+
}
|
|
6252
|
+
}
|
|
6253
|
+
else {
|
|
6254
|
+
const inputs = ['searchInput1'];
|
|
6255
|
+
inputs.forEach((id) => {
|
|
6256
|
+
const input = document.getElementById(id);
|
|
6282
6257
|
if (input) {
|
|
6283
6258
|
input.value = '';
|
|
6284
6259
|
}
|
|
6285
|
-
}
|
|
6286
|
-
else {
|
|
6287
|
-
const inputs = ['searchInput1'];
|
|
6288
|
-
inputs.forEach((id) => {
|
|
6289
|
-
const input = document.getElementById(id);
|
|
6290
|
-
if (input) {
|
|
6291
|
-
input.value = '';
|
|
6292
|
-
}
|
|
6293
|
-
});
|
|
6294
|
-
}
|
|
6260
|
+
});
|
|
6295
6261
|
}
|
|
6296
6262
|
this.searchValue = '';
|
|
6297
6263
|
this.coreConstantsService.searchValue = '';
|
|
6298
6264
|
this.getCollectionSearch();
|
|
6299
6265
|
}
|
|
6300
6266
|
setupMobileMenu() {
|
|
6301
|
-
if (!isPlatformBrowser(this.platformId))
|
|
6302
|
-
return;
|
|
6303
6267
|
// console.log('setupMobileMenu called');
|
|
6304
6268
|
const menuMobile = document.querySelector('.menuMobile');
|
|
6305
6269
|
if (!(menuMobile instanceof HTMLElement))
|
|
@@ -6335,8 +6299,6 @@ class HeaderEcComponent extends MenuEcComponent {
|
|
|
6335
6299
|
});
|
|
6336
6300
|
}
|
|
6337
6301
|
setupSearchInputs() {
|
|
6338
|
-
if (!isPlatformBrowser(this.platformId))
|
|
6339
|
-
return;
|
|
6340
6302
|
const inputs = ['searchInput1', 'searchInput2'];
|
|
6341
6303
|
inputs.forEach(id => {
|
|
6342
6304
|
const input = document.getElementById(id);
|
|
@@ -6933,6 +6895,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
6933
6895
|
class ProductEcComponent {
|
|
6934
6896
|
injector = inject(Injector);
|
|
6935
6897
|
routerService = inject(Router);
|
|
6898
|
+
_cartService = inject(CartService);
|
|
6899
|
+
_toastService = inject(ToastService);
|
|
6900
|
+
isAddingToCart = signal(false);
|
|
6901
|
+
quantity = signal(1);
|
|
6936
6902
|
/**
|
|
6937
6903
|
* Navega al detalle del producto y sube al inicio de la página
|
|
6938
6904
|
* @param productId ID del producto
|
|
@@ -7005,12 +6971,97 @@ class ProductEcComponent {
|
|
|
7005
6971
|
const discount = ((originalPrice - salePrice) / originalPrice) * 100;
|
|
7006
6972
|
return Math.round(discount);
|
|
7007
6973
|
}
|
|
6974
|
+
plus(stock, multipleQuantity) {
|
|
6975
|
+
console.log('Aumentando cantidad');
|
|
6976
|
+
const current = Number(this.quantity()); // <-- fuerza a número
|
|
6977
|
+
if (multipleQuantity && multipleQuantity > 0) {
|
|
6978
|
+
stock
|
|
6979
|
+
? (current < stock
|
|
6980
|
+
? this.quantity.set(current + multipleQuantity)
|
|
6981
|
+
: this._toastService.show('out-of-stock-actually'))
|
|
6982
|
+
: this.quantity.set(current + multipleQuantity);
|
|
6983
|
+
}
|
|
6984
|
+
else {
|
|
6985
|
+
stock
|
|
6986
|
+
? (current < stock
|
|
6987
|
+
? this.quantity.set(current + 1)
|
|
6988
|
+
: this._toastService.show('out-of-stock-actually'))
|
|
6989
|
+
: this.quantity.set(current + 1);
|
|
6990
|
+
}
|
|
6991
|
+
}
|
|
6992
|
+
less(multipleQuantity) {
|
|
6993
|
+
console.log('Disminuyendo cantidad');
|
|
6994
|
+
const current = Number(this.quantity()); // <-- fuerza a número
|
|
6995
|
+
if (multipleQuantity && multipleQuantity > 0) {
|
|
6996
|
+
current > multipleQuantity
|
|
6997
|
+
? this.quantity.set(current - multipleQuantity)
|
|
6998
|
+
: null;
|
|
6999
|
+
}
|
|
7000
|
+
else {
|
|
7001
|
+
current > 1 ? this.quantity.set(current - 1) : null;
|
|
7002
|
+
}
|
|
7003
|
+
}
|
|
7004
|
+
addToCart() {
|
|
7005
|
+
console.log('Añadiendo al carrito');
|
|
7006
|
+
if (this.isAddingToCart() || this.quantity() <= 0)
|
|
7007
|
+
return;
|
|
7008
|
+
// Verificar que tenemos el producto y sus variantes
|
|
7009
|
+
if (!this.product || !this.product.variants || this.product.variants.length === 0) {
|
|
7010
|
+
this._toastService.show('cant-buy');
|
|
7011
|
+
return;
|
|
7012
|
+
}
|
|
7013
|
+
// Verificar stock
|
|
7014
|
+
const firstVariant = this.product.variants[0];
|
|
7015
|
+
if (!firstVariant.stock || firstVariant.stock <= 0) {
|
|
7016
|
+
this._toastService.show('out-of-stock');
|
|
7017
|
+
return;
|
|
7018
|
+
}
|
|
7019
|
+
// Verificar que no se supere el stock disponible
|
|
7020
|
+
if (this.quantity() > firstVariant.stock) {
|
|
7021
|
+
this._toastService.show('out-of-stock-actually');
|
|
7022
|
+
return;
|
|
7023
|
+
}
|
|
7024
|
+
this.isAddingToCart.set(true);
|
|
7025
|
+
try {
|
|
7026
|
+
// Agregar al carrito usando CartService directamente
|
|
7027
|
+
this._cartService.addToCart(this.product, this.quantity(), firstVariant.code);
|
|
7028
|
+
console.log('Producto agregado al carrito exitosamente');
|
|
7029
|
+
// Resetear cantidad a 1 después de agregar al carrito
|
|
7030
|
+
this.quantity.set(1);
|
|
7031
|
+
}
|
|
7032
|
+
catch (error) {
|
|
7033
|
+
console.error('Error al agregar al carrito:', error);
|
|
7034
|
+
this._toastService.show('cant-buy');
|
|
7035
|
+
}
|
|
7036
|
+
setTimeout(() => {
|
|
7037
|
+
this.isAddingToCart.set(false);
|
|
7038
|
+
}, 2000);
|
|
7039
|
+
}
|
|
7040
|
+
checkStock(stock) {
|
|
7041
|
+
if (this.quantity() >= stock)
|
|
7042
|
+
this.quantity.set(stock);
|
|
7043
|
+
}
|
|
7044
|
+
onQuantityChange(event) {
|
|
7045
|
+
const target = event.target;
|
|
7046
|
+
const value = +target.value;
|
|
7047
|
+
// Validar que el valor sea mayor a 0
|
|
7048
|
+
if (value > 0) {
|
|
7049
|
+
this.quantity.set(value);
|
|
7050
|
+
// Validar contra el stock disponible
|
|
7051
|
+
const maxStock = this.product?.variants?.[0]?.stock || this.product?.stock || 0;
|
|
7052
|
+
this.checkStock(maxStock);
|
|
7053
|
+
}
|
|
7054
|
+
else {
|
|
7055
|
+
// Si el valor es 0 o negativo, resetear a 1
|
|
7056
|
+
this.quantity.set(1);
|
|
7057
|
+
}
|
|
7058
|
+
}
|
|
7008
7059
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductEcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7009
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ProductEcComponent, isStandalone: true, selector: "app-product-ec", inputs: { product: "product", isProductBox: "isProductBox", isCollection: "isCollection" }, outputs: { loaded: "loaded" }, ngImport: i0, template: "<a [routerLink]=\"['/product', product.id]\" class=\"text-decoration-none producto\">\r\n <!-- Marca especial y descuento -->\r\n <!-- <div *ngIf=\"product.saleprice || (product.special_mark && product.special_mark !== null && product.special_mark !== undefined && product.special_mark.length >0)\"\r\n class=\"marcas\">\r\n <div *ecProductStock=\"product\" [ecProductMini]=\"product.special_mark\"></div>\r\n <ng-container *ngIf=\"shouldShowPrice\">\r\n <div *ecProductStock=\"product\" [ngClass]=\"{'tag-dsc float-right': product.saleprice}\"\r\n [ecProductOff]=\"product\">\r\n </div>\r\n </ng-container>\r\n </div> -->\r\n\r\n <!-- Imagen del producto -->\r\n <div class=\"foto\">\r\n @if(product.picturesdefault){\r\n @if (product.picturesdefault && product.picturesdefault.length > 1 ) {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n <img [src]=\"mediaUrl + product.picturesdefault[1]\" alt=\"Imagen secundaria\" class=\"w-100 pic02\" />\r\n } @else {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n }\r\n }\r\n </div>\r\n <!-- Precio -->\r\n\r\n\r\n <!-- Nombre del producto -->\r\n <h6 class=\"title\">{{ product.name | titlecase }}</h6>\r\n\r\n <div class=\"sku\" [innerHTML]=\"product.shortdetails\"></div>\r\n\r\n @if (shouldShowPrice) {\r\n <app-price-ec [price]=\"product.price\" [saleprice]=\"product.saleprice\" class=\"\" />\r\n }\r\n @if(!hidePrices){\r\n @if(!showPricesOnlyToLoggedUsers || isAuthenticated$){\r\n\r\n <div class=\"fixBottom\">\r\n\r\n <!-- Bot\u00F3n de acciones -->\r\n <!-- <ng-container *ecProductStock=\"product; else noStock\"> -->\r\n <!-- Cuando no tiene marca especial o es de tipo 'standard' -->\r\n @if (!product.special_mark || product.special_mark.length === 0 || product.special_mark[0]?.type ===\r\n 'standard') {\r\n <button class=\"btn standard\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n <ng-container *ngIf=\"isCollection; else normalText\">\r\n <span> {{(\"buy\" | translate) | uppercase}} </span>\r\n </ng-container>\r\n <ng-template #normalText>\r\n {{(\"buy\" | translate) | uppercase}}\r\n </ng-template>\r\n </button>\r\n }@else {\r\n <!-- Caso 1: Agotado o Disponible muy pronto -->\r\n @if (product.special_mark[0]?.type === 'out_of_stock' || product.special_mark[0]?.type === 'coming_soon') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0].name | uppercase }} </span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>}\r\n <!-- Caso 2: Contacto por WhatsApp -->\r\n @if (product.special_mark[0].type === 'whatsapp_contact') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\"\r\n (click)=\"openWhatsApp(product.special_mark[0]?.whatsappContact)\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n\r\n </button>\r\n }\r\n <!-- Caso 3: Solicitar m\u00E1s informaci\u00F3n -->\r\n @if (product.special_mark[0]?.type === 'more_info') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n }}\r\n</a>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "component", type: PriceEcComponent, selector: "app-price-ec", inputs: ["price", "saleprice", "basePrice", "taxeAmount", "taxes", "priceSize", "showTaxLegendOnly", "disableTaxInfo", "customPriceTemplate", "customSalePriceTemplate", "customSimplePriceTemplate", "customSimpleSalePriceTemplate", "customTaxTemplate", "customOnlyTaxLabelTemplate"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
|
|
7060
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ProductEcComponent, isStandalone: true, selector: "app-product-ec", inputs: { product: "product", isProductBox: "isProductBox", isCollection: "isCollection" }, outputs: { loaded: "loaded" }, ngImport: i0, template: "<a [routerLink]=\"['/product', product.id]\" class=\"text-decoration-none producto\">\r\n <!-- Marca especial y descuento -->\r\n <!-- <div *ngIf=\"product.saleprice || (product.special_mark && product.special_mark !== null && product.special_mark !== undefined && product.special_mark.length >0)\"\r\n class=\"marcas\">\r\n <div *ecProductStock=\"product\" [ecProductMini]=\"product.special_mark\"></div>\r\n <ng-container *ngIf=\"shouldShowPrice\">\r\n <div *ecProductStock=\"product\" [ngClass]=\"{'tag-dsc float-right': product.saleprice}\"\r\n [ecProductOff]=\"product\">\r\n </div>\r\n </ng-container>\r\n </div> -->\r\n\r\n <!-- Imagen del producto -->\r\n <div class=\"foto\">\r\n @if(product.picturesdefault){\r\n @if (product.picturesdefault && product.picturesdefault.length > 1 ) {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n <img [src]=\"mediaUrl + product.picturesdefault[1]\" alt=\"Imagen secundaria\" class=\"w-100 pic02\" />\r\n } @else {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n }\r\n }\r\n </div>\r\n <!-- Precio -->\r\n\r\n\r\n <!-- Nombre del producto -->\r\n <h6 class=\"title\">{{ product.name | titlecase }}</h6>\r\n\r\n <div class=\"sku\" [innerHTML]=\"product.shortdetails\"></div>\r\n\r\n @if (shouldShowPrice) {\r\n <app-price-ec [price]=\"product.price\" [saleprice]=\"product.saleprice\" class=\"\" />\r\n }\r\n @if(!hidePrices){\r\n @if(!showPricesOnlyToLoggedUsers || isAuthenticated$){\r\n\r\n <div class=\"fixBottom\">\r\n\r\n <!-- Bot\u00F3n de acciones -->\r\n <!-- <ng-container *ecProductStock=\"product; else noStock\"> -->\r\n <!-- Cuando no tiene marca especial o es de tipo 'standard' -->\r\n @if (!product.special_mark || product.special_mark.length === 0 || product.special_mark[0]?.type ===\r\n 'standard') {\r\n <button class=\"btn standard\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n <ng-container *ngIf=\"isCollection; else normalText\">\r\n <span> {{(\"buy\" | translate) | uppercase}} </span>\r\n </ng-container>\r\n <ng-template #normalText>\r\n {{(\"buy\" | translate) | uppercase}}\r\n </ng-template>\r\n </button>\r\n }@else {\r\n <!-- Caso 1: Agotado o Disponible muy pronto -->\r\n @if (product.special_mark[0]?.type === 'out_of_stock' || product.special_mark[0]?.type === 'coming_soon') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0].name | uppercase }} </span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>}\r\n <!-- Caso 2: Contacto por WhatsApp -->\r\n @if (product.special_mark[0].type === 'whatsapp_contact') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\"\r\n (click)=\"openWhatsApp(product.special_mark[0]?.whatsappContact)\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n\r\n </button>\r\n }\r\n <!-- Caso 3: Solicitar m\u00E1s informaci\u00F3n -->\r\n @if (product.special_mark[0]?.type === 'more_info') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n }}\r\n</a>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "component", type: PriceEcComponent, selector: "app-price-ec", inputs: ["price", "saleprice", "basePrice", "taxeAmount", "taxes", "priceSize", "showTaxLegendOnly", "disableTaxInfo", "customPriceTemplate", "customSalePriceTemplate", "customSimplePriceTemplate", "customSimpleSalePriceTemplate", "customTaxTemplate", "customOnlyTaxLabelTemplate"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: FormsModule }] });
|
|
7010
7061
|
}
|
|
7011
7062
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ProductEcComponent, decorators: [{
|
|
7012
7063
|
type: Component,
|
|
7013
|
-
args: [{ selector: 'app-product-ec', standalone: true, imports: [CommonModule, PriceEcComponent, RouterLink, TranslateModule], template: "<a [routerLink]=\"['/product', product.id]\" class=\"text-decoration-none producto\">\r\n <!-- Marca especial y descuento -->\r\n <!-- <div *ngIf=\"product.saleprice || (product.special_mark && product.special_mark !== null && product.special_mark !== undefined && product.special_mark.length >0)\"\r\n class=\"marcas\">\r\n <div *ecProductStock=\"product\" [ecProductMini]=\"product.special_mark\"></div>\r\n <ng-container *ngIf=\"shouldShowPrice\">\r\n <div *ecProductStock=\"product\" [ngClass]=\"{'tag-dsc float-right': product.saleprice}\"\r\n [ecProductOff]=\"product\">\r\n </div>\r\n </ng-container>\r\n </div> -->\r\n\r\n <!-- Imagen del producto -->\r\n <div class=\"foto\">\r\n @if(product.picturesdefault){\r\n @if (product.picturesdefault && product.picturesdefault.length > 1 ) {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n <img [src]=\"mediaUrl + product.picturesdefault[1]\" alt=\"Imagen secundaria\" class=\"w-100 pic02\" />\r\n } @else {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n }\r\n }\r\n </div>\r\n <!-- Precio -->\r\n\r\n\r\n <!-- Nombre del producto -->\r\n <h6 class=\"title\">{{ product.name | titlecase }}</h6>\r\n\r\n <div class=\"sku\" [innerHTML]=\"product.shortdetails\"></div>\r\n\r\n @if (shouldShowPrice) {\r\n <app-price-ec [price]=\"product.price\" [saleprice]=\"product.saleprice\" class=\"\" />\r\n }\r\n @if(!hidePrices){\r\n @if(!showPricesOnlyToLoggedUsers || isAuthenticated$){\r\n\r\n <div class=\"fixBottom\">\r\n\r\n <!-- Bot\u00F3n de acciones -->\r\n <!-- <ng-container *ecProductStock=\"product; else noStock\"> -->\r\n <!-- Cuando no tiene marca especial o es de tipo 'standard' -->\r\n @if (!product.special_mark || product.special_mark.length === 0 || product.special_mark[0]?.type ===\r\n 'standard') {\r\n <button class=\"btn standard\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n <ng-container *ngIf=\"isCollection; else normalText\">\r\n <span> {{(\"buy\" | translate) | uppercase}} </span>\r\n </ng-container>\r\n <ng-template #normalText>\r\n {{(\"buy\" | translate) | uppercase}}\r\n </ng-template>\r\n </button>\r\n }@else {\r\n <!-- Caso 1: Agotado o Disponible muy pronto -->\r\n @if (product.special_mark[0]?.type === 'out_of_stock' || product.special_mark[0]?.type === 'coming_soon') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0].name | uppercase }} </span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>}\r\n <!-- Caso 2: Contacto por WhatsApp -->\r\n @if (product.special_mark[0].type === 'whatsapp_contact') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\"\r\n (click)=\"openWhatsApp(product.special_mark[0]?.whatsappContact)\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n\r\n </button>\r\n }\r\n <!-- Caso 3: Solicitar m\u00E1s informaci\u00F3n -->\r\n @if (product.special_mark[0]?.type === 'more_info') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n }}\r\n</a>" }]
|
|
7064
|
+
args: [{ selector: 'app-product-ec', standalone: true, imports: [CommonModule, PriceEcComponent, RouterLink, TranslateModule, FormsModule], template: "<a [routerLink]=\"['/product', product.id]\" class=\"text-decoration-none producto\">\r\n <!-- Marca especial y descuento -->\r\n <!-- <div *ngIf=\"product.saleprice || (product.special_mark && product.special_mark !== null && product.special_mark !== undefined && product.special_mark.length >0)\"\r\n class=\"marcas\">\r\n <div *ecProductStock=\"product\" [ecProductMini]=\"product.special_mark\"></div>\r\n <ng-container *ngIf=\"shouldShowPrice\">\r\n <div *ecProductStock=\"product\" [ngClass]=\"{'tag-dsc float-right': product.saleprice}\"\r\n [ecProductOff]=\"product\">\r\n </div>\r\n </ng-container>\r\n </div> -->\r\n\r\n <!-- Imagen del producto -->\r\n <div class=\"foto\">\r\n @if(product.picturesdefault){\r\n @if (product.picturesdefault && product.picturesdefault.length > 1 ) {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n <img [src]=\"mediaUrl + product.picturesdefault[1]\" alt=\"Imagen secundaria\" class=\"w-100 pic02\" />\r\n } @else {\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"Imagen principal\" class=\"w-100 pic01\" />\r\n }\r\n }\r\n </div>\r\n <!-- Precio -->\r\n\r\n\r\n <!-- Nombre del producto -->\r\n <h6 class=\"title\">{{ product.name | titlecase }}</h6>\r\n\r\n <div class=\"sku\" [innerHTML]=\"product.shortdetails\"></div>\r\n\r\n @if (shouldShowPrice) {\r\n <app-price-ec [price]=\"product.price\" [saleprice]=\"product.saleprice\" class=\"\" />\r\n }\r\n @if(!hidePrices){\r\n @if(!showPricesOnlyToLoggedUsers || isAuthenticated$){\r\n\r\n <div class=\"fixBottom\">\r\n\r\n <!-- Bot\u00F3n de acciones -->\r\n <!-- <ng-container *ecProductStock=\"product; else noStock\"> -->\r\n <!-- Cuando no tiene marca especial o es de tipo 'standard' -->\r\n @if (!product.special_mark || product.special_mark.length === 0 || product.special_mark[0]?.type ===\r\n 'standard') {\r\n <button class=\"btn standard\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n <ng-container *ngIf=\"isCollection; else normalText\">\r\n <span> {{(\"buy\" | translate) | uppercase}} </span>\r\n </ng-container>\r\n <ng-template #normalText>\r\n {{(\"buy\" | translate) | uppercase}}\r\n </ng-template>\r\n </button>\r\n }@else {\r\n <!-- Caso 1: Agotado o Disponible muy pronto -->\r\n @if (product.special_mark[0]?.type === 'out_of_stock' || product.special_mark[0]?.type === 'coming_soon') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0].name | uppercase }} </span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>}\r\n <!-- Caso 2: Contacto por WhatsApp -->\r\n @if (product.special_mark[0].type === 'whatsapp_contact') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\"\r\n (click)=\"openWhatsApp(product.special_mark[0]?.whatsappContact)\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n\r\n </button>\r\n }\r\n <!-- Caso 3: Solicitar m\u00E1s informaci\u00F3n -->\r\n @if (product.special_mark[0]?.type === 'more_info') {\r\n <button class=\"btn\" [ngClass]=\"isCollection ? 'px-2 w-100 d-sm-block' : 'py-2 px-4'\">\r\n @if(isCollection){\r\n <span>{{ product.special_mark[0]?.name | uppercase }}</span>\r\n }@else {\r\n {{ product.special_mark[0]?.name | uppercase }}\r\n }\r\n </button>\r\n }\r\n }\r\n </div>\r\n }}\r\n</a>" }]
|
|
7014
7065
|
}], ctorParameters: () => [], propDecorators: { product: [{
|
|
7015
7066
|
type: Input,
|
|
7016
7067
|
args: [{
|
|
@@ -7083,7 +7134,7 @@ class BlockProductsEcComponent extends BlockEcComponent {
|
|
|
7083
7134
|
* Permite personalización de las imágenes de las flechas mediante @Input.
|
|
7084
7135
|
*/
|
|
7085
7136
|
setupSwiperNavigation() {
|
|
7086
|
-
if (this.meta?.styles?.carrousel !== false
|
|
7137
|
+
if (this.meta?.styles?.carrousel !== false) {
|
|
7087
7138
|
// Usar setTimeout para asegurar que el swiper esté inicializado
|
|
7088
7139
|
setTimeout(() => {
|
|
7089
7140
|
this.initializeSwiperWithCustomNavigation();
|
|
@@ -7095,8 +7146,6 @@ class BlockProductsEcComponent extends BlockEcComponent {
|
|
|
7095
7146
|
* Esta función puede ser movida al componente base para reutilización.
|
|
7096
7147
|
*/
|
|
7097
7148
|
initializeSwiperWithCustomNavigation() {
|
|
7098
|
-
if (!isPlatformBrowser(this.platformId))
|
|
7099
|
-
return;
|
|
7100
7149
|
const prevButton = document.getElementById(`${this.meta?.code}-prev`);
|
|
7101
7150
|
const nextButton = document.getElementById(`${this.meta?.code}-next`);
|
|
7102
7151
|
const swiperElement = document.getElementById(this.meta?.code);
|
|
@@ -7456,9 +7505,7 @@ class MagnizoomEcComponent {
|
|
|
7456
7505
|
this.image = this.document.createElement('img');
|
|
7457
7506
|
this.image.onload = () => {
|
|
7458
7507
|
this.lensSize = { width: this.image.width / 2, height: this.image.height / 2 };
|
|
7459
|
-
|
|
7460
|
-
setTimeout(() => this.render());
|
|
7461
|
-
}
|
|
7508
|
+
setTimeout(() => this.render());
|
|
7462
7509
|
};
|
|
7463
7510
|
this.image.src = src;
|
|
7464
7511
|
}
|
|
@@ -7588,6 +7635,265 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
7588
7635
|
args: ['mainCanvas', { static: true }]
|
|
7589
7636
|
}] } });
|
|
7590
7637
|
|
|
7638
|
+
class ComponentHelper {
|
|
7639
|
+
constructor() {
|
|
7640
|
+
this.ecOnConstruct();
|
|
7641
|
+
}
|
|
7642
|
+
ecOnInit = (params = {}) => {
|
|
7643
|
+
};
|
|
7644
|
+
ecOnConstruct = (params = {}) => {
|
|
7645
|
+
};
|
|
7646
|
+
hasParams = (params, searched) => {
|
|
7647
|
+
if (!params || !searched)
|
|
7648
|
+
return false;
|
|
7649
|
+
const q = searched.trim().toLowerCase();
|
|
7650
|
+
return params.some(p => {
|
|
7651
|
+
const code = p?.['code']?.toString().toLowerCase() ?? '';
|
|
7652
|
+
// Primero chequeo exacto, y si no, parcial
|
|
7653
|
+
return code === q || code.includes(q);
|
|
7654
|
+
});
|
|
7655
|
+
};
|
|
7656
|
+
navigateOnRouter(router, url) {
|
|
7657
|
+
router.navigateByUrl(`/${url}`);
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
7660
|
+
|
|
7661
|
+
class RedsysCatchEcComponent extends ComponentHelper {
|
|
7662
|
+
activedRoute;
|
|
7663
|
+
router;
|
|
7664
|
+
checkoutService;
|
|
7665
|
+
renderer;
|
|
7666
|
+
elementRef;
|
|
7667
|
+
document;
|
|
7668
|
+
platformId;
|
|
7669
|
+
message = '';
|
|
7670
|
+
subscription = null;
|
|
7671
|
+
isMobile = false;
|
|
7672
|
+
sessionId = '';
|
|
7673
|
+
constructor(activedRoute, router, checkoutService, renderer, elementRef, document, platformId) {
|
|
7674
|
+
super();
|
|
7675
|
+
this.activedRoute = activedRoute;
|
|
7676
|
+
this.router = router;
|
|
7677
|
+
this.checkoutService = checkoutService;
|
|
7678
|
+
this.renderer = renderer;
|
|
7679
|
+
this.elementRef = elementRef;
|
|
7680
|
+
this.document = document;
|
|
7681
|
+
this.platformId = platformId;
|
|
7682
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
7683
|
+
this.detectMobile();
|
|
7684
|
+
this.sessionId = this.generateSessionId();
|
|
7685
|
+
// Verificar si debe procesar esta pestaña
|
|
7686
|
+
if (this.shouldProcessPayment()) {
|
|
7687
|
+
this.hideHeaderFooter();
|
|
7688
|
+
}
|
|
7689
|
+
else {
|
|
7690
|
+
// Si no debe procesar, cerrar esta pestaña y redirigir a la principal
|
|
7691
|
+
this.closeRedundantTab();
|
|
7692
|
+
return;
|
|
7693
|
+
}
|
|
7694
|
+
}
|
|
7695
|
+
this.ecOnConstruct();
|
|
7696
|
+
}
|
|
7697
|
+
detectMobile() {
|
|
7698
|
+
if (isPlatformBrowser(this.platformId) && typeof window !== 'undefined') {
|
|
7699
|
+
const userAgent = window.navigator.userAgent.toLowerCase();
|
|
7700
|
+
this.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(userAgent) ||
|
|
7701
|
+
(window.innerWidth <= 768);
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
generateSessionId() {
|
|
7705
|
+
return `catch_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
7706
|
+
}
|
|
7707
|
+
shouldProcessPayment() {
|
|
7708
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
7709
|
+
return false; // En el servidor no procesar
|
|
7710
|
+
}
|
|
7711
|
+
if (!this.isMobile) {
|
|
7712
|
+
return true; // En desktop siempre procesar
|
|
7713
|
+
}
|
|
7714
|
+
// En mobile, verificar si ya hay otra pestaña procesando
|
|
7715
|
+
const processingTab = localStorage.getItem('mp_processing_tab');
|
|
7716
|
+
const currentTime = Date.now();
|
|
7717
|
+
const processingTabTime = localStorage.getItem('mp_processing_tab_time');
|
|
7718
|
+
// Si no hay pestaña procesando o la anterior es muy antigua (más de 30 segundos)
|
|
7719
|
+
if (!processingTab || !processingTabTime || (currentTime - parseInt(processingTabTime)) > 30000) {
|
|
7720
|
+
// Esta pestaña será la que procese
|
|
7721
|
+
localStorage.setItem('mp_processing_tab', this.sessionId);
|
|
7722
|
+
localStorage.setItem('mp_processing_tab_time', currentTime.toString());
|
|
7723
|
+
return true;
|
|
7724
|
+
}
|
|
7725
|
+
// Si ya hay otra pestaña procesando
|
|
7726
|
+
return processingTab === this.sessionId;
|
|
7727
|
+
}
|
|
7728
|
+
closeRedundantTab() {
|
|
7729
|
+
console.log('Cerrando pestaña redundante...');
|
|
7730
|
+
// Intentar cerrar la pestaña
|
|
7731
|
+
if (isPlatformBrowser(this.platformId) && typeof window !== 'undefined') {
|
|
7732
|
+
// Redirigir a la página principal en lugar de cerrar
|
|
7733
|
+
window.location.href = '/checkout/order_success';
|
|
7734
|
+
}
|
|
7735
|
+
}
|
|
7736
|
+
ngOnInit() {
|
|
7737
|
+
this.subscription = combineLatest([
|
|
7738
|
+
this.activedRoute.params,
|
|
7739
|
+
this.activedRoute.queryParams
|
|
7740
|
+
]).subscribe(([queryRouter, queryParams]) => {
|
|
7741
|
+
let state;
|
|
7742
|
+
state = queryRouter['state'];
|
|
7743
|
+
if (state && state === 'statuspayment') {
|
|
7744
|
+
state = queryParams['status'];
|
|
7745
|
+
}
|
|
7746
|
+
console.log('PARAMETROS STATE -> ', state);
|
|
7747
|
+
this.handlePaymentState(state, queryParams);
|
|
7748
|
+
});
|
|
7749
|
+
this.ecOnInit();
|
|
7750
|
+
}
|
|
7751
|
+
ngOnDestroy() {
|
|
7752
|
+
if (this.subscription) {
|
|
7753
|
+
this.subscription.unsubscribe();
|
|
7754
|
+
}
|
|
7755
|
+
this.showHeaderFooter();
|
|
7756
|
+
// Limpiar marcadores de mobile si esta pestaña estaba procesando
|
|
7757
|
+
if (this.isMobile && isPlatformBrowser(this.platformId)) {
|
|
7758
|
+
const processingTab = localStorage.getItem('mp_processing_tab');
|
|
7759
|
+
if (processingTab === this.sessionId) {
|
|
7760
|
+
localStorage.removeItem('mp_processing_tab');
|
|
7761
|
+
localStorage.removeItem('mp_processing_tab_time');
|
|
7762
|
+
}
|
|
7763
|
+
}
|
|
7764
|
+
// this.ecOnDestroy(); // Removido si no existe en ComponentHelper
|
|
7765
|
+
}
|
|
7766
|
+
hideHeaderFooter() {
|
|
7767
|
+
// Usar Renderer2 en lugar de jQuery para manipular el DOM
|
|
7768
|
+
const header = this.document.querySelector('header');
|
|
7769
|
+
const footer = this.document.querySelector('footer');
|
|
7770
|
+
if (header) {
|
|
7771
|
+
this.renderer.setStyle(header, 'display', 'none');
|
|
7772
|
+
}
|
|
7773
|
+
if (footer) {
|
|
7774
|
+
this.renderer.setStyle(footer, 'display', 'none');
|
|
7775
|
+
}
|
|
7776
|
+
}
|
|
7777
|
+
showHeaderFooter() {
|
|
7778
|
+
// Restaurar la visibilidad al destruir el componente
|
|
7779
|
+
const header = this.document.querySelector('header');
|
|
7780
|
+
const footer = this.document.querySelector('footer');
|
|
7781
|
+
if (header) {
|
|
7782
|
+
this.renderer.removeStyle(header, 'display');
|
|
7783
|
+
}
|
|
7784
|
+
if (footer) {
|
|
7785
|
+
this.renderer.removeStyle(footer, 'display');
|
|
7786
|
+
}
|
|
7787
|
+
}
|
|
7788
|
+
handlePaymentState(state, queryParams) {
|
|
7789
|
+
// Solo procesar el estado si esta pestaña está autorizada
|
|
7790
|
+
if (this.isMobile && !this.shouldProcessPayment()) {
|
|
7791
|
+
console.log('Pestaña no autorizada para procesar el pago, redirigiendo...');
|
|
7792
|
+
this.closeRedundantTab();
|
|
7793
|
+
return;
|
|
7794
|
+
}
|
|
7795
|
+
switch (state) {
|
|
7796
|
+
case '200':
|
|
7797
|
+
this.setStateInLocal('Su pago fue procesado con éxito.', 'success');
|
|
7798
|
+
this.storeTotalAmount(queryParams);
|
|
7799
|
+
this.redirectToSuccess();
|
|
7800
|
+
break;
|
|
7801
|
+
case 'success':
|
|
7802
|
+
this.setStateInLocal('Su pago fue procesado con éxito.', state);
|
|
7803
|
+
this.storeTotalAmount(queryParams);
|
|
7804
|
+
this.redirectToSuccess();
|
|
7805
|
+
break;
|
|
7806
|
+
case 'pending':
|
|
7807
|
+
this.setStateInLocal('Su pago fue procesado con éxito.', state);
|
|
7808
|
+
this.redirectToSuccess();
|
|
7809
|
+
break;
|
|
7810
|
+
case 'failure':
|
|
7811
|
+
this.setStateInLocal('Se ha cancelado el proceso de pago.', state);
|
|
7812
|
+
this.storeTotalAmount(queryParams);
|
|
7813
|
+
this.redirectToCheckout();
|
|
7814
|
+
break;
|
|
7815
|
+
case 'cancel':
|
|
7816
|
+
this.setStateInLocal('Se ha cancelado el proceso de pago.', state);
|
|
7817
|
+
this.redirectToCheckout();
|
|
7818
|
+
break;
|
|
7819
|
+
case 'ok':
|
|
7820
|
+
this.setStateInSesion('Su pago fue procesado con éxito.', state);
|
|
7821
|
+
break;
|
|
7822
|
+
case 'challenge':
|
|
7823
|
+
this.setStateInSesion('Redirigiendo a autenticación del banco emisor.', state);
|
|
7824
|
+
break;
|
|
7825
|
+
case 'error':
|
|
7826
|
+
this.setStateInSesion('Algo no salio bien en la validación de sus datos.', state);
|
|
7827
|
+
break;
|
|
7828
|
+
case '0':
|
|
7829
|
+
this.setStateInLocal('Se ha cancelado el proceso de pago.', 'failure');
|
|
7830
|
+
this.redirectToCheckout();
|
|
7831
|
+
break;
|
|
7832
|
+
default:
|
|
7833
|
+
break;
|
|
7834
|
+
}
|
|
7835
|
+
}
|
|
7836
|
+
redirectToSuccess() {
|
|
7837
|
+
// Limpiar marcadores de procesamiento
|
|
7838
|
+
if (this.isMobile && isPlatformBrowser(this.platformId)) {
|
|
7839
|
+
localStorage.removeItem('mp_processing_tab');
|
|
7840
|
+
localStorage.removeItem('mp_processing_tab_time');
|
|
7841
|
+
}
|
|
7842
|
+
// Redirigir después de un breve delay
|
|
7843
|
+
setTimeout(() => {
|
|
7844
|
+
this.router.navigate(['/checkout/order_success']);
|
|
7845
|
+
}, 2000);
|
|
7846
|
+
}
|
|
7847
|
+
redirectToCheckout() {
|
|
7848
|
+
// Limpiar marcadores de procesamiento
|
|
7849
|
+
if (this.isMobile && isPlatformBrowser(this.platformId)) {
|
|
7850
|
+
localStorage.removeItem('mp_processing_tab');
|
|
7851
|
+
localStorage.removeItem('mp_processing_tab_time');
|
|
7852
|
+
}
|
|
7853
|
+
// Redirigir después de un breve delay
|
|
7854
|
+
setTimeout(() => {
|
|
7855
|
+
this.router.navigate(['/checkout']);
|
|
7856
|
+
}, 2000);
|
|
7857
|
+
}
|
|
7858
|
+
storeTotalAmount(queryParams) {
|
|
7859
|
+
const totalAmount = queryParams['total_amount'];
|
|
7860
|
+
if (totalAmount && isPlatformBrowser(this.platformId)) {
|
|
7861
|
+
localStorage.setItem('total_amount', totalAmount);
|
|
7862
|
+
}
|
|
7863
|
+
}
|
|
7864
|
+
setStateInLocal = (mensaje, state) => {
|
|
7865
|
+
this.message = mensaje;
|
|
7866
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
7867
|
+
localStorage.setItem('state', state);
|
|
7868
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
7869
|
+
sessionStorage.setItem('modalnews', 'false');
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
};
|
|
7873
|
+
setStateInSesion = (mensaje, state) => {
|
|
7874
|
+
this.message = mensaje;
|
|
7875
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
7876
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
7877
|
+
sessionStorage.setItem('state', state);
|
|
7878
|
+
sessionStorage.setItem('modalnews', 'false');
|
|
7879
|
+
}
|
|
7880
|
+
localStorage.setItem('state', state);
|
|
7881
|
+
}
|
|
7882
|
+
};
|
|
7883
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RedsysCatchEcComponent, deps: [{ token: i2.ActivatedRoute }, { token: i2.Router }, { token: CheckoutService }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
7884
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RedsysCatchEcComponent, isStandalone: true, selector: "app-redsys-catch-ec", usesInheritance: true, ngImport: i0, template: "<div id=\"container\">\r\n <div class=\"row\">\r\n <div class=\"col align-self-center\">\r\n <h4 class=\"titpage center-block text-center font-nexa font-lg my-3\">{{ message | uppercase }}</h4>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col align-self-center\">\r\n <h5 class=\"center-block text-center font-nexa my-3\">Redirigiendo en segundos...</h5>\r\n <br>\r\n <div class=\"d-flex flex-column jusitfy-content-center align-items-center\">\r\n <app-loading-full-ec></app-loading-full-ec>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".loader{border:16px solid #f3f3f3;border-top:16px solid #dc3545;border-radius:50%;width:50px;height:50px;animation:spin 2s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.flex-container{display:flex;justify-content:center;align-items:center;height:80vh;width:100%}.flex-container>div{width:90%;height:100px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: LoadingFullEcComponent, selector: "app-loading-full-ec" }] });
|
|
7885
|
+
}
|
|
7886
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RedsysCatchEcComponent, decorators: [{
|
|
7887
|
+
type: Component,
|
|
7888
|
+
args: [{ selector: 'app-redsys-catch-ec', standalone: true, imports: [CommonModule, LoadingFullEcComponent], template: "<div id=\"container\">\r\n <div class=\"row\">\r\n <div class=\"col align-self-center\">\r\n <h4 class=\"titpage center-block text-center font-nexa font-lg my-3\">{{ message | uppercase }}</h4>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col align-self-center\">\r\n <h5 class=\"center-block text-center font-nexa my-3\">Redirigiendo en segundos...</h5>\r\n <br>\r\n <div class=\"d-flex flex-column jusitfy-content-center align-items-center\">\r\n <app-loading-full-ec></app-loading-full-ec>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".loader{border:16px solid #f3f3f3;border-top:16px solid #dc3545;border-radius:50%;width:50px;height:50px;animation:spin 2s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.flex-container{display:flex;justify-content:center;align-items:center;height:80vh;width:100%}.flex-container>div{width:90%;height:100px}\n"] }]
|
|
7889
|
+
}], ctorParameters: () => [{ type: i2.ActivatedRoute }, { type: i2.Router }, { type: CheckoutService }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: Document, decorators: [{
|
|
7890
|
+
type: Inject,
|
|
7891
|
+
args: [DOCUMENT]
|
|
7892
|
+
}] }, { type: undefined, decorators: [{
|
|
7893
|
+
type: Inject,
|
|
7894
|
+
args: [PLATFORM_ID]
|
|
7895
|
+
}] }] });
|
|
7896
|
+
|
|
7591
7897
|
// export * from './rating-ec/rating-ec.component';
|
|
7592
7898
|
|
|
7593
7899
|
class BlockFormContactEcComponent extends BlockEcComponent {
|
|
@@ -7863,6 +8169,7 @@ class LoginFormEcComponent {
|
|
|
7863
8169
|
_formBuilder = inject(FormBuilder);
|
|
7864
8170
|
_toastService = inject(ToastService);
|
|
7865
8171
|
_router = inject(Router);
|
|
8172
|
+
showPassword = false;
|
|
7866
8173
|
/**
|
|
7867
8174
|
* Parametro para indicar si tras loguear
|
|
7868
8175
|
* debe redireccionar o no.
|
|
@@ -7951,6 +8258,9 @@ class LoginFormEcComponent {
|
|
|
7951
8258
|
? resolverFunction()
|
|
7952
8259
|
: this._router.navigateByUrl(this.redirectTo);
|
|
7953
8260
|
}
|
|
8261
|
+
togglePassword() {
|
|
8262
|
+
this.showPassword = !this.showPassword;
|
|
8263
|
+
}
|
|
7954
8264
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LoginFormEcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7955
8265
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LoginFormEcComponent, isStandalone: true, selector: "app-login-form-ec", inputs: { redirect: "redirect", redirectTo: "redirectTo", inCart: "inCart" }, outputs: { ready: "ready" }, ngImport: i0, template: "<div class=\"d-flex flex-column position-relative\">\r\n <h1 class=\"right-line ff-ubuntu-light mb-4\"><span>Ingresar</span></h1>\r\n <p class=\"ff-ubuntu-light font-sm pr-4 mb-4\">\r\n Si ya est\u00E1s registrado. Ingresa en tu cuenta con tu email y la\r\n contrase\u00F1a adecuada.\r\n </p>\r\n <div class=\"w-md-50 w-100 text-center\">\r\n <form [formGroup]=\"loginForm()\" (submit)=\"login($event)\">\r\n <input class=\"form-control mb-4 radius-0\" type=\"email\" formControlName=\"username\"\r\n placeholder=\"Correo Electr\u00F3nico\">\r\n <input class=\"form-control mb-4 radius-0\" type=\"password\" formControlName=\"password\"\r\n placeholder=\"Contrase\u00F1a\">\r\n\r\n <div class=\"row d-flex flex-column\">\r\n <div class=\"col-12 mb-4\">\r\n <button type=\"submit\"\r\n class=\"bg-gray border-0 px-4 py-2 color-white ff-ubuntu-light\">INGRESAR</button>\r\n </div>\r\n <div class=\"col-12 d-flex justify-content-center align-items-center\">\r\n <a [routerLink]=\"'/auth/forgot-password'\" class=\"font-md ff-ubuntu-light\">\r\n \u00BFOlvid\u00F3 su contrase\u00F1a?\r\n </a>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n @if(loading){\r\n <app-loading-section-ec></app-loading-section-ec>\r\n }\r\n</div>", styles: [""], dependencies: [{ kind: "component", type: LoadingSectionEcComponent, selector: "app-loading-section-ec" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
7956
8266
|
}
|
|
@@ -8050,6 +8360,7 @@ class RegisterFormEcComponent {
|
|
|
8050
8360
|
_analyticsService = inject(AnalyticsService);
|
|
8051
8361
|
_formBuilder = inject(FormBuilder);
|
|
8052
8362
|
channelConfigService = inject(ChannelService);
|
|
8363
|
+
showPassword = false;
|
|
8053
8364
|
/**
|
|
8054
8365
|
* Indica si debe redireccionar o se queda en la misma pantalla
|
|
8055
8366
|
*/
|
|
@@ -8165,6 +8476,9 @@ class RegisterFormEcComponent {
|
|
|
8165
8476
|
this.register_loading = false;
|
|
8166
8477
|
}
|
|
8167
8478
|
}
|
|
8479
|
+
togglePassword() {
|
|
8480
|
+
this.showPassword = !this.showPassword;
|
|
8481
|
+
}
|
|
8168
8482
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RegisterFormEcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
8169
8483
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: RegisterFormEcComponent, isStandalone: true, selector: "app-register-form-ec", inputs: { redirect: "redirect" }, outputs: { ready: "ready" }, ngImport: i0, template: "<div class=\"w-100 pl-md-5 position-relative\" id=\"register\">\r\n <div class=\"py-2\">\r\n <h5>CREAR CUENTA</h5>\r\n </div>\r\n <form id=\"registro\" [formGroup]=\"registerForm\" (submit)=\"register($event)\">\r\n <div class=\"form-group\">\r\n <label for=\"\" class=\"form-label\">NOMBRE</label>\r\n <input formControlName=\"firstName\" class=\"form-control rounded-0\" type=\"text\" placeholder=\"Nombre\">\r\n </div>\r\n <div class=\"form-group\">\r\n <label for=\"\" class=\"form-label\">APELLIDO</label>\r\n <input formControlName=\"lastName\" class=\"form-control rounded-0\" type=\"text\" placeholder=\"Apellido\">\r\n </div>\r\n <div class=\"form-group\">\r\n <label for=\"\" class=\"\">CORREO ELECTRONICO</label>\r\n <input formControlName=\"email\" email required class=\"form-control rounded-0\" type=\"email\"\r\n placeholder=\"Correo electr\u00F3nico\">\r\n </div>\r\n <div class=\"form-group\">\r\n <label for=\"\" class=\"form-label\">CONTRASE\u00D1A</label>\r\n <input formControlName=\"plainPassword\" required class=\"form-control rounded-0\" type=\"password\"\r\n placeholder=\"Contrase\u00F1a\">\r\n </div>\r\n <div class=\"form-group\">\r\n <label for=\"\" class=\"form-label\">REPETIR CONTRASE\u00D1A</label>\r\n <input formControlName=\"plainPassword2\" required class=\"form-control rounded-0\" type=\"password\"\r\n placeholder=\"Repetir contrase\u00F1a\">\r\n </div>\r\n\r\n <div class=\"custom-control d-flex flex-row form-check custom-checkbox mr-sm-2 mt-4 mb-2\">\r\n <input type=\"checkbox\" formControlName=\"terms\" required class=\"custom-control-input form-check-input\" name=\"Color2\"\r\n id=\"Color2\">\r\n <label class=\"custom-control-label ff-ubuntu-light font-sm form-check-label\" for=\"Color2\"> He\r\n le\u00EDdo y acepto las pol\u00EDticas de privacidad y los t\u00E9rminos y\r\n condiciones</label>\r\n </div>\r\n\r\n <div class=\"custom-control d-flex flex-row form-check custom-checkbox mr-sm-2 mb-4\">\r\n <input type=\"checkbox\" formControlName=\"newsletter\" class=\"custom-control-input form-check-input\" name=\"Color3\" id=\"Color3\">\r\n <label class=\"custom-control-label form-check-label ff-ubuntu-light font-sm\" for=\"Color3\">\r\n Suscripci\u00F3n al Newsletter</label>\r\n </div>\r\n\r\n <div class=\"row\">\r\n <div class=\"col-12\">\r\n <button [disabled]=\"registerForm.invalid\" type=\"submit\"\r\n class=\"btn btn-primary px-5 py-2 h-fit\">CREAR</button>\r\n </div>\r\n </div>\r\n </form>\r\n @if(loading){\r\n <app-loading-section-ec />\r\n }\r\n \r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1$3.CheckboxRequiredValidator, selector: "input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]" }, { kind: "directive", type: i1$3.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: LoadingSectionEcComponent, selector: "app-loading-section-ec" }] });
|
|
8170
8484
|
}
|
|
@@ -8319,29 +8633,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
8319
8633
|
type: Output
|
|
8320
8634
|
}] } });
|
|
8321
8635
|
|
|
8322
|
-
class ComponentHelper {
|
|
8323
|
-
constructor() {
|
|
8324
|
-
this.ecOnConstruct();
|
|
8325
|
-
}
|
|
8326
|
-
ecOnInit = (params = {}) => {
|
|
8327
|
-
};
|
|
8328
|
-
ecOnConstruct = (params = {}) => {
|
|
8329
|
-
};
|
|
8330
|
-
hasParams = (params, searched) => {
|
|
8331
|
-
if (!params || !searched)
|
|
8332
|
-
return false;
|
|
8333
|
-
const q = searched.trim().toLowerCase();
|
|
8334
|
-
return params.some(p => {
|
|
8335
|
-
const code = p?.['code']?.toString().toLowerCase() ?? '';
|
|
8336
|
-
// Primero chequeo exacto, y si no, parcial
|
|
8337
|
-
return code === q || code.includes(q);
|
|
8338
|
-
});
|
|
8339
|
-
};
|
|
8340
|
-
navigateOnRouter(router, url) {
|
|
8341
|
-
router.navigateByUrl(`/${url}`);
|
|
8342
|
-
}
|
|
8343
|
-
}
|
|
8344
|
-
|
|
8345
8636
|
class PasswordResetEcComponent extends ComponentHelper {
|
|
8346
8637
|
authService;
|
|
8347
8638
|
toastr;
|
|
@@ -8942,6 +9233,7 @@ class CartItemEcComponent {
|
|
|
8942
9233
|
_cartService = inject(CartService);
|
|
8943
9234
|
_toastService = inject(ToastService);
|
|
8944
9235
|
_constants = inject(CoreConstantsService);
|
|
9236
|
+
parametersService = inject(ParametersService);
|
|
8945
9237
|
mediaUrl = this._constants.mediaUrl();
|
|
8946
9238
|
quantity = 0;
|
|
8947
9239
|
variantsToShow = ['TALLA', 'COLOR'];
|
|
@@ -9028,6 +9320,9 @@ class CartItemEcComponent {
|
|
|
9028
9320
|
}
|
|
9029
9321
|
return false; // Solo se ejecuta si no se cumple la condición
|
|
9030
9322
|
}
|
|
9323
|
+
// PARAMETROS
|
|
9324
|
+
parameters$ = this.parametersService.getParameters();
|
|
9325
|
+
hasParams = this.parametersService.hasParams;
|
|
9031
9326
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CartItemEcComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9032
9327
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: CartItemEcComponent, isStandalone: true, selector: "app-cart-item-ec", inputs: { item: "item", inSidebar: "inSidebar" }, ngImport: i0, template: "@if(!inSidebar){\r\n<p>cart-item-ec works!</p>\r\n}@else{\r\n\r\n<div class=\"row\">\r\n <div class=\"col-3\">\r\n @let product= item.product;\r\n @if(item.variant_id && product.variants.length>0){\r\n <img [src]=\"mediaUrl + product.variants[0].images[0]\" alt=\"\" class=\"img-fluid\">\r\n }@else{\r\n <img [src]=\"mediaUrl + product.picturesdefault[0]\" alt=\"\" class=\"img-fluid\">\r\n }\r\n </div>\r\n <div class=\"col-7\">\r\n <div class=\"info d-flex flex-column align-items-start\">\r\n @if (item.product.special_mark?.length > 0 || item.product.saleprice) {\r\n <div class=\"marcas\">\r\n <img [src]=\"mediaUrl + (item.product.special_mark?.[0]?.images[0] || '')\" alt=\"\">\r\n\r\n @if (item.product.saleprice) {\r\n <div class=\"tag-dsc\">\r\n {{\r\n createDiscountMessage(item.product.saleprice,\r\n item.product.price)\r\n }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n <a class=\"title text-dark text-decoration-none m-0 p-0 h6 mb-0\"\r\n [routerLink]=\"['/product', item.variant_id]\">{{\r\n item.product.name | titlecase\r\n }}</a>\r\n <div class=\"qty1\">\r\n <span>{{ item.product.id}}</span>\r\n </div>\r\n <div class=\"price h6 fw-bold mb-0 pb-0\">{{ item.product.price | ecCurrencySymbol\r\n }}</div>\r\n @if(getVariants(item); as options){\r\n <div class=\"d-flex align-items-center p-0\">\r\n @for(option of options; track $index){\r\n <span class=\"me-1\"> {{option.name | titlecase}}:</span>\r\n @if(option.name == 'COLOR'){\r\n <div class=\"p-2 rounded\" [style.background]=\"'#' + option.value\"></div>\r\n }@else{\r\n <b>{{option.value}}</b>\r\n }\r\n }\r\n </div>\r\n }\r\n <div class=\"campoCantidad mt-2\">\r\n <div class=\"numero\">\r\n <button (click)=\"less(item.product.variants[0]?.stock)\" class=\"btn btn-outline-secondary\"\r\n type=\"button\" id=\"button-addon1\">\r\n <i class=\"fa fa-minus\" aria-hidden=\"true\"></i>\r\n </button>\r\n <input type=\"text\" class=\"form-control text-center\" placeholder=\"\"\r\n aria-label=\"Example text with button addon\" aria-describedby=\"button-addon1\"\r\n [value]=\"item.quantity\" min=\"1\" step=\"1\" [(ngModel)]=\"quantity\"\r\n (change)=\"updateQuantity(item.product.variants[0]?.stock)\">\r\n <button (click)=\"plus(item.product.variants[0]?.stock)\" class=\"btn btn-outline-secondary\"\r\n type=\"button\" id=\"button-addon1\">\r\n <i class=\"fa fa-plus\" aria-hidden=\"true\"></i>\r\n </button>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"col-2\">\r\n <a (click)=\"deleteCartItem()\" class=\"btn botBorrar\"><i class=\"fa fa-trash\" aria-hidden=\"true\"></i></a>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n}", styles: [""], dependencies: [{ kind: "pipe", type: TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: EcCurrencySymbolPipe, name: "ecCurrencySymbol" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
9033
9328
|
}
|
|
@@ -9550,16 +9845,33 @@ class MpRedirectEcComponent {
|
|
|
9550
9845
|
ventana;
|
|
9551
9846
|
window;
|
|
9552
9847
|
localStorage;
|
|
9848
|
+
isMobile = false;
|
|
9849
|
+
sessionId = '';
|
|
9553
9850
|
platformId = inject(PLATFORM_ID);
|
|
9554
9851
|
constructor() {
|
|
9555
9852
|
if (isPlatformBrowser(this.platformId)) {
|
|
9556
9853
|
this.window = window;
|
|
9557
9854
|
this.localStorage = localStorage;
|
|
9855
|
+
this.detectMobile();
|
|
9856
|
+
this.generateSessionId();
|
|
9558
9857
|
}
|
|
9559
9858
|
}
|
|
9560
9859
|
ngOnInit() {
|
|
9561
9860
|
this.getPreference();
|
|
9562
9861
|
}
|
|
9862
|
+
detectMobile() {
|
|
9863
|
+
if (isPlatformBrowser(this.platformId) && this.window) {
|
|
9864
|
+
const userAgent = this.window.navigator.userAgent.toLowerCase();
|
|
9865
|
+
this.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(userAgent) ||
|
|
9866
|
+
(this.window.innerWidth <= 768);
|
|
9867
|
+
}
|
|
9868
|
+
}
|
|
9869
|
+
generateSessionId() {
|
|
9870
|
+
this.sessionId = `mp_session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
9871
|
+
if (isPlatformBrowser(this.platformId) && this.localStorage) {
|
|
9872
|
+
this.localStorage.setItem('mp_session_id', this.sessionId);
|
|
9873
|
+
}
|
|
9874
|
+
}
|
|
9563
9875
|
clickClose = () => {
|
|
9564
9876
|
/* this.closeModal = 'cancel'
|
|
9565
9877
|
this.ventana?.close() */
|
|
@@ -9567,17 +9879,52 @@ class MpRedirectEcComponent {
|
|
|
9567
9879
|
iniciar = () => {
|
|
9568
9880
|
this.closeModal = '';
|
|
9569
9881
|
this.clearStorageState();
|
|
9570
|
-
|
|
9571
|
-
this.
|
|
9882
|
+
// Solo ejecutar en el browser
|
|
9883
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
9884
|
+
return;
|
|
9885
|
+
}
|
|
9886
|
+
// En mobile, marcamos esta pestaña como la principal
|
|
9887
|
+
if (this.isMobile && this.localStorage) {
|
|
9888
|
+
this.localStorage.setItem('mp_main_tab', this.sessionId);
|
|
9889
|
+
this.localStorage.setItem('mp_payment_started', 'true');
|
|
9890
|
+
}
|
|
9891
|
+
if (this.isMobile && this.window) {
|
|
9892
|
+
// En mobile, usar window.location.href en lugar de popup
|
|
9893
|
+
this.window.location.href = this.url;
|
|
9894
|
+
}
|
|
9895
|
+
else if (this.window) {
|
|
9896
|
+
// En desktop, usar popup como antes
|
|
9897
|
+
this.ventana = this.window.open(this.url);
|
|
9898
|
+
this.callState();
|
|
9899
|
+
}
|
|
9572
9900
|
};
|
|
9573
9901
|
callState = () => {
|
|
9902
|
+
// Solo ejecutar en el browser
|
|
9903
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
9904
|
+
return;
|
|
9905
|
+
}
|
|
9574
9906
|
let state = this.closeModal != '' ? this.closeModal : this.localStorage?.getItem('state');
|
|
9575
|
-
!state && this.ventana
|
|
9907
|
+
!state && this.ventana?.closed && (state = 'cancel');
|
|
9576
9908
|
this.loading = true;
|
|
9577
9909
|
state && console.log(state);
|
|
9910
|
+
// En mobile, verificar si esta pestaña debe procesar el estado
|
|
9911
|
+
if (this.isMobile && this.localStorage) {
|
|
9912
|
+
const mainTab = this.localStorage.getItem('mp_main_tab');
|
|
9913
|
+
const currentSessionId = this.localStorage.getItem('mp_session_id');
|
|
9914
|
+
// Si no es la pestaña principal, no procesar
|
|
9915
|
+
if (mainTab !== currentSessionId && mainTab !== null) {
|
|
9916
|
+
console.log('Esta no es la pestaña principal, ignorando estado');
|
|
9917
|
+
return;
|
|
9918
|
+
}
|
|
9919
|
+
}
|
|
9578
9920
|
if (state) {
|
|
9579
9921
|
this.loading = false;
|
|
9580
9922
|
this.localStorage?.removeItem('state');
|
|
9923
|
+
// Limpiar marcadores de mobile
|
|
9924
|
+
if (this.isMobile && this.localStorage) {
|
|
9925
|
+
this.localStorage.removeItem('mp_main_tab');
|
|
9926
|
+
this.localStorage.removeItem('mp_payment_started');
|
|
9927
|
+
}
|
|
9581
9928
|
if (state == 'success') {
|
|
9582
9929
|
this.ventana?.close();
|
|
9583
9930
|
this.ready.emit(true);
|
|
@@ -9602,17 +9949,31 @@ class MpRedirectEcComponent {
|
|
|
9602
9949
|
this.processError('');
|
|
9603
9950
|
return;
|
|
9604
9951
|
}
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9952
|
+
// Solo continuar polling si no es mobile o si es la pestaña principal
|
|
9953
|
+
if (!this.isMobile || (this.isMobile && this.localStorage?.getItem('mp_main_tab') === this.sessionId)) {
|
|
9954
|
+
setTimeout(() => {
|
|
9955
|
+
this.callState();
|
|
9956
|
+
}, 5000);
|
|
9957
|
+
}
|
|
9608
9958
|
};
|
|
9609
9959
|
processError = (err) => {
|
|
9610
9960
|
this._toastService.show(err != '' ? err : 'payment-error');
|
|
9611
9961
|
// console.log("ERROR ENVIO BACK ", err);
|
|
9612
9962
|
};
|
|
9613
9963
|
clearStorageState = () => {
|
|
9614
|
-
|
|
9964
|
+
// Solo ejecutar en el browser
|
|
9965
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
9966
|
+
return;
|
|
9967
|
+
}
|
|
9968
|
+
if (typeof sessionStorage !== 'undefined') {
|
|
9969
|
+
sessionStorage.removeItem('state');
|
|
9970
|
+
}
|
|
9615
9971
|
this.localStorage?.removeItem('state');
|
|
9972
|
+
// Limpiar también los marcadores de mobile
|
|
9973
|
+
if (this.isMobile && this.localStorage) {
|
|
9974
|
+
this.localStorage.removeItem('mp_processing_tab');
|
|
9975
|
+
this.localStorage.removeItem('mp_processing_tab_time');
|
|
9976
|
+
}
|
|
9616
9977
|
};
|
|
9617
9978
|
getPreference = () => this._paymentService.getPreference(this.allData).then(res => {
|
|
9618
9979
|
this.preference = res;
|
|
@@ -9623,7 +9984,11 @@ class MpRedirectEcComponent {
|
|
|
9623
9984
|
//this.error = message;
|
|
9624
9985
|
};
|
|
9625
9986
|
renderMP = (preference) => {
|
|
9626
|
-
|
|
9987
|
+
// Solo ejecutar en el browser
|
|
9988
|
+
if (!isPlatformBrowser(this.platformId) || !this.window) {
|
|
9989
|
+
return;
|
|
9990
|
+
}
|
|
9991
|
+
this.window.addEventListener("message", (event) => {
|
|
9627
9992
|
if (event.origin !== 'https://www.mercadopago.com.ar' || !event.data.type) {
|
|
9628
9993
|
return;
|
|
9629
9994
|
}
|
|
@@ -10504,11 +10869,9 @@ class RelatedProductsEcComponent extends BlockEcComponent {
|
|
|
10504
10869
|
this._relatedProductsSubject.next(relatedProducts);
|
|
10505
10870
|
res.map((products) => this._analyticsService.callEvent('view_item_list', { products: products.items, item_list_name: products.title || 'Related Products', item_list_id: products.id || 'related-products' }));
|
|
10506
10871
|
// Inicializar swiper después de que los datos estén disponibles
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
|
|
10510
|
-
}, 100);
|
|
10511
|
-
}
|
|
10872
|
+
setTimeout(() => {
|
|
10873
|
+
this.initSwiper();
|
|
10874
|
+
}, 100);
|
|
10512
10875
|
});
|
|
10513
10876
|
}
|
|
10514
10877
|
initSwiper() {
|
|
@@ -11760,5 +12123,5 @@ const directives = [
|
|
|
11760
12123
|
* Generated bundle index. Do not edit.
|
|
11761
12124
|
*/
|
|
11762
12125
|
|
|
11763
|
-
export { AccountEcComponent, AddressingService, AnalyticsService, AuthEcComponent, AuthService, AuthStorageService, BlockBannerBoxEcComponent, BlockBannerFullEcComponent, BlockFormContactEcComponent, BlockHtmlEcComponent, BlockNewsletterEcComponent, BlockProductsEcComponent, BlocksEcComponent, BlocksRepositoryService, BlocksService, BreadcrumbEcComponent, CartEcComponent, CartItemEcComponent, CartService, ChannelService, CheckoutEcComponent, CheckoutService, CollectionEcComponent, ConfirmAccountEcComponent, ContactEcComponent, CoreConstantsService, CouponEcComponent, CurrencyService, DopplerService, ENVIRONMENT_TOKEN, EcCurrencySymbolPipe, EcSafeHtmlPipe, FacebookPixelService, FaqsEcComponent, FiltersEcComponent, FiltersService, FiltersSortEcComponent, FooterEcComponent, ForgotPasswordEcComponent, FormService, GTMService, GoogleAnalyticsService, HeaderEcComponent, HomeEcComponent, LoadingFullEcComponent, LoadingInlineEcComponent, LoadingSectionEcComponent, LocalStorageService, LoginFormEcComponent, MagnizoomEcComponent, MetricoolPixelService, NgxLocalStorageService, OptionsService, OrderEcComponent, OrderUtilityService, OrdersListEcComponent, OrdersService, PaginationService, ParametersService, ParamsContext, PasswordResetEcComponent, PaymentService, PriceEcComponent, PriceRangeFilterComponent, ProductDetailEcComponent, ProductDetailService, ProductEcComponent, ProductOffDirective, ProductStockDirective, ProductsService, ReCaptchaEcComponent, ReCaptchaService, RegisterFormEcComponent, RegisterWholesalerFormEcComponent, RelatedProductsEcComponent, ReviewsEcComponent, ReviewsFormEcComponent, SectionContainerEcComponent, ShareEcComponent, ShipmentService, SidebarEcComponent, StoresEcComponent, SuccessEcComponent, TestService, ToastService, VariantsEcComponent, authGuard, authInterceptor, directives, provideEnvironment };
|
|
12126
|
+
export { AccountEcComponent, AddressingService, AnalyticsService, AuthEcComponent, AuthService, AuthStorageService, BlockBannerBoxEcComponent, BlockBannerFullEcComponent, BlockFormContactEcComponent, BlockHtmlEcComponent, BlockNewsletterEcComponent, BlockProductsEcComponent, BlocksEcComponent, BlocksRepositoryService, BlocksService, BreadcrumbEcComponent, CartEcComponent, CartItemEcComponent, CartService, ChannelService, CheckoutEcComponent, CheckoutService, CollectionEcComponent, ConfirmAccountEcComponent, ContactEcComponent, CoreConstantsService, CouponEcComponent, CurrencyService, DopplerService, ENVIRONMENT_TOKEN, EcCurrencySymbolPipe, EcSafeHtmlPipe, FacebookPixelService, FaqsEcComponent, FiltersEcComponent, FiltersService, FiltersSortEcComponent, FooterEcComponent, ForgotPasswordEcComponent, FormService, GTMService, GoogleAnalyticsService, HeaderEcComponent, HomeEcComponent, LoadingFullEcComponent, LoadingInlineEcComponent, LoadingSectionEcComponent, LocalStorageService, LoginFormEcComponent, MagnizoomEcComponent, MetricoolPixelService, NgxLocalStorageService, OptionsService, OrderEcComponent, OrderUtilityService, OrdersListEcComponent, OrdersService, PaginationService, ParametersService, ParamsContext, PasswordResetEcComponent, PaymentService, PriceEcComponent, PriceRangeFilterComponent, ProductDetailEcComponent, ProductDetailService, ProductEcComponent, ProductOffDirective, ProductStockDirective, ProductsService, ReCaptchaEcComponent, ReCaptchaService, RedsysCatchEcComponent, RegisterFormEcComponent, RegisterWholesalerFormEcComponent, RelatedProductsEcComponent, ReviewsEcComponent, ReviewsFormEcComponent, SectionContainerEcComponent, ShareEcComponent, ShipmentService, SidebarEcComponent, StoresEcComponent, SuccessEcComponent, TestService, ToastService, VariantsEcComponent, authGuard, authInterceptor, directives, provideEnvironment };
|
|
11764
12127
|
//# sourceMappingURL=ng-easycommerce-v18.mjs.map
|