@influence-society-web/deshotelsetdesiles 4.1.3
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/dist/index.js +4 -0
- package/dist/index.js.map +7 -0
- package/dist/pages/CarnetDeVoyage.js +409 -0
- package/dist/pages/CarnetDeVoyage.js.map +7 -0
- package/dist/pages/DemanderUnDevis.js +409 -0
- package/dist/pages/DemanderUnDevis.js.map +7 -0
- package/dist/pages/Destinations.js +409 -0
- package/dist/pages/Destinations.js.map +7 -0
- package/dist/pages/Excursion.js +409 -0
- package/dist/pages/Excursion.js.map +7 -0
- package/dist/pages/Home.js +409 -0
- package/dist/pages/Home.js.map +7 -0
- package/dist/pages/HotelEtVilla.js +3651 -0
- package/dist/pages/HotelEtVilla.js.map +7 -0
- package/dist/pages/OfferSlug.js +3863 -0
- package/dist/pages/OfferSlug.js.map +7 -0
- package/dist/pages/Offers.js +955 -0
- package/dist/pages/Offers.js.map +7 -0
- package/dist/pages/OffersDeMinute.js +959 -0
- package/dist/pages/OffersDeMinute.js.map +7 -0
- package/dist/pages/OffersReservez.js +959 -0
- package/dist/pages/OffersReservez.js.map +7 -0
- package/dist/pages/Themes.js +995 -0
- package/dist/pages/Themes.js.map +7 -0
- package/dist/pages/Villas.js +409 -0
- package/dist/pages/Villas.js.map +7 -0
- package/dist/splide.min.css +1 -0
- package/package.json +42 -0
- package/src/index.ts +0 -0
|
@@ -0,0 +1,955 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(() => {
|
|
3
|
+
// src/utils/constants.ts
|
|
4
|
+
var prefix = "data";
|
|
5
|
+
var SELECTORS = {
|
|
6
|
+
startingPriceList: `[${prefix}=starting-price-list]`,
|
|
7
|
+
price: `[${prefix}=price]`,
|
|
8
|
+
discount: `[${prefix}=discount]`,
|
|
9
|
+
discountContainer: `[${prefix}=discount-container]`,
|
|
10
|
+
currency: `[${prefix}=currency]`,
|
|
11
|
+
beHid: `[${prefix}-be-hid]`,
|
|
12
|
+
destination: `[${prefix}=destination]`,
|
|
13
|
+
offersList: `[${prefix}=offers-list]`,
|
|
14
|
+
/** Offer slug page: wrapper with existing main offer. Match both data="..." and data-... for Webflow. */
|
|
15
|
+
offerSlugDetail: `[${prefix}=offer-slug-detail], [data-offer-slug-detail]`,
|
|
16
|
+
/** Offer slug page: "Nos autres offres" list container. */
|
|
17
|
+
offerSlugOthersList: `[${prefix}=offer-slug-others-list], [data-offer-slug-others-list]`,
|
|
18
|
+
/** Offer slug page: card template inside offer-slug-others-list (use .offer-others_item if no data-list-item). */
|
|
19
|
+
offerSlugOthersListItem: ".offer-others_item",
|
|
20
|
+
/** Offer slug page: "Nos autres offres" section wrapper. Shown when other offers are rendered. */
|
|
21
|
+
offersMoreWrapper: `[${prefix}=offers-more-wrapper]`,
|
|
22
|
+
offersListContainer: `[${prefix}=offers-list-container]`,
|
|
23
|
+
listItem: `[${prefix}=list-item]`,
|
|
24
|
+
image: `[${prefix}=image]`,
|
|
25
|
+
name: `[${prefix}=name]`,
|
|
26
|
+
description: `[${prefix}=description]`,
|
|
27
|
+
hotelName: `[${prefix}=hotel-name]`,
|
|
28
|
+
hotelLink: `[${prefix}=hotel-link]`,
|
|
29
|
+
hotelStartingPriceContainer: `[${prefix}=hotel-starting-price-container]`,
|
|
30
|
+
moreDetails: `[${prefix}=more-details]`,
|
|
31
|
+
offersPopup: `[${prefix}=offers-popup]`,
|
|
32
|
+
offersPopupClose: `[${prefix}=close-btn]`,
|
|
33
|
+
hotelReserveLink: `[${prefix}=hotel-reserve-link]`,
|
|
34
|
+
hotelVillaReserveLink: `[${prefix}=hotel-villa-reserve-link]`,
|
|
35
|
+
hotelURLS: `[${prefix}=hotel-urls]`,
|
|
36
|
+
languageDropdown: `[${prefix}=language-dropdown]`,
|
|
37
|
+
selectedLanguage: `[${prefix}=selected-language]`,
|
|
38
|
+
loadingSpinner: `[${prefix}=loading-spinner]`,
|
|
39
|
+
cmsFilterEmptyState: `[fs-cmsfilter-element=empty]`,
|
|
40
|
+
startingfromItem: (id) => `[${prefix}-be-hid=${id}]`,
|
|
41
|
+
popupOverlay: `[fs-smartlightbox-element=trigger-close]`
|
|
42
|
+
};
|
|
43
|
+
var GUADELOUPE = {
|
|
44
|
+
en: "Guadeloupe Islands",
|
|
45
|
+
fr: "Les \xCEles de Guadeloupe",
|
|
46
|
+
es: "Las islas de Guadalupe",
|
|
47
|
+
it: "Le isole della Guadalupa"
|
|
48
|
+
};
|
|
49
|
+
var DOMINIQUE = {
|
|
50
|
+
en: "La Dominique",
|
|
51
|
+
fr: "La Dominique",
|
|
52
|
+
es: "Dominica",
|
|
53
|
+
it: "Dominica"
|
|
54
|
+
};
|
|
55
|
+
var SAINT_LUCIE = {
|
|
56
|
+
en: "Saint Lucia",
|
|
57
|
+
fr: "Sainte-Lucie",
|
|
58
|
+
es: "Santa Luc\xEDa",
|
|
59
|
+
it: "Santa Lucia"
|
|
60
|
+
};
|
|
61
|
+
var MARTINIQUE = {
|
|
62
|
+
en: "Martinique",
|
|
63
|
+
fr: "Martinique",
|
|
64
|
+
es: "Martinica",
|
|
65
|
+
it: "Martinica"
|
|
66
|
+
};
|
|
67
|
+
var ILE_MAURICE = {
|
|
68
|
+
en: "Mauritius",
|
|
69
|
+
fr: "\xCEle Maurice",
|
|
70
|
+
es: "Mauricio",
|
|
71
|
+
it: "Mauritius"
|
|
72
|
+
};
|
|
73
|
+
var SAINT_MARTIN = {
|
|
74
|
+
en: "Saint Martin",
|
|
75
|
+
fr: "Saint-Martin",
|
|
76
|
+
es: "Saint-Martin",
|
|
77
|
+
it: "Saint Martin"
|
|
78
|
+
};
|
|
79
|
+
var ANTIGUA = {
|
|
80
|
+
en: "Antigua",
|
|
81
|
+
fr: "Antigua",
|
|
82
|
+
es: "Antigua",
|
|
83
|
+
it: "Antigua"
|
|
84
|
+
};
|
|
85
|
+
var ANGUILLA = {
|
|
86
|
+
en: "Anguilla",
|
|
87
|
+
fr: "Anguilla",
|
|
88
|
+
es: "Anguila",
|
|
89
|
+
it: "Anguilla"
|
|
90
|
+
};
|
|
91
|
+
var SNIPPET_CODE_TO_HOTEL = {
|
|
92
|
+
gpgos12767: {
|
|
93
|
+
destination: GUADELOUPE,
|
|
94
|
+
slug: "/hotels-et-villas/creole-beach-hotel-spa",
|
|
95
|
+
codeIPlanet: "FRAN414",
|
|
96
|
+
cmsId: "67c809b5f63deab8a71cf8e9"
|
|
97
|
+
},
|
|
98
|
+
gptro12772: {
|
|
99
|
+
destination: GUADELOUPE,
|
|
100
|
+
slug: "/hotels-et-villas/le-jardin-malanga",
|
|
101
|
+
codeIPlanet: "FRAN416",
|
|
102
|
+
cmsId: "67c809b5f63deab8a71cf90d"
|
|
103
|
+
},
|
|
104
|
+
gpsai12770: {
|
|
105
|
+
destination: GUADELOUPE,
|
|
106
|
+
slug: "/hotels-et-villas/la-toubana-hotel-spa",
|
|
107
|
+
codeIPlanet: "FRAN411",
|
|
108
|
+
cmsId: "67c809b5f63deab8a71cf8ef"
|
|
109
|
+
},
|
|
110
|
+
gpgos12769: {
|
|
111
|
+
destination: GUADELOUPE,
|
|
112
|
+
slug: "/hotels-et-villas/mahogany-hotel-residence-spa",
|
|
113
|
+
codeIPlanet: "FRAN423",
|
|
114
|
+
cmsId: "67c809b5f63deab8a71cf91f"
|
|
115
|
+
},
|
|
116
|
+
gpgua27143: {
|
|
117
|
+
destination: GUADELOUPE,
|
|
118
|
+
slug: "/hotels-et-villas/langley-resort-fort-royal",
|
|
119
|
+
codeIPlanet: "GPAN32",
|
|
120
|
+
cmsId: "67c809b5f63deab8a71cf8f0"
|
|
121
|
+
},
|
|
122
|
+
mqros18592: {
|
|
123
|
+
destination: DOMINIQUE,
|
|
124
|
+
slug: "/hotels-et-villas/jungle-bay-dominica",
|
|
125
|
+
codeIPlanet: "DMAN1",
|
|
126
|
+
cmsId: "67c809b5f63deab8a71cf8ed"
|
|
127
|
+
},
|
|
128
|
+
dmtib00001: {
|
|
129
|
+
destination: DOMINIQUE,
|
|
130
|
+
slug: "/hotels-et-villas/secret-bay-dominique",
|
|
131
|
+
codeIPlanet: "DMAN2",
|
|
132
|
+
cmsId: "67c809b5f63deab8a71cfefd"
|
|
133
|
+
},
|
|
134
|
+
agste21689: {
|
|
135
|
+
destination: SAINT_LUCIE,
|
|
136
|
+
slug: "/hotels-et-villas/jade-mountain",
|
|
137
|
+
codeIPlanet: "AGAN6",
|
|
138
|
+
cmsId: "67c809b5f63deab8a71cf92a"
|
|
139
|
+
},
|
|
140
|
+
zzzzz25376: {
|
|
141
|
+
destination: SAINT_LUCIE,
|
|
142
|
+
slug: "/hotels-et-villas/windjammer-landing",
|
|
143
|
+
codeIPlanet: "LCAN4",
|
|
144
|
+
cmsId: "67c809b5f63deab8a71cf92b"
|
|
145
|
+
},
|
|
146
|
+
lcgro30400: {
|
|
147
|
+
destination: SAINT_LUCIE,
|
|
148
|
+
slug: "/hotels-et-villas/cap-maison",
|
|
149
|
+
codeIPlanet: "LCLC8",
|
|
150
|
+
cmsId: "67c809b5f63deab8a71cf929"
|
|
151
|
+
},
|
|
152
|
+
agste21688: {
|
|
153
|
+
destination: SAINT_LUCIE,
|
|
154
|
+
slug: "/hotels-et-villas/anse-chastanet",
|
|
155
|
+
codeIPlanet: "AGAN5",
|
|
156
|
+
cmsId: "67c809b5f63deab8a71cf928"
|
|
157
|
+
},
|
|
158
|
+
mqsai18593: {
|
|
159
|
+
destination: MARTINIQUE,
|
|
160
|
+
slug: "/hotels-et-villas/plein-soleil",
|
|
161
|
+
codeIPlanet: "MQAN16",
|
|
162
|
+
cmsId: "67c809b5f63deab8a71cf925"
|
|
163
|
+
},
|
|
164
|
+
zzzzz25378: {
|
|
165
|
+
destination: ILE_MAURICE,
|
|
166
|
+
slug: "/hotels-et-villas/shanti-maurice",
|
|
167
|
+
codeIPlanet: "MUAN22",
|
|
168
|
+
cmsId: "67c809b5f63deab8a71cf933"
|
|
169
|
+
},
|
|
170
|
+
zzzzz25377: {
|
|
171
|
+
destination: ILE_MAURICE,
|
|
172
|
+
slug: "/hotels-et-villas/lux-le-morne",
|
|
173
|
+
codeIPlanet: "MUAN21",
|
|
174
|
+
cmsId: "67c809b5f63deab8a71cf931"
|
|
175
|
+
},
|
|
176
|
+
zzzzz25379: {
|
|
177
|
+
destination: ILE_MAURICE,
|
|
178
|
+
slug: "/hotels-et-villas/constance-belle-mare-plage",
|
|
179
|
+
codeIPlanet: "MUAN20",
|
|
180
|
+
cmsId: "67c809b5f63deab8a71cf92f"
|
|
181
|
+
},
|
|
182
|
+
mupos25678: {
|
|
183
|
+
destination: ILE_MAURICE,
|
|
184
|
+
slug: "/hotels-et-villas/constance-le-prince-maurice",
|
|
185
|
+
codeIPlanet: "MUAN24",
|
|
186
|
+
cmsId: "67c809b5f63deab8a71cf930"
|
|
187
|
+
},
|
|
188
|
+
zzzzz25380: {
|
|
189
|
+
destination: ILE_MAURICE,
|
|
190
|
+
slug: "/hotels-et-villas/anahita-the-resort",
|
|
191
|
+
codeIPlanet: "MUAN19",
|
|
192
|
+
cmsId: "67c809b5f63deab8a71cf92e"
|
|
193
|
+
},
|
|
194
|
+
agstm21687: {
|
|
195
|
+
destination: SAINT_MARTIN,
|
|
196
|
+
slug: "/hotels-et-villas/la-samanna",
|
|
197
|
+
codeIPlanet: "FRAN2350",
|
|
198
|
+
cmsId: "67c809b5f63deab8a71cf926"
|
|
199
|
+
},
|
|
200
|
+
frsai31536: {
|
|
201
|
+
destination: SAINT_MARTIN,
|
|
202
|
+
slug: "/hotels-et-villas/le-grand-case-beach-club",
|
|
203
|
+
codeIPlanet: "FRFRA3",
|
|
204
|
+
cmsId: "67c809b5f63deab8a71cf927"
|
|
205
|
+
},
|
|
206
|
+
ageng20433: {
|
|
207
|
+
destination: ANTIGUA,
|
|
208
|
+
slug: "/hotels-et-villas/the-inn-at-english-harbour",
|
|
209
|
+
codeIPlanet: "AGAN4",
|
|
210
|
+
cmsId: "67c809b5f63deab8a71cf8ec"
|
|
211
|
+
},
|
|
212
|
+
agcro20496: {
|
|
213
|
+
destination: ANTIGUA,
|
|
214
|
+
slug: "/hotels-et-villas/blue-waters",
|
|
215
|
+
codeIPlanet: "AGAN1",
|
|
216
|
+
cmsId: "67c809b5f63deab8a71cf8eb"
|
|
217
|
+
},
|
|
218
|
+
gpang25884: {
|
|
219
|
+
destination: ANGUILLA,
|
|
220
|
+
slug: "/hotels-et-villas/aurora-anguilla-resort-golf-club",
|
|
221
|
+
codeIPlanet: "GPAN30",
|
|
222
|
+
cmsId: "67c809b5f63deab8a71cf8ea"
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
var CURRENCY_TO_SYMBOL = {
|
|
226
|
+
AED: "\u062F.\u0625.",
|
|
227
|
+
AFN: "Af",
|
|
228
|
+
ALL: "L",
|
|
229
|
+
AMD: "\u058F",
|
|
230
|
+
ANG: "\u0192",
|
|
231
|
+
AOA: "Kz",
|
|
232
|
+
ARS: "AR$",
|
|
233
|
+
AUD: "AU$",
|
|
234
|
+
AWG: "\u0192",
|
|
235
|
+
AZN: "\u043C\u0430\u043D",
|
|
236
|
+
BAM: "KM",
|
|
237
|
+
BBD: "BBD$",
|
|
238
|
+
BDT: "\u09F3",
|
|
239
|
+
BGN: "\u043B\u0432.",
|
|
240
|
+
BHD: "BD",
|
|
241
|
+
BIF: "FBu",
|
|
242
|
+
BMD: "$",
|
|
243
|
+
BND: "B$",
|
|
244
|
+
BOB: "Bs.",
|
|
245
|
+
BRL: "R$",
|
|
246
|
+
BSD: "$",
|
|
247
|
+
BTN: "Nu.",
|
|
248
|
+
BWP: "P",
|
|
249
|
+
BYN: "Br",
|
|
250
|
+
BZD: "BZ$",
|
|
251
|
+
CAD: "CA$",
|
|
252
|
+
CDF: "FC",
|
|
253
|
+
CHF: "Fr.",
|
|
254
|
+
CKD: "$",
|
|
255
|
+
CLP: "CL$",
|
|
256
|
+
CNY: "CN\xA5",
|
|
257
|
+
COP: "CO$",
|
|
258
|
+
CRC: "\u20A1",
|
|
259
|
+
CUC: "CUC$",
|
|
260
|
+
CUP: "$MN",
|
|
261
|
+
CVE: "CV$",
|
|
262
|
+
CZK: "K\u010D",
|
|
263
|
+
DJF: "Fdj",
|
|
264
|
+
DKK: "kr.",
|
|
265
|
+
DOP: "RD$",
|
|
266
|
+
DZD: "DA",
|
|
267
|
+
EGP: "E\xA3",
|
|
268
|
+
EHP: "Ptas.",
|
|
269
|
+
ERN: "Nkf",
|
|
270
|
+
ETB: "Br",
|
|
271
|
+
EUR: "\u20AC",
|
|
272
|
+
FJD: "FJ$",
|
|
273
|
+
FKP: "FK\xA3",
|
|
274
|
+
FOK: "kr",
|
|
275
|
+
GBP: "\xA3",
|
|
276
|
+
GEL: "\u20BE",
|
|
277
|
+
GGP: "\xA3",
|
|
278
|
+
GHS: "GH\u20B5",
|
|
279
|
+
GIP: "\xA3",
|
|
280
|
+
GMD: "D",
|
|
281
|
+
GNF: "FG",
|
|
282
|
+
GTQ: "Q",
|
|
283
|
+
GYD: "G$",
|
|
284
|
+
HKD: "HK$",
|
|
285
|
+
HNL: "L",
|
|
286
|
+
HRK: "kn",
|
|
287
|
+
HTG: "G",
|
|
288
|
+
HUF: "Ft",
|
|
289
|
+
IDR: "Rp",
|
|
290
|
+
ILS: "\u20AA",
|
|
291
|
+
IMP: "\xA3",
|
|
292
|
+
INR: "Rs.",
|
|
293
|
+
IQD: "\u062F.\u0639.",
|
|
294
|
+
IRR: "\uFDFC",
|
|
295
|
+
ISK: "kr",
|
|
296
|
+
JEP: "\xA3",
|
|
297
|
+
JMD: "J$",
|
|
298
|
+
JOD: "JD",
|
|
299
|
+
JPY: "\xA5",
|
|
300
|
+
KES: "KSh",
|
|
301
|
+
KGS: "\u0441",
|
|
302
|
+
KHR: "\u17DB",
|
|
303
|
+
KID: "$",
|
|
304
|
+
KMF: "CF",
|
|
305
|
+
KPW: "\u20A9",
|
|
306
|
+
KRW: "\u20A9",
|
|
307
|
+
KWD: "KD",
|
|
308
|
+
KYD: "CI$",
|
|
309
|
+
KZT: "\u20B8",
|
|
310
|
+
LAK: "\u20ADN",
|
|
311
|
+
LBP: "LL.",
|
|
312
|
+
LKR: "Rs.",
|
|
313
|
+
LRD: "L$",
|
|
314
|
+
LSL: "L",
|
|
315
|
+
LYD: "LD",
|
|
316
|
+
MAD: "DH",
|
|
317
|
+
MDL: "L",
|
|
318
|
+
MGA: "Ar",
|
|
319
|
+
MKD: "den",
|
|
320
|
+
MMK: "Ks",
|
|
321
|
+
MNT: "\u20AE",
|
|
322
|
+
MOP: "MOP$",
|
|
323
|
+
MRU: "UM",
|
|
324
|
+
MUR: "Rs.",
|
|
325
|
+
MVR: "MRf",
|
|
326
|
+
MWK: "MK",
|
|
327
|
+
MXN: "MX$",
|
|
328
|
+
MYR: "RM",
|
|
329
|
+
MZN: "MTn",
|
|
330
|
+
NAD: "N$",
|
|
331
|
+
NGN: "\u20A6",
|
|
332
|
+
NIO: "C$",
|
|
333
|
+
NOK: "kr",
|
|
334
|
+
NPR: "Rs.",
|
|
335
|
+
NZD: "NZ$",
|
|
336
|
+
OMR: "OR",
|
|
337
|
+
PAB: "B/.",
|
|
338
|
+
PEN: "S/.",
|
|
339
|
+
PGK: "K",
|
|
340
|
+
PHP: "\u20B1",
|
|
341
|
+
PKR: "Rs.",
|
|
342
|
+
PLN: "z\u0142",
|
|
343
|
+
PND: "$",
|
|
344
|
+
PRB: "\u0440.",
|
|
345
|
+
PYG: "\u20B2",
|
|
346
|
+
QAR: "QR",
|
|
347
|
+
RON: "L",
|
|
348
|
+
RSD: "din",
|
|
349
|
+
RUB: "\u20BD",
|
|
350
|
+
RWF: "FRw",
|
|
351
|
+
SAR: "SR",
|
|
352
|
+
SBD: "SI$",
|
|
353
|
+
SCR: "Rs.",
|
|
354
|
+
SDG: "\xA3SD",
|
|
355
|
+
SEK: "kr",
|
|
356
|
+
SGD: "S$",
|
|
357
|
+
SHP: "\xA3",
|
|
358
|
+
SLL: "Le",
|
|
359
|
+
SLS: "Sl",
|
|
360
|
+
SOS: "Sh.So.",
|
|
361
|
+
SRD: "Sr$",
|
|
362
|
+
SSP: "SS\xA3",
|
|
363
|
+
STN: "Db",
|
|
364
|
+
SVC: "\u20A1",
|
|
365
|
+
SYP: "LS",
|
|
366
|
+
SZL: "L",
|
|
367
|
+
THB: "\u0E3F",
|
|
368
|
+
TJS: "SM",
|
|
369
|
+
TMT: "m.",
|
|
370
|
+
TND: "DT",
|
|
371
|
+
TOP: "T$",
|
|
372
|
+
TRY: "TL",
|
|
373
|
+
TTD: "TT$",
|
|
374
|
+
TVD: "$",
|
|
375
|
+
TWD: "NT$",
|
|
376
|
+
TZS: "TSh",
|
|
377
|
+
UAH: "\u20B4",
|
|
378
|
+
UGX: "USh",
|
|
379
|
+
USD: "$",
|
|
380
|
+
UYU: "$U",
|
|
381
|
+
UZS: "\u0441\u0443\u043C",
|
|
382
|
+
VED: "Bs.",
|
|
383
|
+
VES: "Bs.F",
|
|
384
|
+
VND: "\u20AB",
|
|
385
|
+
VUV: "VT",
|
|
386
|
+
WST: "T",
|
|
387
|
+
XAF: "Fr",
|
|
388
|
+
XCD: "$",
|
|
389
|
+
XOF: "\u20A3",
|
|
390
|
+
XPF: "\u20A3",
|
|
391
|
+
YER: "YR",
|
|
392
|
+
ZAR: "R",
|
|
393
|
+
ZMW: "ZK",
|
|
394
|
+
ZWB: "",
|
|
395
|
+
ZWL: "Z$",
|
|
396
|
+
Abkhazia: "",
|
|
397
|
+
Artsakh: "\u0564\u0580."
|
|
398
|
+
};
|
|
399
|
+
var LANG_TO_LOCALE = {
|
|
400
|
+
it: "it_IT",
|
|
401
|
+
es: "es_ES",
|
|
402
|
+
fr: "fr_FR",
|
|
403
|
+
en: "en_GB"
|
|
404
|
+
};
|
|
405
|
+
var apiBaseUrl = "https://deshotelsetdesiles.ccordier.workers.dev/v2/";
|
|
406
|
+
var hotelAndFlightURLBaseUrl = "https://deshotelsetdesiles.i-planet.fr/dhdi-public/searchform.cgi";
|
|
407
|
+
var DEFAULT_COUNTRY_CODE = "FR";
|
|
408
|
+
var GTM_GL = "1*q1lzz9*_gcl_au*MTMyMzcyMDY5NC4xNzM5Mjg5MzYx*_ga*NTAxMzI1MzMwLjE3MzkyODkzNjE.*_ga_Q0RXHLR7D4*MTczOTI5NzEzNC4zLjAuMTczOTI5NzE3Mi4yMi4wLjA.";
|
|
409
|
+
|
|
410
|
+
// src/utils/countries/userCountry.ts
|
|
411
|
+
var getUserCountryCode = async () => {
|
|
412
|
+
return new Promise((resolve) => {
|
|
413
|
+
geoip2.country(
|
|
414
|
+
(successResponse) => {
|
|
415
|
+
resolve(successResponse.country.iso_code);
|
|
416
|
+
},
|
|
417
|
+
() => {
|
|
418
|
+
resolve(DEFAULT_COUNTRY_CODE);
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
});
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// src/utils/buildQueryParams.ts
|
|
425
|
+
var buildQueryParams = (queryParams) => {
|
|
426
|
+
let url = "?";
|
|
427
|
+
for (const [key, value] of Object.entries(queryParams)) {
|
|
428
|
+
if (value) {
|
|
429
|
+
url += `${key}=${value}&`;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
return url;
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// src/utils/ApiClient.ts
|
|
436
|
+
var ApiClient = class {
|
|
437
|
+
/**
|
|
438
|
+
*
|
|
439
|
+
* @param queryParams to include as part of query for the request
|
|
440
|
+
* @returns offers data for a group of hotels
|
|
441
|
+
*/
|
|
442
|
+
async getGroupOffersData(queryParams) {
|
|
443
|
+
const url = apiBaseUrl + "groupOffers" + buildQueryParams(queryParams);
|
|
444
|
+
const response = await fetch(url);
|
|
445
|
+
const body = await response.json();
|
|
446
|
+
if (body.error || !body.data)
|
|
447
|
+
return null;
|
|
448
|
+
return body;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
*
|
|
452
|
+
* @param queryParams to include as part of query for the request
|
|
453
|
+
* @returns offers data for a single hotel
|
|
454
|
+
*/
|
|
455
|
+
async getSingleHotelOffersData(queryParams) {
|
|
456
|
+
const url = apiBaseUrl + "offers" + buildQueryParams(queryParams);
|
|
457
|
+
const response = await fetch(url);
|
|
458
|
+
const body = await response.json();
|
|
459
|
+
if (body.error || !body.data)
|
|
460
|
+
return null;
|
|
461
|
+
return body;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
*
|
|
465
|
+
* @param queryParams to include as part of query for the request
|
|
466
|
+
* @returns Starting CMS offers data
|
|
467
|
+
*/
|
|
468
|
+
async getCMSOffers() {
|
|
469
|
+
const url = apiBaseUrl + "cmsOffers";
|
|
470
|
+
const response = await fetch(url);
|
|
471
|
+
const body = await response.json();
|
|
472
|
+
if (!body.items)
|
|
473
|
+
return null;
|
|
474
|
+
return body;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* @returns all CMS countries
|
|
478
|
+
*/
|
|
479
|
+
async getCountries() {
|
|
480
|
+
const url = apiBaseUrl + "cmsCountries";
|
|
481
|
+
const response = await fetch(url);
|
|
482
|
+
const body = await response.json();
|
|
483
|
+
if (!body.items)
|
|
484
|
+
return null;
|
|
485
|
+
return body;
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
// src/utils/utils.ts
|
|
490
|
+
var listenForLanguageChange = () => {
|
|
491
|
+
const isitProduction = isProduction();
|
|
492
|
+
if (!isitProduction) {
|
|
493
|
+
const currentStagingLang = localStorage.getItem("wglang") || "fr";
|
|
494
|
+
window.Weglot.switchTo(currentStagingLang);
|
|
495
|
+
}
|
|
496
|
+
window.Weglot.on("languageChanged", () => {
|
|
497
|
+
if (isitProduction) {
|
|
498
|
+
window.location.reload();
|
|
499
|
+
} else {
|
|
500
|
+
const newLang = window.Weglot.getCurrentLang();
|
|
501
|
+
localStorage.setItem("wglang", newLang);
|
|
502
|
+
if (window.loadFromServer) {
|
|
503
|
+
window.loadFromServer();
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
};
|
|
508
|
+
var isProduction = () => {
|
|
509
|
+
return window.location.hostname !== "deshotelsetdesiles.webflow.io";
|
|
510
|
+
};
|
|
511
|
+
var getLocale = () => {
|
|
512
|
+
const lang = getLanguage();
|
|
513
|
+
return LANG_TO_LOCALE[lang];
|
|
514
|
+
};
|
|
515
|
+
var getLanguage = () => {
|
|
516
|
+
if (!isProduction()) {
|
|
517
|
+
return localStorage.getItem("wglang") || "fr";
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
const language = window.Weglot.getCurrentLang();
|
|
521
|
+
if (language) {
|
|
522
|
+
return language;
|
|
523
|
+
}
|
|
524
|
+
} catch (error) {
|
|
525
|
+
console.error("Error getting language", error);
|
|
526
|
+
return "fr";
|
|
527
|
+
}
|
|
528
|
+
return "fr";
|
|
529
|
+
};
|
|
530
|
+
var cmsIDToHotelIdMap = () => {
|
|
531
|
+
const map = {};
|
|
532
|
+
Object.entries(SNIPPET_CODE_TO_HOTEL).forEach(([key, value]) => {
|
|
533
|
+
map[value.cmsId] = key;
|
|
534
|
+
});
|
|
535
|
+
return map;
|
|
536
|
+
};
|
|
537
|
+
var offerSlug = (hotelId, offerName) => {
|
|
538
|
+
return `${hotelId.toLowerCase().trim()}-${offerName.toLowerCase().trim()}`;
|
|
539
|
+
};
|
|
540
|
+
var hotelAndFlightURL = (currency, hotelID, accessCodeValue) => {
|
|
541
|
+
const lang = getLanguage().toUpperCase();
|
|
542
|
+
const hotelCode = SNIPPET_CODE_TO_HOTEL[hotelID].codeIPlanet.toUpperCase();
|
|
543
|
+
let url = `${hotelAndFlightURLBaseUrl}?Lang=${lang}¤cy=${currency.toUpperCase()}&HotelCode=${hotelCode}`;
|
|
544
|
+
const gaTag = getCookie("_ga");
|
|
545
|
+
const glTag = GTM_GL;
|
|
546
|
+
const gclAuTag = getCookie("_gcl_au");
|
|
547
|
+
url += `&_ga=${gaTag}&_gl=${glTag}&_gcl_au=${gclAuTag}`;
|
|
548
|
+
if (accessCodeValue) {
|
|
549
|
+
url = `${url}&HotelPromo=${accessCodeValue}`;
|
|
550
|
+
}
|
|
551
|
+
return url;
|
|
552
|
+
};
|
|
553
|
+
var getCookie = (name) => {
|
|
554
|
+
const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
|
|
555
|
+
return match ? match[2] : null;
|
|
556
|
+
};
|
|
557
|
+
|
|
558
|
+
// src/utils/bindQuotationData.ts
|
|
559
|
+
var bindQuotationData = (container, rate, hotelId, cmsOfferData) => {
|
|
560
|
+
const {
|
|
561
|
+
quotation,
|
|
562
|
+
rate: { distribution }
|
|
563
|
+
} = rate;
|
|
564
|
+
const { pricePerNight, currency, plainBookLink } = quotation;
|
|
565
|
+
const { accessCode } = distribution || {};
|
|
566
|
+
let accessCodeValue = "";
|
|
567
|
+
if (accessCode && accessCode.length > 0) {
|
|
568
|
+
[accessCodeValue] = accessCode;
|
|
569
|
+
}
|
|
570
|
+
updatePriceElement(container, pricePerNight, currency);
|
|
571
|
+
const hotelReserveEls = container.querySelector(SELECTORS.hotelReserveLink);
|
|
572
|
+
if (hotelReserveEls) {
|
|
573
|
+
hotelReserveEls.addEventListener("click", (e) => {
|
|
574
|
+
e.preventDefault();
|
|
575
|
+
e.stopPropagation();
|
|
576
|
+
window.open(plainBookLink, "_blank");
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
const hotelVillaReserveEl = container.querySelector(
|
|
580
|
+
SELECTORS.hotelVillaReserveLink
|
|
581
|
+
);
|
|
582
|
+
if (hotelVillaReserveEl) {
|
|
583
|
+
hotelVillaReserveEl.addEventListener("click", (e) => {
|
|
584
|
+
e.preventDefault();
|
|
585
|
+
e.stopPropagation();
|
|
586
|
+
window.open(hotelAndFlightURL(currency, hotelId, accessCodeValue), "_blank");
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
if (cmsOfferData) {
|
|
590
|
+
const {
|
|
591
|
+
fieldData: { "discount-percentage": discountPercentage }
|
|
592
|
+
} = cmsOfferData;
|
|
593
|
+
const discountEl = container.querySelector(SELECTORS.discount);
|
|
594
|
+
if (discountEl && discountPercentage)
|
|
595
|
+
discountEl.innerHTML = `-${discountPercentage}%`;
|
|
596
|
+
const discountContainerEl = container.querySelector(
|
|
597
|
+
SELECTORS.discountContainer
|
|
598
|
+
);
|
|
599
|
+
if (discountContainerEl && !discountPercentage) {
|
|
600
|
+
discountContainerEl.style.display = "none";
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
var updatePriceElement = (container, pricePerNight, currency) => {
|
|
605
|
+
const priceEl = container.querySelector(SELECTORS.price);
|
|
606
|
+
if (priceEl)
|
|
607
|
+
priceEl.innerHTML = Math.floor(pricePerNight).toString();
|
|
608
|
+
const currencyEl = container.querySelector(SELECTORS.currency);
|
|
609
|
+
if (currencyEl)
|
|
610
|
+
currencyEl.innerHTML = CURRENCY_TO_SYMBOL[currency];
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// src/utils/Offers.ts
|
|
614
|
+
var Offers = class {
|
|
615
|
+
/**
|
|
616
|
+
*
|
|
617
|
+
* @param listInstance The list that the offers will be displayed in
|
|
618
|
+
* @param itemTemplateElement The template element to create new items from
|
|
619
|
+
*/
|
|
620
|
+
constructor(listInstance, itemTemplateElement) {
|
|
621
|
+
this.listInstance = listInstance;
|
|
622
|
+
this.itemTemplateElement = itemTemplateElement;
|
|
623
|
+
this.cmsFilterEmptyState = document.querySelector(
|
|
624
|
+
SELECTORS.cmsFilterEmptyState
|
|
625
|
+
);
|
|
626
|
+
if (this.cmsFilterEmptyState) {
|
|
627
|
+
this.cmsFilterEmptyState.classList.add("hide-empty-state");
|
|
628
|
+
}
|
|
629
|
+
listInstance.clearItems();
|
|
630
|
+
listenForLanguageChange();
|
|
631
|
+
this.loadingSpinner = document.querySelector(SELECTORS.loadingSpinner);
|
|
632
|
+
this.countryCode = DEFAULT_COUNTRY_CODE;
|
|
633
|
+
}
|
|
634
|
+
/** The loading spinner element */
|
|
635
|
+
loadingSpinner;
|
|
636
|
+
/** The empty state element */
|
|
637
|
+
cmsFilterEmptyState;
|
|
638
|
+
/** A lookup object for the cms offers data */
|
|
639
|
+
offerLookup = {};
|
|
640
|
+
/** The api client */
|
|
641
|
+
apiClient = new ApiClient();
|
|
642
|
+
/** The user's country code */
|
|
643
|
+
countryCode;
|
|
644
|
+
/** All available countries in CMS */
|
|
645
|
+
availableCountries = {};
|
|
646
|
+
/**
|
|
647
|
+
* Retrieve hotel offer for given hotel IDs
|
|
648
|
+
* @param options to filter the offers
|
|
649
|
+
*/
|
|
650
|
+
async getGroupOffers(options) {
|
|
651
|
+
const { clearItems = true, filter } = options || {};
|
|
652
|
+
if (clearItems)
|
|
653
|
+
this.listInstance.clearItems();
|
|
654
|
+
const cmsOffersData = await this.apiClient.getCMSOffers();
|
|
655
|
+
if (!cmsOffersData)
|
|
656
|
+
return;
|
|
657
|
+
const cmsCountries = await this.apiClient.getCountries();
|
|
658
|
+
if (!cmsCountries)
|
|
659
|
+
return;
|
|
660
|
+
cmsCountries.items.forEach((c) => {
|
|
661
|
+
this.availableCountries[c.id] = c.fieldData.title?.trim();
|
|
662
|
+
});
|
|
663
|
+
this.countryCode = await getUserCountryCode();
|
|
664
|
+
const filteredOffers = cmsOffersData.items.filter(filter).filter(this.countryCodeFilter);
|
|
665
|
+
const generatedHotelIds = this.generateHotelIds(filteredOffers);
|
|
666
|
+
let hids = this.generateHotelIds(filteredOffers).join(",");
|
|
667
|
+
const singleHotel = generatedHotelIds.length === 1;
|
|
668
|
+
if (singleHotel) {
|
|
669
|
+
hids = [hids, hids].join(",");
|
|
670
|
+
}
|
|
671
|
+
const { offerMetaData } = this.generateOfferData(filteredOffers);
|
|
672
|
+
const locale = getLocale();
|
|
673
|
+
const hotelOffersData = await this.apiClient.getGroupOffersData({
|
|
674
|
+
hids,
|
|
675
|
+
locale
|
|
676
|
+
});
|
|
677
|
+
if (!hotelOffersData || hotelOffersData.error || !hotelOffersData.data) {
|
|
678
|
+
this.hideSpinnerAndShowFilter();
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
if (singleHotel) {
|
|
682
|
+
hotelOffersData.data = [hotelOffersData.data[0]];
|
|
683
|
+
}
|
|
684
|
+
const offers = this.getAllOffers(hotelOffersData, offerMetaData);
|
|
685
|
+
this.addHotelToCollection(offers);
|
|
686
|
+
this.hideSpinnerAndShowFilter();
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Retrieve hotel offer for given offer category
|
|
690
|
+
* @param categoryId
|
|
691
|
+
* @param allOffers
|
|
692
|
+
*/
|
|
693
|
+
async getGroupCategoryOffers(categoryId, allOffers = false) {
|
|
694
|
+
const filter = (value) => {
|
|
695
|
+
const { isArchived, isDraft, fieldData } = value;
|
|
696
|
+
if (isArchived || isDraft)
|
|
697
|
+
return false;
|
|
698
|
+
if (allOffers) {
|
|
699
|
+
return (!fieldData.thematiques || fieldData.thematiques.length === 0) && !fieldData.slug.includes("derniere-minute") && !fieldData.slug.includes("reservez-tot");
|
|
700
|
+
}
|
|
701
|
+
return fieldData.category === categoryId;
|
|
702
|
+
};
|
|
703
|
+
await this.getGroupOffers({ filter });
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Retrieve hotel offer for given offer theme
|
|
707
|
+
* @param themeId
|
|
708
|
+
*/
|
|
709
|
+
async getGroupThemeOffers(themeId) {
|
|
710
|
+
const filter = (value) => {
|
|
711
|
+
const { isArchived, isDraft, fieldData } = value;
|
|
712
|
+
if (isArchived || isDraft || !fieldData.thematiques)
|
|
713
|
+
return false;
|
|
714
|
+
return fieldData.thematiques.includes(themeId);
|
|
715
|
+
};
|
|
716
|
+
await this.getGroupOffers({ filter });
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Retrieve hotel offer for the given offer slug (single offer page).
|
|
720
|
+
* @param slug The offer slug from the page URL (e.g. forfait-special-ete-jungle-bay).
|
|
721
|
+
*/
|
|
722
|
+
async getGroupSlugOffers(slug) {
|
|
723
|
+
const filter = (value) => {
|
|
724
|
+
const { isArchived, isDraft, fieldData } = value;
|
|
725
|
+
if (isArchived || isDraft)
|
|
726
|
+
return false;
|
|
727
|
+
return fieldData.slug === slug;
|
|
728
|
+
};
|
|
729
|
+
await this.getGroupOffers({ filter });
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Retrieve all other offers (same as "all offers" list) excluding the given slug.
|
|
733
|
+
* Used for "Nos autres offres" on the offer detail page.
|
|
734
|
+
* @param excludeSlug The current page's offer slug to exclude from the list.
|
|
735
|
+
*/
|
|
736
|
+
async getGroupOtherOffers(excludeSlug) {
|
|
737
|
+
const filter = (value) => {
|
|
738
|
+
const { isArchived, isDraft, fieldData } = value;
|
|
739
|
+
if (isArchived || isDraft)
|
|
740
|
+
return false;
|
|
741
|
+
if (fieldData.slug === excludeSlug)
|
|
742
|
+
return false;
|
|
743
|
+
return (!fieldData.thematiques || fieldData.thematiques.length === 0) && !fieldData.slug.includes("derniere-minute") && !fieldData.slug.includes("reservez-tot");
|
|
744
|
+
};
|
|
745
|
+
await this.getGroupOffers({ filter });
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Hide the loading spinner and show the empty state if no offers are found
|
|
749
|
+
* @private
|
|
750
|
+
*/
|
|
751
|
+
hideSpinnerAndShowFilter() {
|
|
752
|
+
if (this.loadingSpinner)
|
|
753
|
+
this.loadingSpinner.style.display = "none";
|
|
754
|
+
if (this.cmsFilterEmptyState) {
|
|
755
|
+
this.cmsFilterEmptyState.classList.remove("hide-empty-state");
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Filter the offers based on the country code
|
|
760
|
+
* @param item
|
|
761
|
+
*/
|
|
762
|
+
countryCodeFilter = (item) => {
|
|
763
|
+
const { fieldData } = item;
|
|
764
|
+
if (!fieldData["supported-countries"] || fieldData["supported-countries"].length === 0)
|
|
765
|
+
return true;
|
|
766
|
+
const itemCountryCodes = fieldData["supported-countries"].map(
|
|
767
|
+
(c) => this.availableCountries[c]
|
|
768
|
+
);
|
|
769
|
+
return itemCountryCodes.includes(this.countryCode);
|
|
770
|
+
};
|
|
771
|
+
/**
|
|
772
|
+
*
|
|
773
|
+
* @param cmsOffers to generate hotel ids from
|
|
774
|
+
* @returns hotel ids based on the cms offers
|
|
775
|
+
*/
|
|
776
|
+
generateHotelIds(cmsOffers) {
|
|
777
|
+
const hotelIds = [];
|
|
778
|
+
const cmsIDToHotelIds = cmsIDToHotelIdMap();
|
|
779
|
+
cmsOffers.forEach((offer) => {
|
|
780
|
+
const {
|
|
781
|
+
fieldData: { "hotel-villa": hotelCMSId }
|
|
782
|
+
} = offer;
|
|
783
|
+
hotelIds.push(cmsIDToHotelIds[hotelCMSId]);
|
|
784
|
+
});
|
|
785
|
+
return Array.from(new Set(hotelIds));
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Retrieve all offers from the group offers data in a flat structure - sorted by CMS offer order
|
|
789
|
+
* @param hotelOffersData to get all rates from
|
|
790
|
+
* @param offerMetaData
|
|
791
|
+
* @returns the offer with each rate as a separate item
|
|
792
|
+
*/
|
|
793
|
+
getAllOffers(hotelOffersData, offerMetaData) {
|
|
794
|
+
const rates = [];
|
|
795
|
+
hotelOffersData.data.forEach((offer) => {
|
|
796
|
+
const {
|
|
797
|
+
prop: { hid },
|
|
798
|
+
rates: offerRates
|
|
799
|
+
} = offer;
|
|
800
|
+
offerRates.forEach((rate) => {
|
|
801
|
+
const { name, title } = rate.rate;
|
|
802
|
+
const includeOffer = offerMetaData.includes(offerSlug(hid, name)) || offerMetaData.includes(offerSlug(hid, title));
|
|
803
|
+
if (includeOffer) {
|
|
804
|
+
rates.push({
|
|
805
|
+
...offer,
|
|
806
|
+
rates: [rate]
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
});
|
|
811
|
+
rates.sort((a, b) => {
|
|
812
|
+
const cmsOfferA = this.offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.title)] || this.offerLookup[offerSlug(a.prop.hid, a.rates[0].rate.name)];
|
|
813
|
+
const cmsOfferB = this.offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.title)] || this.offerLookup[offerSlug(b.prop.hid, b.rates[0].rate.name)];
|
|
814
|
+
const aOrder = Number(cmsOfferA.fieldData.order) || 0;
|
|
815
|
+
const bOrder = Number(cmsOfferB.fieldData.order) || 0;
|
|
816
|
+
return aOrder - bOrder;
|
|
817
|
+
});
|
|
818
|
+
return rates;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
*
|
|
822
|
+
* @param filteredOffers to generate offer data from CMS offers
|
|
823
|
+
* generate the offer metadata and create a lookup object for the cms offers data (useful when looking up for offers discount percentage)
|
|
824
|
+
* @returns
|
|
825
|
+
*/
|
|
826
|
+
generateOfferData(filteredOffers) {
|
|
827
|
+
const offerMetaData = [];
|
|
828
|
+
filteredOffers.forEach((offer) => {
|
|
829
|
+
const {
|
|
830
|
+
fieldData: { "hotel-or-property-api-id": hotelId, "offer-api-name": name }
|
|
831
|
+
} = offer;
|
|
832
|
+
const slug = offerSlug(hotelId, name);
|
|
833
|
+
offerMetaData.push(slug);
|
|
834
|
+
this.offerLookup[slug] = offer;
|
|
835
|
+
});
|
|
836
|
+
return { offerMetaData };
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
*
|
|
840
|
+
* @param offers
|
|
841
|
+
*/
|
|
842
|
+
addHotelToCollection(offers) {
|
|
843
|
+
for (const { prop, rates } of offers) {
|
|
844
|
+
const items = rates.map((item) => this.createItem(prop, item, this.itemTemplateElement));
|
|
845
|
+
this.listInstance.addItems(items);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Creates an item from the template element.
|
|
850
|
+
* @param offerProperty
|
|
851
|
+
* @param rate The Rate data to create the item from.
|
|
852
|
+
* @param templateElement The template element.
|
|
853
|
+
*
|
|
854
|
+
* @returns A new Collection Item element.
|
|
855
|
+
*/
|
|
856
|
+
createItem(offerProperty, rate, templateElement) {
|
|
857
|
+
const { rate: rateData } = rate;
|
|
858
|
+
const { hid, title: hotelName, property } = offerProperty;
|
|
859
|
+
const { image, title, name } = rateData;
|
|
860
|
+
const offerCMSData = this.offerLookup[offerSlug(hid || property, title)] || this.offerLookup[offerSlug(hid || property, name)];
|
|
861
|
+
const newItem = templateElement.cloneNode(true);
|
|
862
|
+
const hotelMeta = SNIPPET_CODE_TO_HOTEL[hid || property];
|
|
863
|
+
if (!hotelMeta)
|
|
864
|
+
return newItem;
|
|
865
|
+
const { destination, slug } = hotelMeta;
|
|
866
|
+
this.bindOffersMetaData(newItem, { destination, image, hotelName, title, slug });
|
|
867
|
+
bindQuotationData(newItem, rate, hid, offerCMSData);
|
|
868
|
+
const moreDetails = newItem.querySelector(SELECTORS.moreDetails);
|
|
869
|
+
if (moreDetails) {
|
|
870
|
+
moreDetails.addEventListener("click", () => {
|
|
871
|
+
const offersSlug = this.getOffersCmsSlug(hid, property, name);
|
|
872
|
+
window.location.href = `/offers/${offersSlug}`;
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
newItem.style.display = "flex";
|
|
876
|
+
return newItem;
|
|
877
|
+
}
|
|
878
|
+
getOffersCmsSlug(hid, property, title) {
|
|
879
|
+
const offerCMSData = this.offerLookup[offerSlug(hid || property, title)];
|
|
880
|
+
return offerCMSData?.fieldData.slug;
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
*
|
|
884
|
+
* @param container for data item
|
|
885
|
+
* @param destination for offer
|
|
886
|
+
* @param image for offer
|
|
887
|
+
* @param hotelName for hotel
|
|
888
|
+
* @param title for offer
|
|
889
|
+
* @param slug
|
|
890
|
+
* @param description
|
|
891
|
+
*/
|
|
892
|
+
bindOffersMetaData(container, {
|
|
893
|
+
destination,
|
|
894
|
+
image,
|
|
895
|
+
hotelName,
|
|
896
|
+
title,
|
|
897
|
+
slug,
|
|
898
|
+
description
|
|
899
|
+
}) {
|
|
900
|
+
const destinationEl = container.querySelector(SELECTORS.destination);
|
|
901
|
+
const imageEl = container.querySelector(SELECTORS.image);
|
|
902
|
+
const hotelNameEl = container.querySelector(SELECTORS.hotelName);
|
|
903
|
+
const nameEl = container.querySelector(SELECTORS.name);
|
|
904
|
+
const descriptionEl = container.querySelector(SELECTORS.description);
|
|
905
|
+
const hotelLinkEl = container.querySelector(SELECTORS.hotelLink);
|
|
906
|
+
const language = getLanguage();
|
|
907
|
+
if (destinationEl)
|
|
908
|
+
destinationEl.textContent = destination[language];
|
|
909
|
+
if (imageEl)
|
|
910
|
+
imageEl.src = image?.url;
|
|
911
|
+
if (hotelNameEl)
|
|
912
|
+
hotelNameEl.innerHTML = hotelName;
|
|
913
|
+
if (nameEl)
|
|
914
|
+
nameEl.innerHTML = title;
|
|
915
|
+
if (descriptionEl && description)
|
|
916
|
+
descriptionEl.innerHTML = description;
|
|
917
|
+
if (hotelLinkEl && slug) {
|
|
918
|
+
hotelLinkEl.addEventListener("click", () => {
|
|
919
|
+
window.location.href = slug;
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
// src/utils/createOffersInstance.ts
|
|
926
|
+
var createOffersInstance = (filtersInstances) => {
|
|
927
|
+
const [filtersInstance] = filtersInstances;
|
|
928
|
+
const { listInstance } = filtersInstance;
|
|
929
|
+
if (listInstance.items.length === 0) {
|
|
930
|
+
throw new Error("No items found in the list instance - Cannot create an instance of Offers");
|
|
931
|
+
}
|
|
932
|
+
return createOfferForList(listInstance);
|
|
933
|
+
};
|
|
934
|
+
var createOfferForList = (listInstance) => {
|
|
935
|
+
const [firstItem] = listInstance.items;
|
|
936
|
+
if (!firstItem)
|
|
937
|
+
throw new Error("No items found in the list instance");
|
|
938
|
+
const itemTemplateElement = firstItem.element;
|
|
939
|
+
return new Offers(listInstance, itemTemplateElement);
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
// src/pages/Offers.ts
|
|
943
|
+
window.fsAttributes = window.fsAttributes || [];
|
|
944
|
+
window.loadFromServer = () => {
|
|
945
|
+
window.fsAttributes.push([
|
|
946
|
+
"cmsfilter",
|
|
947
|
+
async (filtersInstances) => {
|
|
948
|
+
const offers = createOffersInstance(filtersInstances);
|
|
949
|
+
await offers.getGroupCategoryOffers(void 0, true);
|
|
950
|
+
}
|
|
951
|
+
]);
|
|
952
|
+
};
|
|
953
|
+
window.loadFromServer();
|
|
954
|
+
})();
|
|
955
|
+
//# sourceMappingURL=Offers.js.map
|