@rsltda/components 1.0.11
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 +73 -0
- package/custom-elements.json +54 -0
- package/dist/components/rs-hello.d.ts +4 -0
- package/dist/components/rs-map.d.ts +97 -0
- package/dist/index.d.ts +8 -0
- package/dist/rs-components.es.js +1145 -0
- package/dist/rs-components.es.js.map +1 -0
- package/dist/rs-components.iife.js +411 -0
- package/dist/rs-components.iife.js.map +1 -0
- package/dist/utils/define.d.ts +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,1145 @@
|
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var q = (C, b, e) => b in C ? D(C, b, { enumerable: !0, configurable: !0, writable: !0, value: e }) : C[b] = e;
|
|
3
|
+
var s = (C, b, e) => q(C, typeof b != "symbol" ? b + "" : b, e);
|
|
4
|
+
function U(C, b) {
|
|
5
|
+
customElements.get(C) || customElements.define(C, b);
|
|
6
|
+
}
|
|
7
|
+
const I = "#1e88e5", L = "/assets/fontawesome/css/all.min.css", F = "https://cdn.rsltda.cl/logos/marker/", Z = "https://ap2.rs-shop.cl/web/PuntosMapas", O = {
|
|
8
|
+
ktm: "#ff6600"
|
|
9
|
+
}, M = {
|
|
10
|
+
sucursal: 0,
|
|
11
|
+
distribuidor: 1
|
|
12
|
+
}, R = ["norte", "rm", "centro", "sur"], $ = {
|
|
13
|
+
norte: "Zona Norte",
|
|
14
|
+
rm: "RM",
|
|
15
|
+
centro: "Zona Centro",
|
|
16
|
+
sur: "Zona Sur"
|
|
17
|
+
}, N = {
|
|
18
|
+
0: "Sucursales",
|
|
19
|
+
1: "Distribuidores"
|
|
20
|
+
}, T = 720 * 60 * 60 * 1e3, G = "rs-map-cache", P = "points", B = {
|
|
21
|
+
"region de arica y parinacota": "norte",
|
|
22
|
+
"arica y parinacota": "norte",
|
|
23
|
+
"region de tarapaca": "norte",
|
|
24
|
+
tarapaca: "norte",
|
|
25
|
+
"region de antofagasta": "norte",
|
|
26
|
+
antofagasta: "norte",
|
|
27
|
+
"region de atacama": "norte",
|
|
28
|
+
atacama: "norte",
|
|
29
|
+
"region de coquimbo": "norte",
|
|
30
|
+
coquimbo: "norte",
|
|
31
|
+
"region de valparaiso": "centro",
|
|
32
|
+
valparaiso: "centro",
|
|
33
|
+
"region del libertador general bernardo o higgins": "centro",
|
|
34
|
+
"region del libertador general bernardo o'higgins": "centro",
|
|
35
|
+
"libertador bernardo o'higgins": "centro",
|
|
36
|
+
ohiggins: "centro",
|
|
37
|
+
"region del maule": "centro",
|
|
38
|
+
maule: "centro",
|
|
39
|
+
"region de nuble": "centro",
|
|
40
|
+
nuble: "centro",
|
|
41
|
+
"region del biobio": "centro",
|
|
42
|
+
biobio: "centro",
|
|
43
|
+
"region metropolitana de santiago": "rm",
|
|
44
|
+
"region metropolitana": "rm",
|
|
45
|
+
rm: "rm",
|
|
46
|
+
santiago: "rm",
|
|
47
|
+
"region de la araucania": "sur",
|
|
48
|
+
araucania: "sur",
|
|
49
|
+
"region de los rios": "sur",
|
|
50
|
+
"los rios": "sur",
|
|
51
|
+
"region de los lagos": "sur",
|
|
52
|
+
"los lagos": "sur",
|
|
53
|
+
"region de aysen del general carlos ibanez del campo": "sur",
|
|
54
|
+
"region de aysen": "sur",
|
|
55
|
+
aysen: "sur",
|
|
56
|
+
"region de magallanes y la antartica chilena": "sur",
|
|
57
|
+
magallanes: "sur"
|
|
58
|
+
}, m = class m extends HTMLElement {
|
|
59
|
+
constructor() {
|
|
60
|
+
super();
|
|
61
|
+
s(this, "root");
|
|
62
|
+
s(this, "mapEl");
|
|
63
|
+
s(this, "map");
|
|
64
|
+
s(this, "markers", []);
|
|
65
|
+
s(this, "marca", "");
|
|
66
|
+
s(this, "marcaKey", "default");
|
|
67
|
+
s(this, "tipo", "");
|
|
68
|
+
s(this, "tipoCode", null);
|
|
69
|
+
s(this, "pointsController");
|
|
70
|
+
s(this, "points", []);
|
|
71
|
+
s(this, "pointsByZone", {
|
|
72
|
+
norte: [],
|
|
73
|
+
rm: [],
|
|
74
|
+
centro: [],
|
|
75
|
+
sur: []
|
|
76
|
+
});
|
|
77
|
+
s(this, "initialViewApplied", !1);
|
|
78
|
+
s(this, "zonesContainer");
|
|
79
|
+
s(this, "componentMessageEl");
|
|
80
|
+
s(this, "mapLayoutEl");
|
|
81
|
+
s(this, "zoneButtons", []);
|
|
82
|
+
s(this, "nearestButton");
|
|
83
|
+
s(this, "panelTitleEl");
|
|
84
|
+
s(this, "activeZone", "all");
|
|
85
|
+
s(this, "mapHeight", "");
|
|
86
|
+
s(this, "googleMapsApiKey", "");
|
|
87
|
+
s(this, "pointsApiUrl", Z);
|
|
88
|
+
s(this, "markerIconBaseUrl", F);
|
|
89
|
+
s(this, "defaultMarkerIconUrl", "");
|
|
90
|
+
s(this, "pointsCacheTtlMs", T);
|
|
91
|
+
s(this, "panAnimationFrame", null);
|
|
92
|
+
s(this, "highlightTimeout", null);
|
|
93
|
+
s(this, "isSyncingInitialAttributes", !1);
|
|
94
|
+
s(this, "refreshQueued", !1);
|
|
95
|
+
s(this, "handleZoneButtonClick", (e) => {
|
|
96
|
+
const n = e.currentTarget.dataset.zone;
|
|
97
|
+
n && (this.setActiveZone(n), this.scrollToZoneSection(n));
|
|
98
|
+
});
|
|
99
|
+
s(this, "handleNearestClick", () => {
|
|
100
|
+
if (!navigator.geolocation) {
|
|
101
|
+
alert("La geolocalizacion no esta soportada en este navegador.");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
navigator.geolocation.getCurrentPosition(
|
|
105
|
+
(e) => {
|
|
106
|
+
const { latitude: t, longitude: n } = e.coords, a = this.findNearestPoint(t, n);
|
|
107
|
+
a ? (this.centerMapOnPoint(Number(a.lat), Number(a.lng)), this.scrollToPointCard(a.id)) : alert("No hay puntos disponibles para calcular la tienda cercana.");
|
|
108
|
+
},
|
|
109
|
+
() => {
|
|
110
|
+
alert("No se pudo obtener tu ubicacion.");
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
m.ensureFontAwesome(), this.root = this.attachShadow({ mode: "open" }), this.root.innerHTML = `
|
|
115
|
+
<link rel="stylesheet" href="${L}" />
|
|
116
|
+
<style>
|
|
117
|
+
:host {
|
|
118
|
+
display: block;
|
|
119
|
+
width: 100%;
|
|
120
|
+
height: var(--map-height, 520px);
|
|
121
|
+
--rs-map-accent: ${I};
|
|
122
|
+
}
|
|
123
|
+
.map-layout {
|
|
124
|
+
display: grid;
|
|
125
|
+
grid-template-columns: minmax(0, 2.5fr) minmax(220px, 1fr);
|
|
126
|
+
gap: 16px;
|
|
127
|
+
width: 100%;
|
|
128
|
+
height: 100%;
|
|
129
|
+
}
|
|
130
|
+
.map-panel,
|
|
131
|
+
#map {
|
|
132
|
+
width: 100%;
|
|
133
|
+
height: 100%;
|
|
134
|
+
animation: mapSlide 90s infinite;
|
|
135
|
+
animation-timing-function: ease-in-out;
|
|
136
|
+
}
|
|
137
|
+
.map-panel {
|
|
138
|
+
border-radius: 8px;
|
|
139
|
+
overflow: hidden;
|
|
140
|
+
border: 2px solid var(--rs-map-accent);
|
|
141
|
+
}
|
|
142
|
+
#map {
|
|
143
|
+
background: #f5f5f5;
|
|
144
|
+
}
|
|
145
|
+
.component-shell {
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
height: 100%;
|
|
149
|
+
}
|
|
150
|
+
.component-message {
|
|
151
|
+
margin: 0;
|
|
152
|
+
font-size: 1rem;
|
|
153
|
+
color: #555;
|
|
154
|
+
text-align: center;
|
|
155
|
+
padding: 24px 12px;
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
justify-content: center;
|
|
159
|
+
flex: 1;
|
|
160
|
+
}
|
|
161
|
+
.component-message[hidden] {
|
|
162
|
+
display: none;
|
|
163
|
+
}
|
|
164
|
+
.map-layout[hidden] {
|
|
165
|
+
display: none;
|
|
166
|
+
}
|
|
167
|
+
.points-panel {
|
|
168
|
+
border: 1px solid #e0e0e0;
|
|
169
|
+
border-radius: 8px;
|
|
170
|
+
border-top: 4px solid var(--rs-map-accent);
|
|
171
|
+
padding: 16px;
|
|
172
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
173
|
+
background: #fff;
|
|
174
|
+
display: flex;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
overflow: hidden;
|
|
177
|
+
}
|
|
178
|
+
.panel-message {
|
|
179
|
+
margin: 0;
|
|
180
|
+
font-size: 0.95rem;
|
|
181
|
+
color: #555;
|
|
182
|
+
text-align: center;
|
|
183
|
+
padding: 32px 12px;
|
|
184
|
+
}
|
|
185
|
+
.panel-content[hidden] {
|
|
186
|
+
display: none;
|
|
187
|
+
}
|
|
188
|
+
.points-panel h2 {
|
|
189
|
+
margin: 0 0 8px;
|
|
190
|
+
font-size: 1rem;
|
|
191
|
+
color: var(--rs-map-accent);
|
|
192
|
+
}
|
|
193
|
+
.zone-filters {
|
|
194
|
+
display: flex;
|
|
195
|
+
gap: 8px;
|
|
196
|
+
margin-bottom: 12px;
|
|
197
|
+
overflow-x: auto;
|
|
198
|
+
padding-bottom: 8px;
|
|
199
|
+
flex-wrap: nowrap;
|
|
200
|
+
}
|
|
201
|
+
.zone-button {
|
|
202
|
+
border: 1px solid var(--rs-map-accent);
|
|
203
|
+
border-radius: 999px;
|
|
204
|
+
padding: 6px 12px;
|
|
205
|
+
font-size: 0.85rem;
|
|
206
|
+
background: transparent;
|
|
207
|
+
color: var(--rs-map-accent);
|
|
208
|
+
cursor: pointer;
|
|
209
|
+
transition: background 0.2s ease, color 0.2s ease;
|
|
210
|
+
text-align: center;
|
|
211
|
+
white-space: nowrap;
|
|
212
|
+
}
|
|
213
|
+
.zone-button:hover,
|
|
214
|
+
.zone-button:focus-visible {
|
|
215
|
+
background: var(--rs-map-accent);
|
|
216
|
+
color: #fff;
|
|
217
|
+
}
|
|
218
|
+
.zone-button.is-active {
|
|
219
|
+
background: var(--rs-map-accent);
|
|
220
|
+
color: #fff;
|
|
221
|
+
}
|
|
222
|
+
.zone-button--secondary {
|
|
223
|
+
flex-shrink: 0;
|
|
224
|
+
border-color: #444;
|
|
225
|
+
color: #444;
|
|
226
|
+
}
|
|
227
|
+
.zone-button--secondary i {
|
|
228
|
+
margin-right: 6px;
|
|
229
|
+
}
|
|
230
|
+
.panel-header {
|
|
231
|
+
margin-bottom: 12px;
|
|
232
|
+
display: flex;
|
|
233
|
+
align-items: center;
|
|
234
|
+
justify-content: space-between;
|
|
235
|
+
gap: 12px;
|
|
236
|
+
}
|
|
237
|
+
.panel-header h2[data-panel-title] {
|
|
238
|
+
margin: 0;
|
|
239
|
+
font-size: 1.25rem;
|
|
240
|
+
}
|
|
241
|
+
.zones-container {
|
|
242
|
+
display: flex;
|
|
243
|
+
flex-direction: column;
|
|
244
|
+
gap: 16px;
|
|
245
|
+
flex: 1;
|
|
246
|
+
overflow-y: auto;
|
|
247
|
+
}
|
|
248
|
+
.zone-section {
|
|
249
|
+
border-top: 2px solid #eee;
|
|
250
|
+
padding-top: 12px;
|
|
251
|
+
}
|
|
252
|
+
.zone-section[hidden] {
|
|
253
|
+
display: none;
|
|
254
|
+
}
|
|
255
|
+
.zone-section__header {
|
|
256
|
+
display: flex;
|
|
257
|
+
align-items: baseline;
|
|
258
|
+
justify-content: space-between;
|
|
259
|
+
margin: 0 0 8px;
|
|
260
|
+
font-weight: 600;
|
|
261
|
+
color: #333;
|
|
262
|
+
}
|
|
263
|
+
.zone-section__empty {
|
|
264
|
+
margin: 0;
|
|
265
|
+
font-size: 0.85rem;
|
|
266
|
+
color: #777;
|
|
267
|
+
}
|
|
268
|
+
.zone-section__list {
|
|
269
|
+
display: flex;
|
|
270
|
+
flex-direction: column;
|
|
271
|
+
gap: 10px;
|
|
272
|
+
}
|
|
273
|
+
.point-card {
|
|
274
|
+
border: 1px solid #e6e6e6;
|
|
275
|
+
border-radius: 8px;
|
|
276
|
+
padding: 10px;
|
|
277
|
+
background: #fff;
|
|
278
|
+
display: flex;
|
|
279
|
+
flex-direction: column;
|
|
280
|
+
gap: 6px;
|
|
281
|
+
overflow: hidden;
|
|
282
|
+
transition: border 0.2s ease, box-shadow 0.2s ease;
|
|
283
|
+
}
|
|
284
|
+
.point-card--highlight {
|
|
285
|
+
border: 2px solid var(--rs-map-accent);
|
|
286
|
+
box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);
|
|
287
|
+
animation: highlightFade 3s forwards;
|
|
288
|
+
}
|
|
289
|
+
@keyframes highlightFade {
|
|
290
|
+
0% {
|
|
291
|
+
border-color: var(--rs-map-accent);
|
|
292
|
+
box-shadow: 0 0 0 2px rgba(30, 136, 229, 0.2);
|
|
293
|
+
}
|
|
294
|
+
80% {
|
|
295
|
+
border-color: #111;
|
|
296
|
+
box-shadow: 0 0 0 2px rgba(17, 17, 17, 0.2);
|
|
297
|
+
}
|
|
298
|
+
100% {
|
|
299
|
+
border-color: #e6e6e6;
|
|
300
|
+
box-shadow: none;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
.point-card__title {
|
|
304
|
+
margin: -10px -10px 8px;
|
|
305
|
+
padding: 10px;
|
|
306
|
+
font-size: 0.95rem;
|
|
307
|
+
font-weight: 600;
|
|
308
|
+
text-align: center;
|
|
309
|
+
color: #fff;
|
|
310
|
+
background: var(--rs-map-accent);
|
|
311
|
+
}
|
|
312
|
+
.point-card__focus {
|
|
313
|
+
border: 1px solid var(--rs-map-accent);
|
|
314
|
+
border-radius: 999px;
|
|
315
|
+
padding: 4px 12px;
|
|
316
|
+
font-size: 0.8rem;
|
|
317
|
+
background: transparent;
|
|
318
|
+
color: var(--rs-map-accent);
|
|
319
|
+
cursor: pointer;
|
|
320
|
+
align-self: flex-start;
|
|
321
|
+
margin-top: 8px;
|
|
322
|
+
}
|
|
323
|
+
.point-card__focus:hover,
|
|
324
|
+
.point-card__focus:focus-visible {
|
|
325
|
+
background: var(--rs-map-accent);
|
|
326
|
+
color: #fff;
|
|
327
|
+
}
|
|
328
|
+
@media (max-width: 768px) {
|
|
329
|
+
.map-layout {
|
|
330
|
+
grid-template-columns: 1fr;
|
|
331
|
+
}
|
|
332
|
+
.map-panel {
|
|
333
|
+
display: none;
|
|
334
|
+
}
|
|
335
|
+
.panel-header {
|
|
336
|
+
flex-direction: column;
|
|
337
|
+
align-items: stretch;
|
|
338
|
+
}
|
|
339
|
+
.zone-filters {
|
|
340
|
+
flex-wrap: wrap;
|
|
341
|
+
}
|
|
342
|
+
.point-card__focus {
|
|
343
|
+
display: none;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
.point-card__address,
|
|
347
|
+
.point-card__meta,
|
|
348
|
+
.point-card__contact {
|
|
349
|
+
margin: 0;
|
|
350
|
+
font-size: 0.85rem;
|
|
351
|
+
color: #555;
|
|
352
|
+
}
|
|
353
|
+
.point-card__contact {
|
|
354
|
+
margin: 0 0 6px;
|
|
355
|
+
font-size: 0.85rem;
|
|
356
|
+
color: #555;
|
|
357
|
+
}
|
|
358
|
+
.point-card__contact-title {
|
|
359
|
+
display: flex;
|
|
360
|
+
align-items: center;
|
|
361
|
+
gap: 6px;
|
|
362
|
+
font-weight: 600;
|
|
363
|
+
color: #333;
|
|
364
|
+
margin-bottom: 4px;
|
|
365
|
+
}
|
|
366
|
+
.point-card__phone-list {
|
|
367
|
+
list-style: none;
|
|
368
|
+
padding: 0;
|
|
369
|
+
margin: 0;
|
|
370
|
+
display: flex;
|
|
371
|
+
flex-direction: column;
|
|
372
|
+
gap: 4px;
|
|
373
|
+
}
|
|
374
|
+
.point-card__phone-item {
|
|
375
|
+
display: flex;
|
|
376
|
+
gap: 8px;
|
|
377
|
+
align-items: flex-start;
|
|
378
|
+
}
|
|
379
|
+
.point-card__phone-icon {
|
|
380
|
+
width: 16px;
|
|
381
|
+
display: inline-flex;
|
|
382
|
+
justify-content: center;
|
|
383
|
+
color: var(--rs-map-accent);
|
|
384
|
+
font-size: 0.85rem;
|
|
385
|
+
}
|
|
386
|
+
.point-card__phone-content {
|
|
387
|
+
display: flex;
|
|
388
|
+
flex-direction: column;
|
|
389
|
+
gap: 2px;
|
|
390
|
+
}
|
|
391
|
+
.point-card__phone-name {
|
|
392
|
+
font-weight: 600;
|
|
393
|
+
color: #333;
|
|
394
|
+
}
|
|
395
|
+
.point-card__phone-number {
|
|
396
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
397
|
+
font-size: 0.85rem;
|
|
398
|
+
}
|
|
399
|
+
.point-card__phone-number--link {
|
|
400
|
+
color: var(--rs-map-accent);
|
|
401
|
+
text-decoration: none;
|
|
402
|
+
}
|
|
403
|
+
.point-card__phone-number--link:hover,
|
|
404
|
+
.point-card__phone-number--link:focus-visible {
|
|
405
|
+
text-decoration: underline;
|
|
406
|
+
}
|
|
407
|
+
.point-card__address-block {
|
|
408
|
+
display: flex;
|
|
409
|
+
flex-direction: column;
|
|
410
|
+
gap: 2px;
|
|
411
|
+
}
|
|
412
|
+
.point-card__details {
|
|
413
|
+
display: flex;
|
|
414
|
+
flex-direction: column;
|
|
415
|
+
gap: 6px;
|
|
416
|
+
margin-top: 6px;
|
|
417
|
+
}
|
|
418
|
+
.point-card__details[hidden] {
|
|
419
|
+
display: none;
|
|
420
|
+
}
|
|
421
|
+
.point-card__toggle {
|
|
422
|
+
border: 1px solid var(--rs-map-accent);
|
|
423
|
+
border-radius: 16px;
|
|
424
|
+
padding: 4px 10px;
|
|
425
|
+
background: transparent;
|
|
426
|
+
color: var(--rs-map-accent);
|
|
427
|
+
font-size: 0.8rem;
|
|
428
|
+
cursor: pointer;
|
|
429
|
+
align-self: flex-start;
|
|
430
|
+
display: inline-flex;
|
|
431
|
+
align-items: center;
|
|
432
|
+
gap: 6px;
|
|
433
|
+
}
|
|
434
|
+
.point-card__toggle:hover,
|
|
435
|
+
.point-card__toggle:focus-visible {
|
|
436
|
+
background: var(--rs-map-accent);
|
|
437
|
+
color: #fff;
|
|
438
|
+
}
|
|
439
|
+
.point-card__actions {
|
|
440
|
+
display: flex;
|
|
441
|
+
flex-direction: column;
|
|
442
|
+
align-items: flex-start;
|
|
443
|
+
gap: 6px;
|
|
444
|
+
margin-top: 8px;
|
|
445
|
+
}
|
|
446
|
+
.point-card__action {
|
|
447
|
+
display: inline-flex;
|
|
448
|
+
align-items: center;
|
|
449
|
+
gap: 6px;
|
|
450
|
+
font-size: 0.8rem;
|
|
451
|
+
}
|
|
452
|
+
.point-card__actions a.point-card__action {
|
|
453
|
+
color: var(--rs-map-accent);
|
|
454
|
+
text-decoration: none;
|
|
455
|
+
border-bottom: 1px solid transparent;
|
|
456
|
+
}
|
|
457
|
+
.point-card__actions a.point-card__action:hover,
|
|
458
|
+
.point-card__actions a.point-card__action:focus-visible {
|
|
459
|
+
border-color: currentColor;
|
|
460
|
+
}
|
|
461
|
+
.point-card__actions .point-card__action i {
|
|
462
|
+
font-size: 0.85rem;
|
|
463
|
+
}
|
|
464
|
+
.point-card__actions .point-card__action--text {
|
|
465
|
+
color: #444;
|
|
466
|
+
}
|
|
467
|
+
.point-card__extra {
|
|
468
|
+
margin: 0;
|
|
469
|
+
font-size: 0.8rem;
|
|
470
|
+
color: #444;
|
|
471
|
+
}
|
|
472
|
+
.point-card__extra a {
|
|
473
|
+
color: var(--rs-map-accent);
|
|
474
|
+
text-decoration: none;
|
|
475
|
+
display: inline-flex;
|
|
476
|
+
align-items: center;
|
|
477
|
+
gap: 4px;
|
|
478
|
+
}
|
|
479
|
+
.point-card__extra a:hover,
|
|
480
|
+
.point-card__extra a:focus-visible {
|
|
481
|
+
color: #444;
|
|
482
|
+
text-decoration: underline;
|
|
483
|
+
}
|
|
484
|
+
.point-card__extra-icon {
|
|
485
|
+
font-size: 0.75rem;
|
|
486
|
+
}
|
|
487
|
+
.empty-state {
|
|
488
|
+
margin: 0;
|
|
489
|
+
font-size: 0.9rem;
|
|
490
|
+
color: #777;
|
|
491
|
+
text-align: center;
|
|
492
|
+
}
|
|
493
|
+
.points-panel p {
|
|
494
|
+
margin: 0;
|
|
495
|
+
color: #666;
|
|
496
|
+
font-size: 0.9rem;
|
|
497
|
+
}
|
|
498
|
+
</style>
|
|
499
|
+
<div class="component-shell">
|
|
500
|
+
<p class="component-message" data-component-message>Cargando puntos...</p>
|
|
501
|
+
<div class="map-layout" data-map-layout hidden>
|
|
502
|
+
<div class="map-panel">
|
|
503
|
+
<div id="map"></div>
|
|
504
|
+
</div>
|
|
505
|
+
<aside class="points-panel" aria-live="polite">
|
|
506
|
+
<div class="zone-filters" role="group" aria-label="Filtrar por zona">
|
|
507
|
+
<button class="zone-button" type="button" data-zone="norte" data-label="Zona Norte" aria-pressed="false">Zona Norte</button>
|
|
508
|
+
<button class="zone-button" type="button" data-zone="rm" data-label="RM" aria-pressed="false">RM</button>
|
|
509
|
+
<button class="zone-button" type="button" data-zone="centro" data-label="Zona Centro" aria-pressed="false">Zona Centro</button>
|
|
510
|
+
<button class="zone-button" type="button" data-zone="sur" data-label="Zona Sur" aria-pressed="false">Zona Sur</button>
|
|
511
|
+
</div>
|
|
512
|
+
<div class="panel-header">
|
|
513
|
+
<h2 data-panel-title>Puntos del mapa</h2>
|
|
514
|
+
<button class="zone-button zone-button--secondary" type="button" data-action="nearest">
|
|
515
|
+
<i class="fa-solid fa-location-dot" aria-hidden="true"></i>
|
|
516
|
+
Buscar tienda cercana
|
|
517
|
+
</button>
|
|
518
|
+
</div>
|
|
519
|
+
<div class="zones-container" data-zone-container></div>
|
|
520
|
+
</aside>
|
|
521
|
+
</div>
|
|
522
|
+
</div>
|
|
523
|
+
`;
|
|
524
|
+
}
|
|
525
|
+
static get observedAttributes() {
|
|
526
|
+
return [
|
|
527
|
+
"marca",
|
|
528
|
+
"tipo",
|
|
529
|
+
"height",
|
|
530
|
+
"google-maps-key",
|
|
531
|
+
"points-api-url",
|
|
532
|
+
"cache-days",
|
|
533
|
+
"marker-icon-base",
|
|
534
|
+
"marker-icon-default"
|
|
535
|
+
];
|
|
536
|
+
}
|
|
537
|
+
connectedCallback() {
|
|
538
|
+
this.mapEl = this.root.querySelector("#map"), this.panelTitleEl = this.root.querySelector("[data-panel-title]"), this.zonesContainer = this.root.querySelector("[data-zone-container]"), this.componentMessageEl = this.root.querySelector("[data-component-message]"), this.mapLayoutEl = this.root.querySelector("[data-map-layout]"), this.zoneButtons = Array.from(this.root.querySelectorAll("[data-zone]")), this.nearestButton = this.root.querySelector('[data-action="nearest"]'), this.zoneButtons.forEach((e) => e.addEventListener("click", this.handleZoneButtonClick)), this.nearestButton && this.nearestButton.addEventListener("click", this.handleNearestClick), this.updateZoneButtons(), this.setMapHeight(this.getAttribute("height")), this.setComponentState("loading"), this.syncAttributesToState();
|
|
539
|
+
}
|
|
540
|
+
disconnectedCallback() {
|
|
541
|
+
var e;
|
|
542
|
+
(e = this.pointsController) == null || e.abort(), this.zoneButtons.forEach((t) => t.removeEventListener("click", this.handleZoneButtonClick)), this.nearestButton && this.nearestButton.removeEventListener("click", this.handleNearestClick);
|
|
543
|
+
}
|
|
544
|
+
attributeChangedCallback(e, t, n) {
|
|
545
|
+
e === "marca" ? this.setMarca(n != null ? n : "") : e === "tipo" ? this.setTipo(n != null ? n : "") : e === "height" ? this.setMapHeight(n) : e === "google-maps-key" ? this.setGoogleMapsKey(n) : e === "points-api-url" ? this.setPointsApiUrl(n) : e === "cache-days" ? this.setCacheDays(n) : e === "marker-icon-base" ? this.setMarkerIconBase(n) : e === "marker-icon-default" && this.setDefaultMarkerIcon(n);
|
|
546
|
+
}
|
|
547
|
+
loadGoogleMaps() {
|
|
548
|
+
return window._rsGoogleMapsLoaded ? Promise.resolve().then(() => {
|
|
549
|
+
this.initMap();
|
|
550
|
+
}) : this.googleMapsApiKey ? (m.googleMapsLoaderPromise || (m.googleMapsLoaderPromise = new Promise((e, t) => {
|
|
551
|
+
const n = document.querySelector('script[data-rs-google-maps="true"]');
|
|
552
|
+
if (n) {
|
|
553
|
+
n.addEventListener("load", () => e(), { once: !0 }), n.addEventListener(
|
|
554
|
+
"error",
|
|
555
|
+
() => t(new Error("Error al cargar la API de Google Maps")),
|
|
556
|
+
{ once: !0 }
|
|
557
|
+
);
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
const a = document.createElement("script"), r = new URLSearchParams({
|
|
561
|
+
key: this.googleMapsApiKey,
|
|
562
|
+
v: "weekly"
|
|
563
|
+
});
|
|
564
|
+
a.src = `https://maps.googleapis.com/maps/api/js?${r.toString()}`, a.async = !0, a.defer = !0, a.dataset.rsGoogleMaps = "true", a.onload = () => {
|
|
565
|
+
window._rsGoogleMapsLoaded = !0, e();
|
|
566
|
+
}, a.onerror = () => {
|
|
567
|
+
m.googleMapsLoaderPromise = null, t(new Error("Error al cargar la API de Google Maps"));
|
|
568
|
+
}, document.head.appendChild(a);
|
|
569
|
+
})), m.googleMapsLoaderPromise.then(() => {
|
|
570
|
+
window._rsGoogleMapsLoaded = !0, this.initMap();
|
|
571
|
+
}).catch((e) => {
|
|
572
|
+
console.error(e instanceof Error ? e.message : "Error al cargar la API de Google Maps");
|
|
573
|
+
})) : (console.error('Falta la clave de Google Maps. Define el atributo "google-maps-key" en <rs-map>.'), Promise.resolve());
|
|
574
|
+
}
|
|
575
|
+
initMap() {
|
|
576
|
+
const e = window.google;
|
|
577
|
+
if (!e) {
|
|
578
|
+
console.error("Google Maps aun no esta disponible.");
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const t = this.getInitialCenter();
|
|
582
|
+
this.map = new e.maps.Map(this.mapEl, {
|
|
583
|
+
center: t,
|
|
584
|
+
zoom: 14,
|
|
585
|
+
mapTypeId: "roadmap"
|
|
586
|
+
}), this.points.length && this.updateMarkers(this.points);
|
|
587
|
+
}
|
|
588
|
+
getInitialCenter() {
|
|
589
|
+
const e = this.getFirstValidPoint();
|
|
590
|
+
return e || { lat: -33.4489, lng: -70.6693 };
|
|
591
|
+
}
|
|
592
|
+
getFirstValidPoint() {
|
|
593
|
+
for (const e of this.points) {
|
|
594
|
+
const t = Number(e.lat), n = Number(e.lng);
|
|
595
|
+
if (Number.isFinite(t) && Number.isFinite(n))
|
|
596
|
+
return { lat: t, lng: n };
|
|
597
|
+
}
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
syncAttributesToState() {
|
|
601
|
+
var e, t;
|
|
602
|
+
this.isSyncingInitialAttributes = !0, this.setMarca((e = this.getAttribute("marca")) != null ? e : ""), this.setTipo((t = this.getAttribute("tipo")) != null ? t : ""), this.setGoogleMapsKey(this.getAttribute("google-maps-key")), this.setPointsApiUrl(this.getAttribute("points-api-url")), this.setCacheDays(this.getAttribute("cache-days")), this.setMarkerIconBase(this.getAttribute("marker-icon-base")), this.setDefaultMarkerIcon(this.getAttribute("marker-icon-default")), this.isSyncingInitialAttributes = !1, this.queueRefreshPoints();
|
|
603
|
+
}
|
|
604
|
+
setMapHeight(e) {
|
|
605
|
+
const t = (e != null ? e : "").trim();
|
|
606
|
+
if (!t) {
|
|
607
|
+
this.mapHeight = "", this.style.removeProperty("--map-height");
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
this.mapHeight = t, this.style.setProperty("--map-height", t);
|
|
611
|
+
}
|
|
612
|
+
setGoogleMapsKey(e) {
|
|
613
|
+
this.googleMapsApiKey = (e != null ? e : "").trim(), this.googleMapsApiKey && this.isConnected && this.loadGoogleMaps();
|
|
614
|
+
}
|
|
615
|
+
setPointsApiUrl(e) {
|
|
616
|
+
const t = (e != null ? e : "").trim();
|
|
617
|
+
this.pointsApiUrl = t || Z, this.pointsApiUrl && this.isConnected && !this.isSyncingInitialAttributes && this.queueRefreshPoints();
|
|
618
|
+
}
|
|
619
|
+
setCacheDays(e) {
|
|
620
|
+
const t = (e != null ? e : "").trim();
|
|
621
|
+
if (!t) {
|
|
622
|
+
this.pointsCacheTtlMs = T;
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
const n = Number(t);
|
|
626
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
627
|
+
this.pointsCacheTtlMs = T;
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
this.pointsCacheTtlMs = n * 24 * 60 * 60 * 1e3;
|
|
631
|
+
}
|
|
632
|
+
setMarkerIconBase(e) {
|
|
633
|
+
const t = (e != null ? e : "").trim();
|
|
634
|
+
if (!t) {
|
|
635
|
+
this.markerIconBaseUrl = F;
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
this.markerIconBaseUrl = t.endsWith("/") ? t : `${t}/`;
|
|
639
|
+
}
|
|
640
|
+
setDefaultMarkerIcon(e) {
|
|
641
|
+
this.defaultMarkerIconUrl = (e != null ? e : "").trim();
|
|
642
|
+
}
|
|
643
|
+
setMarca(e) {
|
|
644
|
+
this.marca = e.trim(), this.marcaKey = this.normalizeBrandKey(this.marca), this.applyBrandColor(), this.isSyncingInitialAttributes || this.queueRefreshPoints();
|
|
645
|
+
}
|
|
646
|
+
setTipo(e) {
|
|
647
|
+
this.tipo = e.trim(), this.tipoCode = this.normalizeTipo(this.tipo), this.updatePanelTitle(), this.isSyncingInitialAttributes || this.queueRefreshPoints();
|
|
648
|
+
}
|
|
649
|
+
queueRefreshPoints() {
|
|
650
|
+
this.refreshQueued || (this.refreshQueued = !0, queueMicrotask(() => {
|
|
651
|
+
this.refreshQueued = !1, this.refreshPoints();
|
|
652
|
+
}));
|
|
653
|
+
}
|
|
654
|
+
get marcaFilter() {
|
|
655
|
+
return this.marca;
|
|
656
|
+
}
|
|
657
|
+
get tipoFilter() {
|
|
658
|
+
return this.tipo;
|
|
659
|
+
}
|
|
660
|
+
updatePanelTitle() {
|
|
661
|
+
if (!this.panelTitleEl)
|
|
662
|
+
return;
|
|
663
|
+
const e = this.getTipoLabel();
|
|
664
|
+
this.panelTitleEl.textContent = e != null ? e : "Puntos del mapa";
|
|
665
|
+
}
|
|
666
|
+
getTipoLabel() {
|
|
667
|
+
if (this.tipoCode !== null && this.tipoCode in N)
|
|
668
|
+
return N[this.tipoCode];
|
|
669
|
+
const e = this.tipo.trim().toLowerCase(), t = e && e in M ? M[e] : null;
|
|
670
|
+
return t !== null && t in N ? N[t] : null;
|
|
671
|
+
}
|
|
672
|
+
applyBrandColor() {
|
|
673
|
+
var t;
|
|
674
|
+
const e = (t = O[this.marcaKey]) != null ? t : I;
|
|
675
|
+
this.style.setProperty("--rs-map-accent", e);
|
|
676
|
+
}
|
|
677
|
+
normalizeTipo(e) {
|
|
678
|
+
if (!e)
|
|
679
|
+
return null;
|
|
680
|
+
const t = e.trim().toLowerCase();
|
|
681
|
+
if (t in M)
|
|
682
|
+
return M[t];
|
|
683
|
+
const n = Number(t);
|
|
684
|
+
return Number.isFinite(n) && (n === 0 || n === 1) ? n : null;
|
|
685
|
+
}
|
|
686
|
+
async refreshPoints() {
|
|
687
|
+
var h;
|
|
688
|
+
if (!this.isConnected || !this.marca || this.tipoCode === null)
|
|
689
|
+
return;
|
|
690
|
+
if (!this.pointsApiUrl) {
|
|
691
|
+
console.error('Falta la URL de la API de puntos. Define el atributo "points-api-url" en <rs-map>.'), this.setComponentState("error");
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
(h = this.pointsController) == null || h.abort();
|
|
695
|
+
const e = new AbortController();
|
|
696
|
+
this.pointsController = e;
|
|
697
|
+
const t = new URLSearchParams({
|
|
698
|
+
marca: this.marca,
|
|
699
|
+
tipo: String(this.tipoCode)
|
|
700
|
+
}), n = this.pointsApiUrl.includes("?"), a = n && !/[?&]$/.test(this.pointsApiUrl), r = n ? a ? "&" : "" : "?", c = `${this.pointsApiUrl}${r}${t.toString()}`, i = this.getPointsCacheKey(c), l = await this.readPointsCache(i), d = l && Date.now() - l.timestamp < this.pointsCacheTtlMs;
|
|
701
|
+
if (l) {
|
|
702
|
+
if (this.applyPointsPayload(l.data), this.setComponentState("ready"), d)
|
|
703
|
+
return;
|
|
704
|
+
} else
|
|
705
|
+
this.setComponentState("loading");
|
|
706
|
+
try {
|
|
707
|
+
const p = await fetch(c, {
|
|
708
|
+
signal: e.signal
|
|
709
|
+
});
|
|
710
|
+
if (!p.ok)
|
|
711
|
+
throw new Error(`Respuesta ${p.status}`);
|
|
712
|
+
const u = await p.json();
|
|
713
|
+
if (!Array.isArray(u))
|
|
714
|
+
throw new Error("La respuesta de puntos no es valida.");
|
|
715
|
+
const y = u;
|
|
716
|
+
await this.writePointsCache(i, y), this.applyPointsPayload(y), this.setComponentState("ready");
|
|
717
|
+
} catch (p) {
|
|
718
|
+
if (p instanceof DOMException && p.name === "AbortError")
|
|
719
|
+
return;
|
|
720
|
+
if (l) {
|
|
721
|
+
console.warn("Se mantienen puntos cacheados por error al refrescar el mapa", p);
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
console.error("No se pudieron cargar los puntos del mapa", p), this.setComponentState("error");
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
applyPointsPayload(e) {
|
|
728
|
+
this.points = this.transformPoints(e), this.renderPoints(this.points), this.initialViewApplied = !1, this.updateMarkers(this.points);
|
|
729
|
+
}
|
|
730
|
+
getPointsCacheKey(e) {
|
|
731
|
+
return `rs-map:points:${e}`;
|
|
732
|
+
}
|
|
733
|
+
async readPointsCache(e) {
|
|
734
|
+
const t = await this.readPointsCacheFromIndexedDb(e);
|
|
735
|
+
if (t)
|
|
736
|
+
return t;
|
|
737
|
+
try {
|
|
738
|
+
const n = window.localStorage.getItem(e);
|
|
739
|
+
if (!n)
|
|
740
|
+
return null;
|
|
741
|
+
const a = JSON.parse(n);
|
|
742
|
+
return !a || !Array.isArray(a.data) || !Number.isFinite(a.timestamp) ? (window.localStorage.removeItem(e), null) : a;
|
|
743
|
+
} catch {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
async writePointsCache(e, t) {
|
|
748
|
+
const n = {
|
|
749
|
+
timestamp: Date.now(),
|
|
750
|
+
data: t
|
|
751
|
+
};
|
|
752
|
+
await this.writePointsCacheToIndexedDb(e, n);
|
|
753
|
+
try {
|
|
754
|
+
window.localStorage.setItem(e, JSON.stringify(n));
|
|
755
|
+
} catch {
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
async readPointsCacheFromIndexedDb(e) {
|
|
759
|
+
const t = await m.openPointsCacheDb();
|
|
760
|
+
return t ? new Promise((n) => {
|
|
761
|
+
const c = t.transaction(P, "readonly").objectStore(P).get(e);
|
|
762
|
+
c.onsuccess = () => {
|
|
763
|
+
const i = c.result;
|
|
764
|
+
if (!i || !Array.isArray(i.data) || !Number.isFinite(i.timestamp)) {
|
|
765
|
+
n(null);
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
n({
|
|
769
|
+
timestamp: i.timestamp,
|
|
770
|
+
data: i.data
|
|
771
|
+
});
|
|
772
|
+
}, c.onerror = () => n(null);
|
|
773
|
+
}) : null;
|
|
774
|
+
}
|
|
775
|
+
async writePointsCacheToIndexedDb(e, t) {
|
|
776
|
+
const n = await m.openPointsCacheDb();
|
|
777
|
+
n && await new Promise((a) => {
|
|
778
|
+
const i = n.transaction(P, "readwrite").objectStore(P).put({
|
|
779
|
+
key: e,
|
|
780
|
+
timestamp: t.timestamp,
|
|
781
|
+
data: t.data
|
|
782
|
+
});
|
|
783
|
+
i.onsuccess = () => a(), i.onerror = () => a();
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
static openPointsCacheDb() {
|
|
787
|
+
return typeof window == "undefined" || !("indexedDB" in window) ? Promise.resolve(null) : (m.pointsCacheDbPromise || (m.pointsCacheDbPromise = new Promise((e) => {
|
|
788
|
+
const t = window.indexedDB.open(G, 1);
|
|
789
|
+
t.onupgradeneeded = () => {
|
|
790
|
+
const n = t.result;
|
|
791
|
+
n.objectStoreNames.contains(P) || n.createObjectStore(P, { keyPath: "key" });
|
|
792
|
+
}, t.onsuccess = () => e(t.result), t.onerror = () => e(null);
|
|
793
|
+
})), m.pointsCacheDbPromise);
|
|
794
|
+
}
|
|
795
|
+
transformPoints(e) {
|
|
796
|
+
return e.map((t) => ({
|
|
797
|
+
...t,
|
|
798
|
+
zone: this.getZoneForPoint(t)
|
|
799
|
+
}));
|
|
800
|
+
}
|
|
801
|
+
renderPoints(e) {
|
|
802
|
+
if (!this.zonesContainer)
|
|
803
|
+
return;
|
|
804
|
+
const t = this.groupPoints(e);
|
|
805
|
+
this.pointsByZone = t, this.updateZoneButtonCounts();
|
|
806
|
+
const n = document.createDocumentFragment();
|
|
807
|
+
R.forEach((a) => {
|
|
808
|
+
const r = document.createElement("section");
|
|
809
|
+
r.className = "zone-section", r.dataset.zoneSection = a;
|
|
810
|
+
const c = document.createElement("div");
|
|
811
|
+
c.className = "zone-section__header";
|
|
812
|
+
const i = document.createElement("span");
|
|
813
|
+
if (i.textContent = $[a], c.appendChild(i), r.appendChild(c), t[a].length === 0) {
|
|
814
|
+
const l = document.createElement("p");
|
|
815
|
+
l.className = "zone-section__empty", l.textContent = "Sin puntos en esta zona.", r.appendChild(l);
|
|
816
|
+
} else {
|
|
817
|
+
const l = document.createElement("div");
|
|
818
|
+
l.className = "zone-section__list", t[a].forEach((d) => {
|
|
819
|
+
l.appendChild(this.createPointCard(d));
|
|
820
|
+
}), r.appendChild(l);
|
|
821
|
+
}
|
|
822
|
+
n.appendChild(r);
|
|
823
|
+
}), this.zonesContainer.replaceChildren(n), this.updateZoneVisibility();
|
|
824
|
+
}
|
|
825
|
+
groupPoints(e) {
|
|
826
|
+
const t = {
|
|
827
|
+
norte: [],
|
|
828
|
+
rm: [],
|
|
829
|
+
centro: [],
|
|
830
|
+
sur: []
|
|
831
|
+
};
|
|
832
|
+
return e.forEach((n) => {
|
|
833
|
+
t[n.zone].push(n);
|
|
834
|
+
}), t;
|
|
835
|
+
}
|
|
836
|
+
createPointCard(e) {
|
|
837
|
+
var y;
|
|
838
|
+
const t = document.createElement("article");
|
|
839
|
+
t.className = "point-card", t.dataset.pointId = String(e.id);
|
|
840
|
+
const n = document.createElement("h3");
|
|
841
|
+
n.className = "point-card__title", n.textContent = e.titulo || "Sin nombre", t.appendChild(n);
|
|
842
|
+
const a = document.createElement("div");
|
|
843
|
+
a.className = "point-card__address-block";
|
|
844
|
+
const r = document.createElement("p");
|
|
845
|
+
if (r.className = "point-card__address", r.textContent = e.direccion || "Sin direccion", a.appendChild(r), e.comuna_name) {
|
|
846
|
+
const o = document.createElement("p");
|
|
847
|
+
o.className = "point-card__meta", o.textContent = e.comuna_name, a.appendChild(o);
|
|
848
|
+
}
|
|
849
|
+
if (e.provincia_name) {
|
|
850
|
+
const o = document.createElement("p");
|
|
851
|
+
o.className = "point-card__meta", o.textContent = e.provincia_name, a.appendChild(o);
|
|
852
|
+
}
|
|
853
|
+
if (e.region_name) {
|
|
854
|
+
const o = document.createElement("p");
|
|
855
|
+
o.className = "point-card__meta", o.textContent = e.region_name, a.appendChild(o);
|
|
856
|
+
}
|
|
857
|
+
t.appendChild(a);
|
|
858
|
+
let c = null;
|
|
859
|
+
const i = Number(e.lat), l = Number(e.lng);
|
|
860
|
+
if (Number.isFinite(i) && Number.isFinite(l)) {
|
|
861
|
+
c = document.createElement("button"), c.type = "button", c.className = "point-card__focus";
|
|
862
|
+
const o = this.createIconElement("fa-solid fa-location-crosshairs");
|
|
863
|
+
c.appendChild(o), c.appendChild(document.createTextNode(" Ver en el mapa")), c.addEventListener("click", () => {
|
|
864
|
+
this.focusPointWithZoom(i, l), this.scrollToPointCard(e.id);
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
const d = document.createElement("div");
|
|
868
|
+
d.className = "point-card__details", d.hidden = !0;
|
|
869
|
+
let h = !1;
|
|
870
|
+
const p = document.createElement("div");
|
|
871
|
+
p.className = "point-card__actions";
|
|
872
|
+
let u = null;
|
|
873
|
+
if (e.url && e.url !== "#") {
|
|
874
|
+
const o = document.createElement("a");
|
|
875
|
+
o.href = e.url, o.target = "_blank", o.rel = "noopener noreferrer", o.className = "point-card__action";
|
|
876
|
+
const g = this.createIconElement("fa-solid fa-globe");
|
|
877
|
+
o.appendChild(g), o.appendChild(document.createTextNode("Sitio web")), p.appendChild(o);
|
|
878
|
+
}
|
|
879
|
+
if (e.email) {
|
|
880
|
+
const o = document.createElement("a");
|
|
881
|
+
o.href = `mailto:${e.email}`, o.target = "_blank", o.rel = "noopener noreferrer", o.className = "point-card__action point-card__action--text";
|
|
882
|
+
const g = this.createIconElement("fa-solid fa-envelope");
|
|
883
|
+
o.appendChild(g), o.appendChild(document.createTextNode(e.email)), p.appendChild(o);
|
|
884
|
+
}
|
|
885
|
+
if (p.childElementCount && (d.appendChild(p), h = !0), (y = e.telefonos) != null && y.length) {
|
|
886
|
+
const o = document.createElement("div");
|
|
887
|
+
o.className = "point-card__contact";
|
|
888
|
+
const g = document.createElement("div");
|
|
889
|
+
g.className = "point-card__contact-title";
|
|
890
|
+
const f = this.createIconElement("fa-solid fa-phone");
|
|
891
|
+
g.appendChild(f), g.appendChild(document.createTextNode("Telefonos")), o.appendChild(g);
|
|
892
|
+
const _ = document.createElement("ul");
|
|
893
|
+
_.className = "point-card__phone-list", e.telefonos.slice().sort((x, w) => x.orden - w.orden).forEach((x) => {
|
|
894
|
+
const w = document.createElement("li");
|
|
895
|
+
w.className = "point-card__phone-item";
|
|
896
|
+
const k = document.createElement("span");
|
|
897
|
+
if (k.className = "point-card__phone-icon", x.whatsapp) {
|
|
898
|
+
const z = this.createIconElement("fa-brands fa-whatsapp");
|
|
899
|
+
k.appendChild(z);
|
|
900
|
+
} else
|
|
901
|
+
k.textContent = "-";
|
|
902
|
+
w.appendChild(k);
|
|
903
|
+
const A = document.createElement("div");
|
|
904
|
+
A.className = "point-card__phone-content";
|
|
905
|
+
const S = document.createElement("span");
|
|
906
|
+
S.className = "point-card__phone-name", S.textContent = x.nombre, A.appendChild(S);
|
|
907
|
+
const E = x.whatsapp ? document.createElement("a") : document.createElement("span");
|
|
908
|
+
if (E.className = "point-card__phone-number", x.whatsapp) {
|
|
909
|
+
const z = this.getWhatsappLink(x.telefono);
|
|
910
|
+
z && (E.href = z, E.target = "_blank", E.rel = "noopener noreferrer", E.classList.add("point-card__phone-number--link"));
|
|
911
|
+
}
|
|
912
|
+
E.textContent = x.telefono, A.appendChild(E), w.appendChild(A), _.appendChild(w);
|
|
913
|
+
}), o.appendChild(_), d.appendChild(o), h = !0;
|
|
914
|
+
}
|
|
915
|
+
if (e.adicional) {
|
|
916
|
+
const o = document.createElement("p");
|
|
917
|
+
o.className = "point-card__extra", o.innerHTML = e.adicional, o.querySelectorAll("a").forEach((g) => {
|
|
918
|
+
g.classList.add("point-card__extra-link");
|
|
919
|
+
const f = this.createIconElement("fa-solid fa-arrow-up-right-from-square");
|
|
920
|
+
f.classList.add("point-card__extra-icon"), g.appendChild(f);
|
|
921
|
+
}), d.appendChild(o), h = !0;
|
|
922
|
+
}
|
|
923
|
+
if (e.googlelink) {
|
|
924
|
+
u = document.createElement("a"), u.href = e.googlelink, u.target = "_blank", u.rel = "noopener noreferrer", u.className = "point-card__action";
|
|
925
|
+
const o = this.createIconElement("fa-solid fa-map-location-dot");
|
|
926
|
+
u.appendChild(o), u.appendChild(document.createTextNode("Google Maps"));
|
|
927
|
+
}
|
|
928
|
+
if (u) {
|
|
929
|
+
const o = document.createElement("div");
|
|
930
|
+
o.className = "point-card__actions", o.appendChild(u), d.appendChild(o), h = !0;
|
|
931
|
+
}
|
|
932
|
+
if (h) {
|
|
933
|
+
const o = document.createElement("button");
|
|
934
|
+
o.type = "button", o.className = "point-card__toggle";
|
|
935
|
+
const g = this.createIconElement("fa-solid fa-circle-info"), f = document.createElement("span");
|
|
936
|
+
f.textContent = "Mas informacion", o.appendChild(g), o.appendChild(f), o.addEventListener("click", () => {
|
|
937
|
+
const _ = d.hidden;
|
|
938
|
+
d.hidden = !_, f.textContent = _ ? "Ocultar informacion" : "Mas informacion", g.className = _ ? "fa-solid fa-circle-xmark" : "fa-solid fa-circle-info";
|
|
939
|
+
}), t.appendChild(o), t.appendChild(d);
|
|
940
|
+
}
|
|
941
|
+
return c && t.appendChild(c), t;
|
|
942
|
+
}
|
|
943
|
+
getZoneForPoint(e) {
|
|
944
|
+
const t = this.normalizeRegionName(e.region_name || "");
|
|
945
|
+
return t && t in B ? B[t] : t.includes("metropolitana") ? "rm" : t.includes("araucania") || t.includes("rios") || t.includes("lagos") || t.includes("aysen") || t.includes("magallanes") ? "sur" : t.includes("arica") || t.includes("tarapaca") || t.includes("antofagasta") || t.includes("atacama") || t.includes("coquimbo") ? "norte" : "centro";
|
|
946
|
+
}
|
|
947
|
+
normalizeRegionName(e) {
|
|
948
|
+
return e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").trim();
|
|
949
|
+
}
|
|
950
|
+
normalizeBrandKey(e) {
|
|
951
|
+
return e && e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+/g, "") || "default";
|
|
952
|
+
}
|
|
953
|
+
getMarkerIcon() {
|
|
954
|
+
const e = this.marcaKey || "default";
|
|
955
|
+
return this.markerIconBaseUrl ? `${this.markerIconBaseUrl}${e}.png` : this.defaultMarkerIconUrl ? this.defaultMarkerIconUrl : null;
|
|
956
|
+
}
|
|
957
|
+
updateMarkers(e) {
|
|
958
|
+
const t = window.google;
|
|
959
|
+
if (!t || !this.map)
|
|
960
|
+
return;
|
|
961
|
+
this.markers.forEach((i) => i.setMap(null)), this.markers = [];
|
|
962
|
+
const n = e.filter((i) => {
|
|
963
|
+
const l = Number(i.lat), d = Number(i.lng);
|
|
964
|
+
return Number.isFinite(l) && Number.isFinite(d);
|
|
965
|
+
});
|
|
966
|
+
if (!n.length)
|
|
967
|
+
return;
|
|
968
|
+
const a = new t.maps.LatLngBounds(), r = this.getMarkerIcon(), c = r && this.map ? {
|
|
969
|
+
url: r,
|
|
970
|
+
scaledSize: new t.maps.Size(36, 36),
|
|
971
|
+
anchor: new t.maps.Point(18, 36)
|
|
972
|
+
} : void 0;
|
|
973
|
+
if (n.forEach((i) => {
|
|
974
|
+
const l = Number(i.lat), d = Number(i.lng), h = new t.maps.Marker({
|
|
975
|
+
map: this.map,
|
|
976
|
+
position: { lat: l, lng: d },
|
|
977
|
+
title: i.titulo,
|
|
978
|
+
icon: c
|
|
979
|
+
});
|
|
980
|
+
this.markers.push(h);
|
|
981
|
+
const p = h.getPosition();
|
|
982
|
+
p && a.extend(p);
|
|
983
|
+
}), !this.initialViewApplied && this.markers.length) {
|
|
984
|
+
const i = this.markers[0].getPosition();
|
|
985
|
+
if (i) {
|
|
986
|
+
this.map.setCenter(i), this.map.setZoom(14), this.initialViewApplied = !0;
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
if (this.markers.length === 1) {
|
|
991
|
+
const i = this.markers[0].getPosition();
|
|
992
|
+
i && this.map.setCenter(i), this.map.setZoom(14);
|
|
993
|
+
} else
|
|
994
|
+
this.map.fitBounds(a);
|
|
995
|
+
}
|
|
996
|
+
setActiveZone(e) {
|
|
997
|
+
}
|
|
998
|
+
scrollToZoneSection(e) {
|
|
999
|
+
if (!this.zonesContainer)
|
|
1000
|
+
return;
|
|
1001
|
+
const t = this.zonesContainer.querySelector(`[data-zone-section="${e}"]`);
|
|
1002
|
+
t && t.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
1003
|
+
}
|
|
1004
|
+
updateZoneButtons() {
|
|
1005
|
+
this.zoneButtons.forEach((e) => {
|
|
1006
|
+
const t = e.dataset.zone, n = this.activeZone === t;
|
|
1007
|
+
e.classList.toggle("is-active", n), e.setAttribute("aria-pressed", String(n));
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
updateZoneButtonCounts() {
|
|
1011
|
+
this.zoneButtons.forEach((e) => {
|
|
1012
|
+
e.dataset.zone;
|
|
1013
|
+
const t = e.dataset.label || e.textContent || "";
|
|
1014
|
+
e.textContent = t;
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
updateZoneVisibility() {
|
|
1018
|
+
if (!this.zonesContainer)
|
|
1019
|
+
return;
|
|
1020
|
+
this.zonesContainer.querySelectorAll("[data-zone-section]").forEach((t) => {
|
|
1021
|
+
t.removeAttribute("hidden");
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
findNearestPoint(e, t) {
|
|
1025
|
+
if (!this.points.length)
|
|
1026
|
+
return null;
|
|
1027
|
+
let n = null, a = 1 / 0;
|
|
1028
|
+
return this.points.forEach((r) => {
|
|
1029
|
+
const c = Number(r.lat), i = Number(r.lng);
|
|
1030
|
+
if (!Number.isFinite(c) || !Number.isFinite(i))
|
|
1031
|
+
return;
|
|
1032
|
+
const l = this.haversine(e, t, c, i);
|
|
1033
|
+
l < a && (a = l, n = r);
|
|
1034
|
+
}), n;
|
|
1035
|
+
}
|
|
1036
|
+
haversine(e, t, n, a) {
|
|
1037
|
+
const r = (p) => p * Math.PI / 180, i = r(n - e), l = r(a - t), d = Math.sin(i / 2) * Math.sin(i / 2) + Math.cos(r(e)) * Math.cos(r(n)) * Math.sin(l / 2) * Math.sin(l / 2);
|
|
1038
|
+
return 6371e3 * (2 * Math.atan2(Math.sqrt(d), Math.sqrt(1 - d)));
|
|
1039
|
+
}
|
|
1040
|
+
scrollToPointCard(e) {
|
|
1041
|
+
if (!this.zonesContainer)
|
|
1042
|
+
return;
|
|
1043
|
+
const t = this.zonesContainer.querySelector(`[data-point-id="${e}"]`);
|
|
1044
|
+
t && (t.scrollIntoView({ behavior: "smooth", block: "center" }), this.highlightPointCard(t));
|
|
1045
|
+
}
|
|
1046
|
+
highlightPointCard(e) {
|
|
1047
|
+
var t;
|
|
1048
|
+
this.highlightTimeout !== null && (clearTimeout(this.highlightTimeout), this.highlightTimeout = null), (t = this.zonesContainer) == null || t.querySelectorAll(".point-card--highlight").forEach((n) => {
|
|
1049
|
+
n.classList.remove("point-card--highlight");
|
|
1050
|
+
}), e.classList.add("point-card--highlight"), this.highlightTimeout = window.setTimeout(() => {
|
|
1051
|
+
e.classList.remove("point-card--highlight"), this.highlightTimeout = null;
|
|
1052
|
+
}, 3500);
|
|
1053
|
+
}
|
|
1054
|
+
setComponentState(e) {
|
|
1055
|
+
if (!(!this.componentMessageEl || !this.mapLayoutEl))
|
|
1056
|
+
if (e === "ready")
|
|
1057
|
+
this.componentMessageEl.setAttribute("hidden", ""), this.mapLayoutEl.removeAttribute("hidden");
|
|
1058
|
+
else {
|
|
1059
|
+
const t = e === "loading" ? "Cargando puntos..." : "Mapa temporalmente no disponible";
|
|
1060
|
+
this.componentMessageEl.textContent = t, this.componentMessageEl.removeAttribute("hidden"), this.mapLayoutEl.setAttribute("hidden", "");
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
centerMapOnPoint(e, t, n = 14) {
|
|
1064
|
+
if (!window.google || !this.map || !Number.isFinite(e) || !Number.isFinite(t))
|
|
1065
|
+
return;
|
|
1066
|
+
const r = typeof this.map.getZoom == "function" ? this.map.getZoom() : null, c = !r || r < n;
|
|
1067
|
+
this.animateMapPan(e, t, () => {
|
|
1068
|
+
c && this.map.setZoom(n);
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
async focusPointWithZoom(e, t) {
|
|
1072
|
+
!window.google || !this.map || !Number.isFinite(e) || !Number.isFinite(t) || (await this.animateZoomTo(8, 800), await this.wait(500), await new Promise((a) => {
|
|
1073
|
+
this.animateMapPan(e, t, a);
|
|
1074
|
+
}), await this.wait(500), await this.animateZoomTo(18, 800));
|
|
1075
|
+
}
|
|
1076
|
+
wait(e) {
|
|
1077
|
+
return new Promise((t) => {
|
|
1078
|
+
window.setTimeout(t, e);
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
async animateZoomTo(e, t = 600) {
|
|
1082
|
+
if (!window.google || !this.map || typeof this.map.getZoom != "function" || typeof this.map.setZoom != "function")
|
|
1083
|
+
return;
|
|
1084
|
+
const a = this.map.getZoom();
|
|
1085
|
+
if (!Number.isFinite(a)) {
|
|
1086
|
+
this.map.setZoom(e);
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
const r = e - a;
|
|
1090
|
+
if (Math.abs(r) < 0.01) {
|
|
1091
|
+
this.map.setZoom(e);
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
await new Promise((c) => {
|
|
1095
|
+
const i = performance.now(), l = (h) => 1 - Math.pow(1 - h, 3), d = (h) => {
|
|
1096
|
+
const p = h - i, u = Math.min(p / t, 1), y = l(u), o = a + r * y;
|
|
1097
|
+
this.map.setZoom(Math.round(o * 100) / 100), u < 1 ? requestAnimationFrame(d) : (this.map.setZoom(e), c());
|
|
1098
|
+
};
|
|
1099
|
+
requestAnimationFrame(d);
|
|
1100
|
+
});
|
|
1101
|
+
}
|
|
1102
|
+
animateMapPan(e, t, n) {
|
|
1103
|
+
if (!window.google || !this.map)
|
|
1104
|
+
return;
|
|
1105
|
+
this.panAnimationFrame !== null && (cancelAnimationFrame(this.panAnimationFrame), this.panAnimationFrame = null);
|
|
1106
|
+
const r = this.map.getCenter();
|
|
1107
|
+
if (!r) {
|
|
1108
|
+
this.map.setCenter({ lat: e, lng: t }), n == null || n();
|
|
1109
|
+
return;
|
|
1110
|
+
}
|
|
1111
|
+
const c = r.lat(), i = r.lng(), l = e - c, d = t - i, h = 600, p = performance.now(), u = (o) => 1 - Math.pow(1 - o, 3), y = (o) => {
|
|
1112
|
+
const g = o - p, f = Math.min(g / h, 1), _ = u(f), x = c + l * _, w = i + d * _;
|
|
1113
|
+
this.map.setCenter({ lat: x, lng: w }), f < 1 ? this.panAnimationFrame = requestAnimationFrame(y) : (this.panAnimationFrame = null, n == null || n());
|
|
1114
|
+
};
|
|
1115
|
+
this.panAnimationFrame = requestAnimationFrame(y);
|
|
1116
|
+
}
|
|
1117
|
+
static ensureFontAwesome() {
|
|
1118
|
+
if (m.fontAwesomeAttached)
|
|
1119
|
+
return;
|
|
1120
|
+
if (document.querySelector(`link[href="${L}"]`)) {
|
|
1121
|
+
m.fontAwesomeAttached = !0;
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
const t = document.createElement("link");
|
|
1125
|
+
t.rel = "stylesheet", t.href = L, t.crossOrigin = "anonymous", t.referrerPolicy = "no-referrer", t.addEventListener("load", () => {
|
|
1126
|
+
m.fontAwesomeAttached = !0;
|
|
1127
|
+
}), document.head.appendChild(t);
|
|
1128
|
+
}
|
|
1129
|
+
createIconElement(e) {
|
|
1130
|
+
const t = document.createElement("i");
|
|
1131
|
+
return t.className = e, t.setAttribute("aria-hidden", "true"), t;
|
|
1132
|
+
}
|
|
1133
|
+
getWhatsappLink(e) {
|
|
1134
|
+
const t = e.replace(/\D+/g, "");
|
|
1135
|
+
return t ? `https://wa.me/${t}` : null;
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
s(m, "tag", "rs-map"), s(m, "googleMapsLoaderPromise", null), s(m, "pointsCacheDbPromise", null), s(m, "fontAwesomeAttached", !1);
|
|
1139
|
+
let v = m;
|
|
1140
|
+
U(v.tag, v);
|
|
1141
|
+
export {
|
|
1142
|
+
v as RsMap,
|
|
1143
|
+
U as safeDefine
|
|
1144
|
+
};
|
|
1145
|
+
//# sourceMappingURL=rs-components.es.js.map
|