@hotelcard/ui 0.0.13 → 0.0.16
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.
Potentially problematic release.
This version of @hotelcard/ui might be problematic. Click here for more details.
- package/README.md +121 -68
- package/dist/index.cjs +1510 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +607 -17
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +857 -79
- package/dist/index.d.ts +857 -79
- package/dist/index.js +1488 -105
- package/dist/index.js.map +1 -1
- package/package.json +22 -11
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -24,36 +34,51 @@ __export(index_exports, {
|
|
|
24
34
|
Benefits: () => Benefits,
|
|
25
35
|
Block: () => Block,
|
|
26
36
|
Button: () => Button,
|
|
37
|
+
CATEGORY_OPTIONS: () => CATEGORY_OPTIONS,
|
|
27
38
|
Card: () => Card,
|
|
28
39
|
Checkbox: () => Checkbox,
|
|
40
|
+
CheckboxFilter: () => CheckboxFilter,
|
|
29
41
|
ChevronLeftIcon: () => ChevronLeftIcon,
|
|
30
42
|
ChevronRightIcon: () => ChevronRightIcon2,
|
|
31
43
|
Chip: () => Chip,
|
|
44
|
+
CollapsibleFilterSection: () => CollapsibleFilterSection,
|
|
32
45
|
DateSelector: () => DateSelector,
|
|
33
46
|
Divider: () => Divider,
|
|
34
47
|
Dropdown: () => Dropdown,
|
|
35
48
|
DualCalendar: () => DualCalendar,
|
|
49
|
+
ExperienceFilter: () => ExperienceFilter,
|
|
36
50
|
FAQ: () => FAQ,
|
|
51
|
+
FilterCheckboxItem: () => FilterCheckboxItem,
|
|
37
52
|
GuestContent: () => GuestContent,
|
|
38
53
|
HeartIcon: () => HeartIcon3,
|
|
39
54
|
HotelCard: () => HotelCard,
|
|
40
55
|
HotelCardContent: () => HotelCardContent,
|
|
41
56
|
HotelCardImage: () => HotelCardImage,
|
|
42
57
|
HotelCardUIProvider: () => HotelCardUIProvider,
|
|
58
|
+
HotelCategoryFilter: () => HotelCategoryFilter,
|
|
43
59
|
Input: () => Input,
|
|
60
|
+
MealsFilter: () => MealsFilter,
|
|
44
61
|
Modal: () => Modal,
|
|
45
62
|
Pin: () => Pin,
|
|
46
63
|
PinIcon: () => PinIcon2,
|
|
64
|
+
PriceRangeFilter: () => PriceRangeFilter,
|
|
65
|
+
REVIEW_OPTIONS: () => REVIEW_OPTIONS,
|
|
47
66
|
RadioButton: () => RadioButton,
|
|
48
67
|
Rating: () => Rating,
|
|
68
|
+
RegionsFilter: () => RegionsFilter,
|
|
49
69
|
ReviewCard: () => ReviewCard,
|
|
70
|
+
ReviewsFilter: () => ReviewsFilter,
|
|
50
71
|
SectionHeader: () => SectionHeader,
|
|
72
|
+
SelectedFiltersRow: () => SelectedFiltersRow,
|
|
51
73
|
StarIcon: () => StarIcon4,
|
|
74
|
+
TransportFilter: () => TransportFilter,
|
|
75
|
+
WellnessFilter: () => WellnessFilter,
|
|
52
76
|
WhenContent: () => WhenContent,
|
|
53
77
|
calculateDiscount: () => calculateDiscount,
|
|
54
78
|
formatDate: () => formatDate,
|
|
55
79
|
formatDateRange: () => formatDateRange,
|
|
56
80
|
formatPrice: () => formatPrice,
|
|
81
|
+
translations: () => translations,
|
|
57
82
|
useDebounce: () => useDebounce,
|
|
58
83
|
useResponsive: () => useResponsive,
|
|
59
84
|
useTranslation: () => useTranslation,
|
|
@@ -64,20 +89,557 @@ module.exports = __toCommonJS(index_exports);
|
|
|
64
89
|
|
|
65
90
|
// src/context/UIContext.tsx
|
|
66
91
|
var import_react = require("react");
|
|
92
|
+
|
|
93
|
+
// src/locales/de.json
|
|
94
|
+
var de_default = {
|
|
95
|
+
button: {
|
|
96
|
+
order: "Bestellen",
|
|
97
|
+
"order-navigation": "Bestellen",
|
|
98
|
+
"order-hc": "HotelCard bestellen",
|
|
99
|
+
"my-account": "Mein Konto",
|
|
100
|
+
search: "Suchen",
|
|
101
|
+
"back-to-top": "Nach oben"
|
|
102
|
+
},
|
|
103
|
+
link: {
|
|
104
|
+
"member-benefits": "Member Benefits",
|
|
105
|
+
"view-all-hotels": "Alle Hoteldeals ansehen",
|
|
106
|
+
"search-by-map": "Kartenansicht",
|
|
107
|
+
"search-by-region": "Hotels nach Region",
|
|
108
|
+
"search-by-experience": "Hotels nach Erlebnis",
|
|
109
|
+
"travel-inspiration": "Reiseinspiration",
|
|
110
|
+
"booking-tips-and-tricks": "Buchungstipps",
|
|
111
|
+
home: "Startseite",
|
|
112
|
+
"all-hotel-deals": "Alle Hotelangebote",
|
|
113
|
+
"search-results": "Suchergebnisse"
|
|
114
|
+
},
|
|
115
|
+
general: {
|
|
116
|
+
"signed-out": "Anmelden und buchen",
|
|
117
|
+
"room-price": "ab CHF xxx / Zimmer",
|
|
118
|
+
guarantee: "14 Tage Geld-zur\xFCck-Garantie",
|
|
119
|
+
contact: "Weitere Fragen? Kontaktieren Sie uns.",
|
|
120
|
+
"breakfast-included": "Fr\xFChst\xFCck inbegriffen",
|
|
121
|
+
"free-cancellation": "Kostenlose Stornierung",
|
|
122
|
+
"suggested-destinations": "Vorgeschlagene Reiseziele",
|
|
123
|
+
"when-months": "Wann m\xF6chtest du reisen?",
|
|
124
|
+
"hotel-deals-found": "Hotelangebote gefunden",
|
|
125
|
+
"no-results": "Probieren Sie andere Reiseziele, \xE4ndern Sie Ihre Daten oder entfernen Sie einige Filter.",
|
|
126
|
+
"unavailable-for-selected-days": "F\xFCr die ausgew\xE4hlten Daten nicht verf\xFCgbar.",
|
|
127
|
+
"cant-accommodate-all": "Das Hotel kann nicht alle G\xE4ste beherbergen.",
|
|
128
|
+
"reset-destination": "Zielsuche zur\xFCcksetzen, um Regionen zu filtern"
|
|
129
|
+
},
|
|
130
|
+
label: {
|
|
131
|
+
"price-from": "ab ",
|
|
132
|
+
"price-for": "/ Zimmer",
|
|
133
|
+
"per-room-night": "pro Zimmer & Nacht ab",
|
|
134
|
+
new: "Neu",
|
|
135
|
+
anytime: "Jederzeit",
|
|
136
|
+
anywhere: "Alle Reiseziele",
|
|
137
|
+
dates: "Datum",
|
|
138
|
+
flexible: "Flexibel",
|
|
139
|
+
where: "Wohin",
|
|
140
|
+
when: "Wann",
|
|
141
|
+
who: "Wer",
|
|
142
|
+
nearby: "In der N\xE4he",
|
|
143
|
+
hotels: "Hotel",
|
|
144
|
+
filter: "Filter",
|
|
145
|
+
sort: "Sortieren",
|
|
146
|
+
map: "Karte",
|
|
147
|
+
rating: "Bewertung",
|
|
148
|
+
"rating-excellent": "Ausgezeichnet",
|
|
149
|
+
"rating-very-good": "Sehr gut",
|
|
150
|
+
"rating-good": "Gut",
|
|
151
|
+
"rating-fair": "Ansprechend",
|
|
152
|
+
"rating-none": "Keine Bewertung"
|
|
153
|
+
},
|
|
154
|
+
product: {
|
|
155
|
+
"6m": "6-Monatsabo",
|
|
156
|
+
"1y": "1-Jahresabo",
|
|
157
|
+
"2y": "2-Jahresabo",
|
|
158
|
+
"3y": "3-Jahresabo",
|
|
159
|
+
"price-6m": "79.-",
|
|
160
|
+
"price-6m-disc": "59.-",
|
|
161
|
+
"price-1y": "99.-",
|
|
162
|
+
"price-1y-disc": "79.-",
|
|
163
|
+
"price-2y": "198.-",
|
|
164
|
+
"price-2y-disc": "173.-",
|
|
165
|
+
"price-3y": "297.-",
|
|
166
|
+
"price-3y-disc": "247.-",
|
|
167
|
+
"price-gift": "99.-",
|
|
168
|
+
"price-gift-disc": "59.-"
|
|
169
|
+
},
|
|
170
|
+
subheadline: {
|
|
171
|
+
"your-hc": "Ihre HotelCard",
|
|
172
|
+
"popular-hotels": "Beliebte Hotelangebote",
|
|
173
|
+
"no-results": "Probieren Sie andere Reiseziele, \xE4ndern Sie Ihre Daten oder entfernen Sie einige Filter.",
|
|
174
|
+
"sort-by": "Sortieren nach"
|
|
175
|
+
},
|
|
176
|
+
form: {
|
|
177
|
+
guests: "G\xE4ste",
|
|
178
|
+
guest: "Gast",
|
|
179
|
+
adults: "Erwachsene",
|
|
180
|
+
children: "Kinder",
|
|
181
|
+
pet: "Haustier",
|
|
182
|
+
"age-of-child": "Alter des Kindes",
|
|
183
|
+
age: "Alter",
|
|
184
|
+
"age-error": "Bitte w\xE4hlen Sie das Alter aus"
|
|
185
|
+
},
|
|
186
|
+
filter: {
|
|
187
|
+
filters: "Filter",
|
|
188
|
+
destination: "Reiseziel",
|
|
189
|
+
experience: "Erlebnis",
|
|
190
|
+
"show-all": "Alle anzeigen",
|
|
191
|
+
price: "Preis",
|
|
192
|
+
discount: "Rabatt",
|
|
193
|
+
services: "Leistungen",
|
|
194
|
+
meals: "Verpflegung",
|
|
195
|
+
"hotel-category": "Hotelkategorie",
|
|
196
|
+
reviews: "Bewertungen",
|
|
197
|
+
mobility: "Mobilit\xE4t",
|
|
198
|
+
"wellness-spa": "Wellness & Spa",
|
|
199
|
+
"price-high-low": "Preis: absteigend",
|
|
200
|
+
"price-low-high": "Preis: aufsteigend",
|
|
201
|
+
"best-rating": "Beste Bewertung",
|
|
202
|
+
"most-popular": "Beliebt",
|
|
203
|
+
"newest-hotels": "Neueste",
|
|
204
|
+
relevance: "Relevanz",
|
|
205
|
+
selected: "String value",
|
|
206
|
+
"clear-all": "Alles l\xF6schen",
|
|
207
|
+
options: "Leistungen",
|
|
208
|
+
"hotellerie-suisse": "Klassifikation HotellerieSuisse",
|
|
209
|
+
trustyou: "Bewertungen von Reisenden auf Trust You\xAE",
|
|
210
|
+
"select-all": "Alle ausw\xE4hlen",
|
|
211
|
+
reset: "Zur\xFCcksetzen",
|
|
212
|
+
"breakfast-included": "Fr\xFChst\xFCck inbegriffen"
|
|
213
|
+
},
|
|
214
|
+
headline: {
|
|
215
|
+
"no-results": "Zurzeit entsprechen keine Aufenthalte Ihrer Suche"
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
// src/locales/en.json
|
|
220
|
+
var en_default = {
|
|
221
|
+
button: {
|
|
222
|
+
order: "Order",
|
|
223
|
+
"order-navigation": "Join",
|
|
224
|
+
"order-hc": "Order HotelCard",
|
|
225
|
+
"my-account": "My account",
|
|
226
|
+
search: "Search",
|
|
227
|
+
"back-to-top": "Back to top"
|
|
228
|
+
},
|
|
229
|
+
link: {
|
|
230
|
+
"member-benefits": "Member Benefits",
|
|
231
|
+
"view-all-hotels": "View all hotel deals",
|
|
232
|
+
"search-by-map": "Map search",
|
|
233
|
+
"search-by-region": "Hotels by region",
|
|
234
|
+
"search-by-experience": "Hotels by experience",
|
|
235
|
+
"travel-inspiration": "Travel inspiration",
|
|
236
|
+
"booking-tips-and-tricks": "Booking tips",
|
|
237
|
+
home: "Home",
|
|
238
|
+
"all-hotel-deals": "All hotel deals",
|
|
239
|
+
"search-results": "Search results"
|
|
240
|
+
},
|
|
241
|
+
general: {
|
|
242
|
+
"signed-out": "Log in and book",
|
|
243
|
+
"room-price": "from CHF xxx / room",
|
|
244
|
+
guarantee: "14-day money-back guarantee",
|
|
245
|
+
contact: "More questions? Contact us.",
|
|
246
|
+
"breakfast-included": "Breakfast included",
|
|
247
|
+
"free-cancellation": "Free cancellation",
|
|
248
|
+
"suggested-destinations": "Not sure where to travel next?",
|
|
249
|
+
"when-months": "When do you want to go?",
|
|
250
|
+
"hotel-deals-found": "hotel deals found",
|
|
251
|
+
"no-results": "Explore different destinations, change your dates, or remove some filters.",
|
|
252
|
+
"unavailable-for-selected-days": "Unavailable for selected dates.",
|
|
253
|
+
"cant-accommodate-all": "Hotel can\u2019t accommodate all guests.",
|
|
254
|
+
"reset-destination": "Reset destination search to use region filters."
|
|
255
|
+
},
|
|
256
|
+
label: {
|
|
257
|
+
"price-from": "from ",
|
|
258
|
+
"price-for": "/ room",
|
|
259
|
+
"per-room-night": "per room & night from",
|
|
260
|
+
new: "New",
|
|
261
|
+
anytime: "Anytime",
|
|
262
|
+
anywhere: "All destinations",
|
|
263
|
+
dates: "Dates",
|
|
264
|
+
flexible: "Flexible",
|
|
265
|
+
where: "Where",
|
|
266
|
+
when: "When",
|
|
267
|
+
who: "Who",
|
|
268
|
+
nearby: "Nearby",
|
|
269
|
+
hotels: "Hotel",
|
|
270
|
+
filter: "Filter",
|
|
271
|
+
sort: "Sort",
|
|
272
|
+
map: "Map",
|
|
273
|
+
rating: "Rating",
|
|
274
|
+
"rating-excellent": "Excellent",
|
|
275
|
+
"rating-very-good": "Very good",
|
|
276
|
+
"rating-good": "Good",
|
|
277
|
+
"rating-fair": "Fair",
|
|
278
|
+
"rating-none": "No rating"
|
|
279
|
+
},
|
|
280
|
+
product: {
|
|
281
|
+
"6m": "6-month subscription",
|
|
282
|
+
"1y": "1-year subscription",
|
|
283
|
+
"2y": "2-year subscription",
|
|
284
|
+
"3y": "3-year subscription",
|
|
285
|
+
"price-6m": "79.-",
|
|
286
|
+
"price-6m-disc": "59.-",
|
|
287
|
+
"price-1y": "99.-",
|
|
288
|
+
"price-1y-disc": "79.-",
|
|
289
|
+
"price-2y": "198.-",
|
|
290
|
+
"price-2y-disc": "173.-",
|
|
291
|
+
"price-3y": "297.-",
|
|
292
|
+
"price-3y-disc": "247.-",
|
|
293
|
+
"price-gift": "99.-",
|
|
294
|
+
"price-gift-disc": "59.-"
|
|
295
|
+
},
|
|
296
|
+
subheadline: {
|
|
297
|
+
"your-hc": "Your HotelCard",
|
|
298
|
+
"popular-hotels": "Popular hotel deals",
|
|
299
|
+
"no-results": "Explore different destinations, change your dates, or remove some filters.",
|
|
300
|
+
"sort-by": "Sort by"
|
|
301
|
+
},
|
|
302
|
+
form: {
|
|
303
|
+
guests: "guests",
|
|
304
|
+
guest: "guest",
|
|
305
|
+
adults: "Adults",
|
|
306
|
+
children: "Children",
|
|
307
|
+
pet: "Pet",
|
|
308
|
+
"age-of-child": "Child\u2019s age",
|
|
309
|
+
age: "Age",
|
|
310
|
+
"age-error": "Please select age"
|
|
311
|
+
},
|
|
312
|
+
filter: {
|
|
313
|
+
filters: "Filters",
|
|
314
|
+
destination: "Destination",
|
|
315
|
+
experience: "Experience",
|
|
316
|
+
"show-all": "Show all",
|
|
317
|
+
price: "Price",
|
|
318
|
+
discount: "Discount",
|
|
319
|
+
services: "Services",
|
|
320
|
+
meals: "Meals",
|
|
321
|
+
"hotel-category": "Hotel category",
|
|
322
|
+
reviews: "Reviews",
|
|
323
|
+
mobility: "Mobility",
|
|
324
|
+
"wellness-spa": "Wellness & Spa",
|
|
325
|
+
"price-high-low": "Price high to low",
|
|
326
|
+
"price-low-high": "Price low to high",
|
|
327
|
+
"best-rating": "Best guest rating",
|
|
328
|
+
"most-popular": "Most popular",
|
|
329
|
+
"newest-hotels": "Newest",
|
|
330
|
+
relevance: "Relevance",
|
|
331
|
+
selected: "Selected",
|
|
332
|
+
"clear-all": "Clear all",
|
|
333
|
+
options: "Options",
|
|
334
|
+
"hotellerie-suisse": "Classification HotellerieSuisse",
|
|
335
|
+
trustyou: "Reviews from travelers on TrustYou\xAE",
|
|
336
|
+
"select-all": "Select all",
|
|
337
|
+
reset: "Reset",
|
|
338
|
+
"breakfast-included": "Breakfast included"
|
|
339
|
+
},
|
|
340
|
+
headline: {
|
|
341
|
+
"no-results": "No stays match your search right now"
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
// src/locales/fr.json
|
|
346
|
+
var fr_default = {
|
|
347
|
+
button: {
|
|
348
|
+
order: "Commander",
|
|
349
|
+
"order-navigation": "Commander",
|
|
350
|
+
"order-hc": "Commander l'HotelCard",
|
|
351
|
+
"my-account": "Mon compte",
|
|
352
|
+
search: "Rechercher",
|
|
353
|
+
"back-to-top": "Haut de page"
|
|
354
|
+
},
|
|
355
|
+
link: {
|
|
356
|
+
"member-benefits": "Member Benefits",
|
|
357
|
+
"view-all-hotels": "D\xE9couvrez toutes nos offres",
|
|
358
|
+
"search-by-map": "Recherche sur la carte",
|
|
359
|
+
"search-by-region": "H\xF4tels par r\xE9gion",
|
|
360
|
+
"search-by-experience": "H\xF4tels par exp\xE9rience",
|
|
361
|
+
"travel-inspiration": "Inspiration voyage",
|
|
362
|
+
"booking-tips-and-tricks": "Conseils r\xE9servation",
|
|
363
|
+
home: "Accueil",
|
|
364
|
+
"all-hotel-deals": "Toutes les offres d\u2019h\xF4tels",
|
|
365
|
+
"search-results": "R\xE9sultats de recherche"
|
|
366
|
+
},
|
|
367
|
+
general: {
|
|
368
|
+
"signed-out": "Se connecter et r\xE9server",
|
|
369
|
+
"room-price": "\xE0 partir de CHF XXX par chambre",
|
|
370
|
+
guarantee: "Garantie de remboursement de 14 jours",
|
|
371
|
+
contact: "D\u2019autres questions ? Contactez-nous.",
|
|
372
|
+
"breakfast-included": "Petit-d\xE9jeuner inclus",
|
|
373
|
+
"free-cancellation": "Annulation gratuite",
|
|
374
|
+
"suggested-destinations": "Suggestions de destinations",
|
|
375
|
+
"when-months": "Quand souhaitez-vous partir ?",
|
|
376
|
+
"hotel-deals-found": "offres d\u2019h\xF4tel trouv\xE9es",
|
|
377
|
+
"no-results": "Explorez d\u2019autres destinations, modifiez vos dates ou retirez certains filtres.",
|
|
378
|
+
"unavailable-for-selected-days": "Indisponible aux dates s\xE9lectionn\xE9es.",
|
|
379
|
+
"cant-accommodate-all": "L\u2019h\xF4tel ne peut pas accueillir tous les voyageurs.",
|
|
380
|
+
"reset-destination": "R\xE9initialiser la destination et filtrer par r\xE9gion"
|
|
381
|
+
},
|
|
382
|
+
label: {
|
|
383
|
+
"price-from": "\xE0 partir de ",
|
|
384
|
+
"price-for": "par chambre",
|
|
385
|
+
"per-room-night": "par chambre & nuit d\xE8s",
|
|
386
|
+
new: "Nouveau",
|
|
387
|
+
anytime: "\xC0 tout moment",
|
|
388
|
+
anywhere: "Toutes les destinations",
|
|
389
|
+
dates: "Dates",
|
|
390
|
+
flexible: "Flexible",
|
|
391
|
+
where: "Destination",
|
|
392
|
+
when: "Quand",
|
|
393
|
+
who: "Voyageurs",
|
|
394
|
+
nearby: "\xC0 proximit\xE9",
|
|
395
|
+
hotels: "H\xF4tel",
|
|
396
|
+
filter: "Filtrer",
|
|
397
|
+
sort: "Trier",
|
|
398
|
+
map: "Carte",
|
|
399
|
+
rating: "Note",
|
|
400
|
+
"rating-excellent": "Excellent",
|
|
401
|
+
"rating-very-good": "Tr\xE8s bien",
|
|
402
|
+
"rating-good": "Bien",
|
|
403
|
+
"rating-fair": "Moyen",
|
|
404
|
+
"rating-none": "Aucune notation"
|
|
405
|
+
},
|
|
406
|
+
product: {
|
|
407
|
+
"6m": "Abonnement de 6 mois",
|
|
408
|
+
"1y": "Abonnement 1 an",
|
|
409
|
+
"2y": "Abonnement 2 ans",
|
|
410
|
+
"3y": "Abonnement 3 ans",
|
|
411
|
+
"price-6m": "79.-",
|
|
412
|
+
"price-6m-disc": "59.-",
|
|
413
|
+
"price-1y": "99.-",
|
|
414
|
+
"price-1y-disc": "79.-",
|
|
415
|
+
"price-2y": "198.-",
|
|
416
|
+
"price-2y-disc": "173.-",
|
|
417
|
+
"price-3y": "297.-",
|
|
418
|
+
"price-3y-disc": "247.-",
|
|
419
|
+
"price-gift": "99.-",
|
|
420
|
+
"price-gift-disc": "59.-"
|
|
421
|
+
},
|
|
422
|
+
subheadline: {
|
|
423
|
+
"your-hc": "Votre HotelCard",
|
|
424
|
+
"popular-hotels": "Offres d\u2019h\xF4tels populaires",
|
|
425
|
+
"no-results": "Explorez d\u2019autres destinations, modifiez vos dates ou retirez certains filtres.",
|
|
426
|
+
"sort-by": "Trier par"
|
|
427
|
+
},
|
|
428
|
+
form: {
|
|
429
|
+
guests: "personnes",
|
|
430
|
+
guest: "personne",
|
|
431
|
+
adults: "Adultes",
|
|
432
|
+
children: "Enfants",
|
|
433
|
+
pet: "Animal domestique",
|
|
434
|
+
"age-of-child": "\xC2ge de l\u2019enfant",
|
|
435
|
+
age: "\xC2ge",
|
|
436
|
+
"age-error": "Veuillez s\xE9lectionner l\u2019\xE2ge"
|
|
437
|
+
},
|
|
438
|
+
filter: {
|
|
439
|
+
filters: "Filtres",
|
|
440
|
+
destination: "Destination",
|
|
441
|
+
experience: "Exp\xE9rience",
|
|
442
|
+
"show-all": "Tout afficher",
|
|
443
|
+
price: "Prix",
|
|
444
|
+
discount: "R\xE9duction",
|
|
445
|
+
services: "Services",
|
|
446
|
+
meals: "Repas",
|
|
447
|
+
"hotel-category": "Cat\xE9gorie d\u2019h\xF4tel",
|
|
448
|
+
reviews: "Avis",
|
|
449
|
+
mobility: "Mobilit\xE9",
|
|
450
|
+
"wellness-spa": "Bien-\xEAtre & Spa",
|
|
451
|
+
"price-high-low": "Prix : du plus bas",
|
|
452
|
+
"price-low-high": "Prix : du plus \xE9lev\xE9",
|
|
453
|
+
"best-rating": "Meilleure note",
|
|
454
|
+
"most-popular": "Plus populaires",
|
|
455
|
+
"newest-hotels": "Plus r\xE9cents",
|
|
456
|
+
relevance: "Pertinence",
|
|
457
|
+
selected: "String value",
|
|
458
|
+
"clear-all": "Tout effacer",
|
|
459
|
+
options: "Services",
|
|
460
|
+
"hotellerie-suisse": "Classification HotellerieSuisse",
|
|
461
|
+
trustyou: "Avis de voyageurs sur TrustYou\xAE",
|
|
462
|
+
"select-all": "Tout s\xE9lectionner",
|
|
463
|
+
reset: "R\xE9initialiser",
|
|
464
|
+
"breakfast-included": "Petit-d\xE9jeuner inclus"
|
|
465
|
+
},
|
|
466
|
+
headline: {
|
|
467
|
+
"no-results": "Aucun s\xE9jour ne correspond \xE0 votre recherche pour le moment"
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/locales/it.json
|
|
472
|
+
var it_default = {
|
|
473
|
+
button: {
|
|
474
|
+
order: "Ordina ora",
|
|
475
|
+
"order-navigation": "Ordina ora",
|
|
476
|
+
"order-hc": "Ordina HotelCard",
|
|
477
|
+
"my-account": "Il mio profilo",
|
|
478
|
+
search: "Cerca",
|
|
479
|
+
"back-to-top": "Torna su"
|
|
480
|
+
},
|
|
481
|
+
link: {
|
|
482
|
+
"member-benefits": "Member Benefits",
|
|
483
|
+
"view-all-hotels": "Tutte le offerte hotel",
|
|
484
|
+
"search-by-map": "Ricerca sulla mappa",
|
|
485
|
+
"search-by-region": "Hotel per regione",
|
|
486
|
+
"search-by-experience": "Hotel per esperienza",
|
|
487
|
+
"travel-inspiration": "Ispirazioni di viaggio",
|
|
488
|
+
"booking-tips-and-tricks": "Consigli prenotazione",
|
|
489
|
+
home: "Home",
|
|
490
|
+
"all-hotel-deals": "Tutte le offerte hotel",
|
|
491
|
+
"search-results": "Risultati di ricerca"
|
|
492
|
+
},
|
|
493
|
+
general: {
|
|
494
|
+
"signed-out": "Accedi e prenota",
|
|
495
|
+
"room-price": "a partire da CHF xxx per camera",
|
|
496
|
+
guarantee: "Garanzia di rimborso di 14 giorni",
|
|
497
|
+
contact: "Altre domande? Contattaci.",
|
|
498
|
+
"breakfast-included": "Colazione inclusa",
|
|
499
|
+
"free-cancellation": "Cancellazione gratuita",
|
|
500
|
+
"suggested-destinations": "Destinazioni suggerite",
|
|
501
|
+
"when-months": "Quando vuoi viaggiare?",
|
|
502
|
+
"hotel-deals-found": "offerte hotel trovate",
|
|
503
|
+
"no-results": "Prova altre destinazioni, cambia le date o rimuovi qualche filtro.",
|
|
504
|
+
"unavailable-for-selected-days": "Non disponibile per le date selezionate.",
|
|
505
|
+
"cant-accommodate-all": "L\u2019hotel non pu\xF2 accogliere tutti gli ospiti.",
|
|
506
|
+
"reset-destination": "Reimposta la destinazione e filtra per regione"
|
|
507
|
+
},
|
|
508
|
+
label: {
|
|
509
|
+
"price-from": "a partire da ",
|
|
510
|
+
"price-for": "per camera",
|
|
511
|
+
"per-room-night": "per camera e notte da",
|
|
512
|
+
new: "Nuovo",
|
|
513
|
+
anytime: "In qualsiasi momento",
|
|
514
|
+
anywhere: "Tutte le destinazioni",
|
|
515
|
+
dates: "Date",
|
|
516
|
+
flexible: "Flessibile",
|
|
517
|
+
where: "Dove",
|
|
518
|
+
when: "Date",
|
|
519
|
+
who: "Chi",
|
|
520
|
+
nearby: "Nelle vicinanze",
|
|
521
|
+
hotels: "Hotel",
|
|
522
|
+
filter: "Filtra",
|
|
523
|
+
sort: "Ordina",
|
|
524
|
+
map: "Mappa",
|
|
525
|
+
rating: "Rating",
|
|
526
|
+
"rating-excellent": "Eccellente",
|
|
527
|
+
"rating-very-good": "Ottimo",
|
|
528
|
+
"rating-good": "Buono",
|
|
529
|
+
"rating-fair": "Sufficiente",
|
|
530
|
+
"rating-none": "Nessun voto"
|
|
531
|
+
},
|
|
532
|
+
product: {
|
|
533
|
+
"6m": "Abbonamento di 6 mesi",
|
|
534
|
+
"1y": "Abbonamento 1 anno",
|
|
535
|
+
"2y": "Abbonamento 2 anni",
|
|
536
|
+
"3y": "Abbonamento 3 anni",
|
|
537
|
+
"price-6m": "79.-",
|
|
538
|
+
"price-6m-disc": "59.-",
|
|
539
|
+
"price-1y": "99.-",
|
|
540
|
+
"price-1y-disc": "79.-",
|
|
541
|
+
"price-2y": "198.-",
|
|
542
|
+
"price-2y-disc": "173.-",
|
|
543
|
+
"price-3y": "297.-",
|
|
544
|
+
"price-3y-disc": "247.-",
|
|
545
|
+
"price-gift": "99.-",
|
|
546
|
+
"price-gift-disc": "59.-"
|
|
547
|
+
},
|
|
548
|
+
subheadline: {
|
|
549
|
+
"your-hc": "La sua HotelCard",
|
|
550
|
+
"popular-hotels": "Offerte hotel popolari",
|
|
551
|
+
"no-results": "Prova altre destinazioni, cambia le date o rimuovi qualche filtro.",
|
|
552
|
+
"sort-by": "Ordina per"
|
|
553
|
+
},
|
|
554
|
+
form: {
|
|
555
|
+
guests: "ospiti",
|
|
556
|
+
guest: "ospite",
|
|
557
|
+
adults: "Adulti",
|
|
558
|
+
children: "Bambini",
|
|
559
|
+
pet: "Animale domestico",
|
|
560
|
+
"age-of-child": "L'et\xE0 del bambino",
|
|
561
|
+
age: "L'et\xE0",
|
|
562
|
+
"age-error": "Seleziona l\u2019et\xE0"
|
|
563
|
+
},
|
|
564
|
+
filter: {
|
|
565
|
+
filters: "Filtri",
|
|
566
|
+
destination: "Destinazione",
|
|
567
|
+
experience: "Esperienza",
|
|
568
|
+
"show-all": "Mostra tutto",
|
|
569
|
+
price: "Prezzo",
|
|
570
|
+
discount: "Sconto",
|
|
571
|
+
services: "Servizi",
|
|
572
|
+
meals: "Pasti",
|
|
573
|
+
"hotel-category": "Categoria hotel",
|
|
574
|
+
reviews: "Recensioni",
|
|
575
|
+
mobility: "Mobilit\xE0",
|
|
576
|
+
"wellness-spa": "Wellness & Spa",
|
|
577
|
+
"price-high-low": "Prezzo: dal pi\xF9 basso",
|
|
578
|
+
"price-low-high": "Prezzo: dal pi\xF9 alto",
|
|
579
|
+
"best-rating": "Miglior voto",
|
|
580
|
+
"most-popular": "Pi\xF9 popolari",
|
|
581
|
+
"newest-hotels": "Pi\xF9 recenti",
|
|
582
|
+
relevance: "Rilevanza",
|
|
583
|
+
selected: "String value",
|
|
584
|
+
"clear-all": "Cancella tutto",
|
|
585
|
+
options: "Servizi",
|
|
586
|
+
"hotellerie-suisse": "Classificazione HotellerieSuisse",
|
|
587
|
+
trustyou: "Recensioni dei viaggiatori su TrustYou\xAE",
|
|
588
|
+
"select-all": "Seleziona tutto",
|
|
589
|
+
reset: "Reimposta",
|
|
590
|
+
"breakfast-included": "Colazione inclusa"
|
|
591
|
+
},
|
|
592
|
+
headline: {
|
|
593
|
+
"no-results": "Al momento nessun soggiorno corrisponde alla tua ricerca"
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
// src/locales/index.ts
|
|
598
|
+
var translations = { de: de_default, en: en_default, fr: fr_default, it: it_default };
|
|
599
|
+
|
|
600
|
+
// src/context/UIContext.tsx
|
|
67
601
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
602
|
+
function getNestedValue(obj, path) {
|
|
603
|
+
const keys = path.split(".");
|
|
604
|
+
let current = obj;
|
|
605
|
+
for (const key of keys) {
|
|
606
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
607
|
+
return void 0;
|
|
608
|
+
}
|
|
609
|
+
current = current[key];
|
|
610
|
+
}
|
|
611
|
+
return typeof current === "string" ? current : void 0;
|
|
612
|
+
}
|
|
613
|
+
function createTranslateFunction(locale) {
|
|
614
|
+
const localeTranslations = translations[locale] || translations.en;
|
|
615
|
+
return (key, fallback) => {
|
|
616
|
+
const value = getNestedValue(localeTranslations, key);
|
|
617
|
+
return value ?? fallback ?? key;
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
var defaultT = createTranslateFunction("de");
|
|
68
621
|
var defaultValue = {
|
|
69
622
|
locale: "de",
|
|
70
623
|
currency: "CHF",
|
|
71
|
-
isDesktop: false
|
|
624
|
+
isDesktop: false,
|
|
625
|
+
t: defaultT
|
|
72
626
|
};
|
|
73
627
|
var UIContext = (0, import_react.createContext)(defaultValue);
|
|
74
628
|
var HotelCardUIProvider = ({
|
|
75
629
|
locale = "de",
|
|
76
630
|
currency = "CHF",
|
|
77
631
|
isDesktop = false,
|
|
632
|
+
t: customT,
|
|
78
633
|
children
|
|
79
634
|
}) => {
|
|
80
|
-
const
|
|
635
|
+
const t = (0, import_react.useMemo)(
|
|
636
|
+
() => customT ?? createTranslateFunction(locale),
|
|
637
|
+
[locale, customT]
|
|
638
|
+
);
|
|
639
|
+
const value = (0, import_react.useMemo)(
|
|
640
|
+
() => ({ locale, currency, isDesktop, t }),
|
|
641
|
+
[locale, currency, isDesktop, t]
|
|
642
|
+
);
|
|
81
643
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UIContext.Provider, { value, children });
|
|
82
644
|
};
|
|
83
645
|
var useUIContext = () => {
|
|
@@ -1557,14 +2119,6 @@ var getDateLocale = (locale) => {
|
|
|
1557
2119
|
};
|
|
1558
2120
|
return localeMap[locale] || "de-CH";
|
|
1559
2121
|
};
|
|
1560
|
-
var defaultLabels = {
|
|
1561
|
-
when: "When",
|
|
1562
|
-
dates: "Dates",
|
|
1563
|
-
flexible: "Flexible",
|
|
1564
|
-
apply: "Apply",
|
|
1565
|
-
selectMonths: "Select months",
|
|
1566
|
-
anytime: "Anytime"
|
|
1567
|
-
};
|
|
1568
2122
|
var WhenContent = ({
|
|
1569
2123
|
initialDateRange = { start: null, end: null },
|
|
1570
2124
|
initialMonthFilter = null,
|
|
@@ -1574,14 +2128,21 @@ var WhenContent = ({
|
|
|
1574
2128
|
showApplyButton = true,
|
|
1575
2129
|
onApply,
|
|
1576
2130
|
className = "",
|
|
1577
|
-
labels: labelsProp,
|
|
1578
2131
|
locale: localeProp
|
|
1579
2132
|
}) => {
|
|
1580
2133
|
const { locale: contextLocale } = useWindowData();
|
|
1581
2134
|
const { isDesktop } = useResponsive();
|
|
2135
|
+
const { t } = useUIContext();
|
|
1582
2136
|
const locale = localeProp || contextLocale;
|
|
1583
2137
|
const dateLocale = getDateLocale(locale);
|
|
1584
|
-
const labels = {
|
|
2138
|
+
const labels = {
|
|
2139
|
+
when: t("label.when", "When"),
|
|
2140
|
+
dates: t("label.dates", "Dates"),
|
|
2141
|
+
flexible: t("label.flexible", "Flexible"),
|
|
2142
|
+
apply: t("button.search", "Apply"),
|
|
2143
|
+
selectMonths: t("general.when-months", "Select months"),
|
|
2144
|
+
anytime: t("label.anytime", "Anytime")
|
|
2145
|
+
};
|
|
1585
2146
|
const [dateRange, setDateRange] = (0, import_react12.useState)(initialDateRange);
|
|
1586
2147
|
const [mode, setMode] = (0, import_react12.useState)(
|
|
1587
2148
|
initialDateRange.start ? "dates" : "anytime"
|
|
@@ -1787,7 +2348,7 @@ var DateSelector = ({
|
|
|
1787
2348
|
className,
|
|
1788
2349
|
icon
|
|
1789
2350
|
}) => {
|
|
1790
|
-
const { t } =
|
|
2351
|
+
const { t } = useUIContext();
|
|
1791
2352
|
const { locale } = useWindowData();
|
|
1792
2353
|
const { isDesktop } = useResponsive();
|
|
1793
2354
|
const dateLocale = getDateLocale2(locale);
|
|
@@ -1844,12 +2405,12 @@ var DateSelector = ({
|
|
|
1844
2405
|
}
|
|
1845
2406
|
if (selectedMonths.length === 1) {
|
|
1846
2407
|
const month = months.find((m) => m.value === selectedMonths[0]);
|
|
1847
|
-
return month ? `${month.label} ${month.year}` : t("
|
|
2408
|
+
return month ? `${month.label} ${month.year}` : t("label.flexible", "Flexible");
|
|
1848
2409
|
}
|
|
1849
2410
|
if (selectedMonths.length > 1) {
|
|
1850
|
-
return
|
|
2411
|
+
return `${selectedMonths.length} months`;
|
|
1851
2412
|
}
|
|
1852
|
-
return t("
|
|
2413
|
+
return t("label.flexible", "Flexible");
|
|
1853
2414
|
};
|
|
1854
2415
|
const handleDateRangeChange = (range) => {
|
|
1855
2416
|
setDateRange(range ?? { start: null, end: null });
|
|
@@ -1937,18 +2498,6 @@ var DropdownIcon = () => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
|
1937
2498
|
)
|
|
1938
2499
|
}
|
|
1939
2500
|
);
|
|
1940
|
-
var defaultLabels2 = {
|
|
1941
|
-
adults: "Adults",
|
|
1942
|
-
children: "Children",
|
|
1943
|
-
pet: "Pet",
|
|
1944
|
-
ageOfChild: "Age of child",
|
|
1945
|
-
age: "Age",
|
|
1946
|
-
decreaseAdults: "Decrease adults",
|
|
1947
|
-
increaseAdults: "Increase adults",
|
|
1948
|
-
decreaseChildren: "Decrease children",
|
|
1949
|
-
increaseChildren: "Increase children",
|
|
1950
|
-
togglePets: "Toggle pets"
|
|
1951
|
-
};
|
|
1952
2501
|
var GuestContent = ({
|
|
1953
2502
|
guests,
|
|
1954
2503
|
onChange,
|
|
@@ -1957,10 +2506,21 @@ var GuestContent = ({
|
|
|
1957
2506
|
showPetToggle = true,
|
|
1958
2507
|
className = "",
|
|
1959
2508
|
childAgeErrors = [],
|
|
1960
|
-
onErrorClear
|
|
1961
|
-
labels: labelsProp
|
|
2509
|
+
onErrorClear
|
|
1962
2510
|
}) => {
|
|
1963
|
-
const
|
|
2511
|
+
const { t } = useUIContext();
|
|
2512
|
+
const labels = {
|
|
2513
|
+
adults: t("form.adults", "Adults"),
|
|
2514
|
+
children: t("form.children", "Children"),
|
|
2515
|
+
pet: t("form.pet", "Pet"),
|
|
2516
|
+
ageOfChild: t("form.age-of-child", "Age of child"),
|
|
2517
|
+
age: t("form.age", "Age"),
|
|
2518
|
+
decreaseAdults: "Decrease adults",
|
|
2519
|
+
increaseAdults: "Increase adults",
|
|
2520
|
+
decreaseChildren: "Decrease children",
|
|
2521
|
+
increaseChildren: "Increase children",
|
|
2522
|
+
togglePets: "Toggle pets"
|
|
2523
|
+
};
|
|
1964
2524
|
const childrenAges = Array.isArray(guests.childrenAges) ? guests.childrenAges : [];
|
|
1965
2525
|
const handleIncrement = (type) => {
|
|
1966
2526
|
if (type === "children" && guests.children >= 6) return;
|
|
@@ -2147,21 +2707,19 @@ var HeartIcon2 = ({ filled }) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
|
2147
2707
|
]
|
|
2148
2708
|
}
|
|
2149
2709
|
);
|
|
2150
|
-
var defaultLabels3 = {
|
|
2151
|
-
removeFromFavorites: "Remove from favorites",
|
|
2152
|
-
addToFavorites: "Add to favorites",
|
|
2153
|
-
previousImage: "Previous image",
|
|
2154
|
-
nextImage: "Next image"
|
|
2155
|
-
};
|
|
2156
2710
|
var HotelCardImage = ({
|
|
2157
2711
|
images,
|
|
2158
2712
|
hotelName,
|
|
2159
2713
|
badges,
|
|
2160
2714
|
isFavorite,
|
|
2161
|
-
onFavoriteClick
|
|
2162
|
-
labels: labelsProp
|
|
2715
|
+
onFavoriteClick
|
|
2163
2716
|
}) => {
|
|
2164
|
-
const labels = {
|
|
2717
|
+
const labels = {
|
|
2718
|
+
removeFromFavorites: "Remove from favorites",
|
|
2719
|
+
addToFavorites: "Add to favorites",
|
|
2720
|
+
previousImage: "Previous image",
|
|
2721
|
+
nextImage: "Next image"
|
|
2722
|
+
};
|
|
2165
2723
|
const displayImages = images.slice(0, MAX_IMAGES);
|
|
2166
2724
|
const [currentImageIndex, setCurrentImageIndex] = (0, import_react14.useState)(0);
|
|
2167
2725
|
const [failedImages, setFailedImages] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
@@ -2304,16 +2862,6 @@ var BreakfastIcon = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("svg",
|
|
|
2304
2862
|
var FreeCancellationIcon = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M0.838695 4.18584L2.62218 6.00458C2.85502 6.24202 3.23153 6.24202 3.4619 6.00458C3.69227 5.76713 3.69474 5.38317 3.4619 5.14825L2.69401 4.36518L3.66406 4.36518C3.9974 4.36518 4.33073 4.36518 4.37346 4.36518C4.66406 4.36518 4.66406 4.36518 4.9974 4.36518L5.22309 4.36518H5.22804H11.5644C11.5644 5.25687 12.2753 5.98184 13.1497 5.98184V8.61902C13.5386 8.66196 13.9151 8.83625 14.2123 9.13938L14.3387 9.26821V4.76682C14.3387 3.87513 13.6278 3.15016 12.7533 3.15016H4.37346H2.69649L3.46438 2.3671C3.69722 2.12965 3.69722 1.74569 3.46438 1.51077C3.23153 1.27585 2.85502 1.27332 2.62218 1.50825L0.838695 3.32699C0.605852 3.56443 0.605852 3.94839 0.838695 4.18331V4.18584ZM1.65612 6.73207V11.2335C1.65612 12.1251 2.36704 12.8501 3.24144 12.8501H13.3008L12.5329 13.6332C12.3 13.8706 12.3 14.2546 12.5329 14.4895C12.7657 14.7244 13.1422 14.727 13.3726 14.4895L15.1561 12.6708C15.3889 12.4333 15.3889 12.0494 15.1561 11.8144L13.3726 9.9957C13.1398 9.75826 12.7633 9.75826 12.5329 9.9957C12.3025 10.2331 12.3 10.6171 12.5329 10.852L13.3008 11.6351L12.3307 11.6351C11.974 11.6351 11.9036 11.6351 11.737 11.6351C11.6641 11.6351 11.6354 11.6351 11.5644 11.6351H4.43043C4.43043 10.7434 3.71952 10.0184 2.84511 10.0184V7.38126C2.45622 7.33832 2.0797 7.16402 1.78245 6.8609L1.65612 6.73207ZM10.3754 8.00014C10.3754 7.35699 10.1248 6.74019 9.67888 6.28541C9.23292 5.83064 8.62807 5.57515 7.9974 5.57515C7.36672 5.57515 6.76187 5.83064 6.31591 6.28541C5.86996 6.74019 5.61942 7.35699 5.61942 8.00014C5.61942 8.64329 5.86996 9.26009 6.31591 9.71486C6.76187 10.1696 7.36672 10.4251 7.9974 10.4251C8.62807 10.4251 9.23292 10.1696 9.67888 9.71486C10.1248 9.26009 10.3754 8.64329 10.3754 8.00014Z", fill: "#006962" }) });
|
|
2305
2863
|
var CheckmarkIcon = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M13.5 4.5L6 12L2.5 8.5", stroke: "#006962", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
2306
2864
|
var RatingBadgeSvg = () => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("svg", { width: "32", height: "24", viewBox: "0 0 36 38", fill: "#478EFA", className: "hc-hotel-card__rating-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { d: "M4 0C1.79086 0 0 1.79086 0 4V32V38L9 32H32C34.2091 32 36 30.2091 36 28V0H4Z" }) });
|
|
2307
|
-
var defaultLabels4 = {
|
|
2308
|
-
ratingExcellent: "Excellent",
|
|
2309
|
-
ratingVeryGood: "Very Good",
|
|
2310
|
-
ratingGood: "Good",
|
|
2311
|
-
ratingFair: "Fair",
|
|
2312
|
-
rating: "Rating",
|
|
2313
|
-
priceFrom: "per room & night from",
|
|
2314
|
-
notAvailable: "Not available",
|
|
2315
|
-
swissLodge: "Swiss Lodge"
|
|
2316
|
-
};
|
|
2317
2865
|
var HotelCardContent = ({
|
|
2318
2866
|
name,
|
|
2319
2867
|
stars,
|
|
@@ -2324,10 +2872,19 @@ var HotelCardContent = ({
|
|
|
2324
2872
|
price,
|
|
2325
2873
|
currency = "CHF",
|
|
2326
2874
|
isAvailable = true,
|
|
2327
|
-
onClick
|
|
2328
|
-
labels: labelsProp
|
|
2875
|
+
onClick
|
|
2329
2876
|
}) => {
|
|
2330
|
-
const
|
|
2877
|
+
const { t } = useUIContext();
|
|
2878
|
+
const labels = {
|
|
2879
|
+
ratingExcellent: t("label.rating-excellent", "Excellent"),
|
|
2880
|
+
ratingVeryGood: t("label.rating-very-good", "Very good"),
|
|
2881
|
+
ratingGood: t("label.rating-good", "Good"),
|
|
2882
|
+
ratingFair: t("label.rating-fair", "Fair"),
|
|
2883
|
+
rating: t("label.rating", "Rating"),
|
|
2884
|
+
priceFrom: t("label.per-room-night", "per room & night from"),
|
|
2885
|
+
notAvailable: t("general.unavailable-for-selected-days", "Not available"),
|
|
2886
|
+
swissLodge: "Swiss Lodge"
|
|
2887
|
+
};
|
|
2331
2888
|
const getRatingCategory = (score) => {
|
|
2332
2889
|
if (score >= 4.4) return labels.ratingExcellent;
|
|
2333
2890
|
if (score >= 4.1) return labels.ratingVeryGood;
|
|
@@ -2378,20 +2935,22 @@ var HotelCardContent = ({
|
|
|
2378
2935
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__pin-icon", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(PinIcon, {}) }),
|
|
2379
2936
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__location", children: location })
|
|
2380
2937
|
] }),
|
|
2381
|
-
|
|
2382
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
"-",
|
|
2393
|
-
|
|
2394
|
-
|
|
2938
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "hc-hotel-card__benefits-and-pricing", children: [
|
|
2939
|
+
benefits.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "hc-hotel-card__benefits-section", children: benefits.slice(0, 3).map((benefit, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "hc-hotel-card__benefit", children: [
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__benefit-icon", children: getBenefitIcon(benefit.id) }),
|
|
2941
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__benefit-text", children: benefit.label })
|
|
2942
|
+
] }, index)) }),
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "hc-hotel-card__pricing-section", children: [
|
|
2944
|
+
isAvailable && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "hc-hotel-card__price-label", children: labels.priceFrom }),
|
|
2945
|
+
!isAvailable && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "hc-hotel-card__not-available", children: labels.notAvailable }),
|
|
2946
|
+
isAvailable && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "hc-hotel-card__price-container", children: [
|
|
2947
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__current-price", children: `${currency} ${price.current}` }),
|
|
2948
|
+
price.original && price.original > price.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "hc-hotel-card__original-price", children: `${currency} ${price.original}` }),
|
|
2949
|
+
price.discount && price.discount > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "hc-hotel-card__discount-badge", children: [
|
|
2950
|
+
"-",
|
|
2951
|
+
price.discount,
|
|
2952
|
+
" %"
|
|
2953
|
+
] })
|
|
2395
2954
|
] })
|
|
2396
2955
|
] })
|
|
2397
2956
|
] })
|
|
@@ -2406,7 +2965,6 @@ var HotelCard = ({
|
|
|
2406
2965
|
hotel,
|
|
2407
2966
|
onFavoriteClick,
|
|
2408
2967
|
onContentClick,
|
|
2409
|
-
labels = {},
|
|
2410
2968
|
className
|
|
2411
2969
|
}) => {
|
|
2412
2970
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: `hc-hotel-card ${className || ""}`, children: [
|
|
@@ -2417,13 +2975,7 @@ var HotelCard = ({
|
|
|
2417
2975
|
hotelName: hotel.name,
|
|
2418
2976
|
badges: hotel.badges,
|
|
2419
2977
|
isFavorite: hotel.isFavorite,
|
|
2420
|
-
onFavoriteClick
|
|
2421
|
-
labels: {
|
|
2422
|
-
removeFromFavorites: labels.removeFromFavorites,
|
|
2423
|
-
addToFavorites: labels.addToFavorites,
|
|
2424
|
-
previousImage: labels.previousImage,
|
|
2425
|
-
nextImage: labels.nextImage
|
|
2426
|
-
}
|
|
2978
|
+
onFavoriteClick
|
|
2427
2979
|
}
|
|
2428
2980
|
),
|
|
2429
2981
|
hotel.usp && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "hc-hotel-card__usp-banner", children: hotel.usp }),
|
|
@@ -2439,25 +2991,866 @@ var HotelCard = ({
|
|
|
2439
2991
|
price: hotel.price,
|
|
2440
2992
|
currency: hotel.currency,
|
|
2441
2993
|
isAvailable: hotel.isAvailable,
|
|
2442
|
-
onClick: onContentClick
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2994
|
+
onClick: onContentClick
|
|
2995
|
+
}
|
|
2996
|
+
)
|
|
2997
|
+
] });
|
|
2998
|
+
};
|
|
2999
|
+
|
|
3000
|
+
// src/components/Filters/FilterCheckboxItem.module.css
|
|
3001
|
+
var FilterCheckboxItem_default = {};
|
|
3002
|
+
|
|
3003
|
+
// src/components/Filters/FilterCheckboxItem.tsx
|
|
3004
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3005
|
+
var FilterCheckboxItem = ({
|
|
3006
|
+
id,
|
|
3007
|
+
label,
|
|
3008
|
+
count,
|
|
3009
|
+
checked,
|
|
3010
|
+
disabled = false,
|
|
3011
|
+
onChange,
|
|
3012
|
+
className = "",
|
|
3013
|
+
trackName
|
|
3014
|
+
}) => {
|
|
3015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3016
|
+
"label",
|
|
3017
|
+
{
|
|
3018
|
+
className: `${FilterCheckboxItem_default.filterRow} ${disabled ? FilterCheckboxItem_default.filterRowDisabled : ""} ${className}`,
|
|
3019
|
+
tabIndex: disabled ? -1 : 0,
|
|
3020
|
+
"data-track": trackName,
|
|
3021
|
+
children: [
|
|
3022
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: FilterCheckboxItem_default.checkboxLabel, children: [
|
|
3023
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: FilterCheckboxItem_default.checkboxButton, children: [
|
|
3024
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3025
|
+
"input",
|
|
3026
|
+
{
|
|
3027
|
+
id,
|
|
3028
|
+
type: "checkbox",
|
|
3029
|
+
className: FilterCheckboxItem_default.checkbox,
|
|
3030
|
+
checked,
|
|
3031
|
+
disabled,
|
|
3032
|
+
onChange
|
|
3033
|
+
}
|
|
3034
|
+
),
|
|
3035
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `${FilterCheckboxItem_default.checkboxBox} ${disabled ? FilterCheckboxItem_default.checkboxBoxDisabled : ""}`, children: checked && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("svg", { viewBox: "0 0 12 10", fill: "none", className: FilterCheckboxItem_default.checkIcon, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3036
|
+
"path",
|
|
3037
|
+
{
|
|
3038
|
+
d: "M1 5L4.5 8.5L11 1",
|
|
3039
|
+
stroke: "currentColor",
|
|
3040
|
+
strokeWidth: "2",
|
|
3041
|
+
strokeLinecap: "round",
|
|
3042
|
+
strokeLinejoin: "round"
|
|
3043
|
+
}
|
|
3044
|
+
) }) })
|
|
3045
|
+
] }),
|
|
3046
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `${FilterCheckboxItem_default.filterLabel} ${disabled ? FilterCheckboxItem_default.filterLabelDisabled : ""}`, children: label })
|
|
3047
|
+
] }),
|
|
3048
|
+
count !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: `${FilterCheckboxItem_default.filterCount} ${disabled ? FilterCheckboxItem_default.filterCountDisabled : ""}`, children: count })
|
|
3049
|
+
]
|
|
3050
|
+
}
|
|
3051
|
+
);
|
|
3052
|
+
};
|
|
3053
|
+
|
|
3054
|
+
// src/components/Filters/CollapsibleFilterSection.tsx
|
|
3055
|
+
var import_react15 = __toESM(require("react"), 1);
|
|
3056
|
+
|
|
3057
|
+
// src/components/Filters/CollapsibleFilterSection.module.css
|
|
3058
|
+
var CollapsibleFilterSection_default = {};
|
|
3059
|
+
|
|
3060
|
+
// src/components/Filters/CollapsibleFilterSection.tsx
|
|
3061
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3062
|
+
var CollapsibleFilterSection = ({
|
|
3063
|
+
title,
|
|
3064
|
+
children,
|
|
3065
|
+
defaultExpanded = true,
|
|
3066
|
+
showAllText,
|
|
3067
|
+
showLessText,
|
|
3068
|
+
hasShowAll = false,
|
|
3069
|
+
initialItemsToShow = 5,
|
|
3070
|
+
className = ""
|
|
3071
|
+
}) => {
|
|
3072
|
+
const { t } = useUIContext();
|
|
3073
|
+
const [isExpanded, setIsExpanded] = (0, import_react15.useState)(defaultExpanded);
|
|
3074
|
+
const [showAll, setShowAll] = (0, import_react15.useState)(false);
|
|
3075
|
+
const resolvedShowAllText = showAllText ?? t("filter.show-all", "Show all");
|
|
3076
|
+
const resolvedShowLessText = showLessText ?? t("filter.show-less", "Show less");
|
|
3077
|
+
(0, import_react15.useEffect)(() => {
|
|
3078
|
+
if (defaultExpanded && !isExpanded) {
|
|
3079
|
+
setIsExpanded(true);
|
|
3080
|
+
}
|
|
3081
|
+
}, [defaultExpanded]);
|
|
3082
|
+
const toggleExpanded = () => {
|
|
3083
|
+
setIsExpanded(!isExpanded);
|
|
3084
|
+
};
|
|
3085
|
+
const toggleShowAll = () => {
|
|
3086
|
+
setShowAll(!showAll);
|
|
3087
|
+
};
|
|
3088
|
+
const childrenArray = import_react15.default.Children.toArray(children);
|
|
3089
|
+
const shouldShowToggle = hasShowAll && childrenArray.length > initialItemsToShow;
|
|
3090
|
+
const displayedChildren = shouldShowToggle && !showAll ? childrenArray.slice(0, initialItemsToShow) : childrenArray;
|
|
3091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: `${CollapsibleFilterSection_default.section} ${className}`, children: [
|
|
3092
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3093
|
+
"button",
|
|
3094
|
+
{
|
|
3095
|
+
type: "button",
|
|
3096
|
+
className: CollapsibleFilterSection_default.header,
|
|
3097
|
+
onClick: toggleExpanded,
|
|
3098
|
+
"aria-expanded": isExpanded,
|
|
3099
|
+
children: [
|
|
3100
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: CollapsibleFilterSection_default.title, children: title }),
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3102
|
+
"svg",
|
|
3103
|
+
{
|
|
3104
|
+
className: `${CollapsibleFilterSection_default.chevron} ${isExpanded ? CollapsibleFilterSection_default.chevronExpanded : ""}`,
|
|
3105
|
+
viewBox: "0 0 24 24",
|
|
3106
|
+
fill: "none",
|
|
3107
|
+
"aria-hidden": "true",
|
|
3108
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3109
|
+
"path",
|
|
3110
|
+
{
|
|
3111
|
+
d: "M6 9L12 15L18 9",
|
|
3112
|
+
stroke: "currentColor",
|
|
3113
|
+
strokeWidth: "2",
|
|
3114
|
+
strokeLinecap: "round",
|
|
3115
|
+
strokeLinejoin: "round"
|
|
3116
|
+
}
|
|
3117
|
+
)
|
|
3118
|
+
}
|
|
3119
|
+
)
|
|
3120
|
+
]
|
|
3121
|
+
}
|
|
3122
|
+
),
|
|
3123
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3124
|
+
"div",
|
|
3125
|
+
{
|
|
3126
|
+
className: `${CollapsibleFilterSection_default.content} ${isExpanded ? CollapsibleFilterSection_default.contentExpanded : ""}`,
|
|
3127
|
+
"aria-hidden": !isExpanded,
|
|
3128
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: CollapsibleFilterSection_default.contentInner, children: [
|
|
3129
|
+
displayedChildren,
|
|
3130
|
+
shouldShowToggle && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
3131
|
+
"button",
|
|
3132
|
+
{
|
|
3133
|
+
type: "button",
|
|
3134
|
+
className: CollapsibleFilterSection_default.showAllButton,
|
|
3135
|
+
onClick: toggleShowAll,
|
|
3136
|
+
children: [
|
|
3137
|
+
showAll ? resolvedShowLessText : resolvedShowAllText,
|
|
3138
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3139
|
+
"svg",
|
|
3140
|
+
{
|
|
3141
|
+
className: `${CollapsibleFilterSection_default.showAllChevron} ${showAll ? CollapsibleFilterSection_default.showAllChevronUp : ""}`,
|
|
3142
|
+
viewBox: "0 0 24 24",
|
|
3143
|
+
fill: "none",
|
|
3144
|
+
"aria-hidden": "true",
|
|
3145
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3146
|
+
"path",
|
|
3147
|
+
{
|
|
3148
|
+
d: "M6 9L12 15L18 9",
|
|
3149
|
+
stroke: "currentColor",
|
|
3150
|
+
strokeWidth: "2",
|
|
3151
|
+
strokeLinecap: "round",
|
|
3152
|
+
strokeLinejoin: "round"
|
|
3153
|
+
}
|
|
3154
|
+
)
|
|
3155
|
+
}
|
|
3156
|
+
)
|
|
3157
|
+
]
|
|
3158
|
+
}
|
|
3159
|
+
)
|
|
3160
|
+
] })
|
|
3161
|
+
}
|
|
3162
|
+
)
|
|
3163
|
+
] });
|
|
3164
|
+
};
|
|
3165
|
+
|
|
3166
|
+
// src/components/Filters/PriceRangeFilter.tsx
|
|
3167
|
+
var import_react16 = require("react");
|
|
3168
|
+
|
|
3169
|
+
// src/components/Filters/PriceRangeFilter.module.css
|
|
3170
|
+
var PriceRangeFilter_default = {};
|
|
3171
|
+
|
|
3172
|
+
// src/components/Filters/PriceRangeFilter.tsx
|
|
3173
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3174
|
+
var DEFAULT_HISTOGRAM = [
|
|
3175
|
+
12,
|
|
3176
|
+
25,
|
|
3177
|
+
38,
|
|
3178
|
+
45,
|
|
3179
|
+
52,
|
|
3180
|
+
48,
|
|
3181
|
+
42,
|
|
3182
|
+
35,
|
|
3183
|
+
28,
|
|
3184
|
+
22,
|
|
3185
|
+
18,
|
|
3186
|
+
15,
|
|
3187
|
+
12,
|
|
3188
|
+
10,
|
|
3189
|
+
8,
|
|
3190
|
+
6,
|
|
3191
|
+
5,
|
|
3192
|
+
4,
|
|
3193
|
+
3,
|
|
3194
|
+
2
|
|
3195
|
+
];
|
|
3196
|
+
var PriceRangeFilter = ({
|
|
3197
|
+
minPrice,
|
|
3198
|
+
maxPrice,
|
|
3199
|
+
value,
|
|
3200
|
+
onChange,
|
|
3201
|
+
onApply,
|
|
3202
|
+
histogram = DEFAULT_HISTOGRAM,
|
|
3203
|
+
currency,
|
|
3204
|
+
onDragStart,
|
|
3205
|
+
onDragEnd,
|
|
3206
|
+
debounceDelay = 500
|
|
3207
|
+
}) => {
|
|
3208
|
+
const { t, currency: contextCurrency } = useUIContext();
|
|
3209
|
+
const displayCurrency = currency ?? contextCurrency;
|
|
3210
|
+
const sliderRef = (0, import_react16.useRef)(null);
|
|
3211
|
+
const [isDragging, setIsDragging] = (0, import_react16.useState)(null);
|
|
3212
|
+
const [isDraggingExternal, setIsDraggingExternal] = (0, import_react16.useState)(false);
|
|
3213
|
+
const lastValueRef = (0, import_react16.useRef)(value);
|
|
3214
|
+
const timeoutRef = (0, import_react16.useRef)(null);
|
|
3215
|
+
const [minInputValue, setMinInputValue] = (0, import_react16.useState)("");
|
|
3216
|
+
const [maxInputValue, setMaxInputValue] = (0, import_react16.useState)("");
|
|
3217
|
+
const [minInputFocused, setMinInputFocused] = (0, import_react16.useState)(false);
|
|
3218
|
+
const [maxInputFocused, setMaxInputFocused] = (0, import_react16.useState)(false);
|
|
3219
|
+
const range = maxPrice - minPrice;
|
|
3220
|
+
const minPercent = range > 0 ? (value.min - minPrice) / range * 100 : 0;
|
|
3221
|
+
const maxPercent = range > 0 ? (value.max - minPrice) / range * 100 : 100;
|
|
3222
|
+
const maxHistogramValue = Math.max(...histogram, 1);
|
|
3223
|
+
const getBarActive = (0, import_react16.useCallback)((index) => {
|
|
3224
|
+
const barStartPercent = index / histogram.length * 100;
|
|
3225
|
+
const barEndPercent = (index + 1) / histogram.length * 100;
|
|
3226
|
+
return barStartPercent < maxPercent && barEndPercent > minPercent;
|
|
3227
|
+
}, [histogram.length, minPercent, maxPercent]);
|
|
3228
|
+
const trackInset = 12;
|
|
3229
|
+
const triggerOnApply = (0, import_react16.useCallback)((newValue) => {
|
|
3230
|
+
if (!onApply) return;
|
|
3231
|
+
if (timeoutRef.current) {
|
|
3232
|
+
clearTimeout(timeoutRef.current);
|
|
3233
|
+
}
|
|
3234
|
+
timeoutRef.current = setTimeout(() => {
|
|
3235
|
+
onApply(newValue);
|
|
3236
|
+
}, debounceDelay);
|
|
3237
|
+
}, [onApply, debounceDelay]);
|
|
3238
|
+
const handleDrag = (0, import_react16.useCallback)((clientX) => {
|
|
3239
|
+
if (!sliderRef.current || !isDragging) return;
|
|
3240
|
+
const rect = sliderRef.current.getBoundingClientRect();
|
|
3241
|
+
const trackWidth = rect.width - trackInset * 2;
|
|
3242
|
+
const trackLeft = rect.left + trackInset;
|
|
3243
|
+
const percent = Math.max(0, Math.min(100, (clientX - trackLeft) / trackWidth * 100));
|
|
3244
|
+
const newValue = Math.round(minPrice + percent / 100 * range);
|
|
3245
|
+
let newMin = value.min;
|
|
3246
|
+
let newMax = value.max;
|
|
3247
|
+
if (isDragging === "min") {
|
|
3248
|
+
const clampedValue = Math.min(newValue, value.max - 1);
|
|
3249
|
+
newMin = Math.max(minPrice, clampedValue);
|
|
3250
|
+
} else {
|
|
3251
|
+
const clampedValue = Math.max(newValue, value.min + 1);
|
|
3252
|
+
newMax = Math.min(maxPrice, clampedValue);
|
|
3253
|
+
}
|
|
3254
|
+
const newRange = { min: newMin, max: newMax };
|
|
3255
|
+
onChange(newRange);
|
|
3256
|
+
lastValueRef.current = newRange;
|
|
3257
|
+
if (!isDraggingExternal) {
|
|
3258
|
+
triggerOnApply(newRange);
|
|
3259
|
+
}
|
|
3260
|
+
}, [isDragging, minPrice, maxPrice, range, value, onChange, isDraggingExternal, triggerOnApply]);
|
|
3261
|
+
const handleMouseDown = (handle) => (e) => {
|
|
3262
|
+
e.preventDefault();
|
|
3263
|
+
setIsDragging(handle);
|
|
3264
|
+
setIsDraggingExternal(true);
|
|
3265
|
+
onDragStart?.();
|
|
3266
|
+
};
|
|
3267
|
+
const handleTouchStart = (handle) => (e) => {
|
|
3268
|
+
e.preventDefault();
|
|
3269
|
+
setIsDragging(handle);
|
|
3270
|
+
setIsDraggingExternal(true);
|
|
3271
|
+
onDragStart?.();
|
|
3272
|
+
};
|
|
3273
|
+
const handleDragEnd = (0, import_react16.useCallback)(() => {
|
|
3274
|
+
if (isDraggingExternal && onApply) {
|
|
3275
|
+
onApply(lastValueRef.current);
|
|
3276
|
+
}
|
|
3277
|
+
setIsDragging(null);
|
|
3278
|
+
setIsDraggingExternal(false);
|
|
3279
|
+
onDragEnd?.();
|
|
3280
|
+
}, [isDraggingExternal, onApply, onDragEnd]);
|
|
3281
|
+
(0, import_react16.useEffect)(() => {
|
|
3282
|
+
if (!isDragging) return;
|
|
3283
|
+
const handleMouseMove = (e) => {
|
|
3284
|
+
handleDrag(e.clientX);
|
|
3285
|
+
};
|
|
3286
|
+
const handleTouchMove = (e) => {
|
|
3287
|
+
if (e.touches.length > 0) {
|
|
3288
|
+
handleDrag(e.touches[0].clientX);
|
|
3289
|
+
}
|
|
3290
|
+
};
|
|
3291
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
3292
|
+
document.addEventListener("mouseup", handleDragEnd);
|
|
3293
|
+
document.addEventListener("touchmove", handleTouchMove, { passive: false });
|
|
3294
|
+
document.addEventListener("touchend", handleDragEnd);
|
|
3295
|
+
return () => {
|
|
3296
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
3297
|
+
document.removeEventListener("mouseup", handleDragEnd);
|
|
3298
|
+
document.removeEventListener("touchmove", handleTouchMove);
|
|
3299
|
+
document.removeEventListener("touchend", handleDragEnd);
|
|
3300
|
+
if (timeoutRef.current) {
|
|
3301
|
+
clearTimeout(timeoutRef.current);
|
|
3302
|
+
}
|
|
3303
|
+
};
|
|
3304
|
+
}, [isDragging, handleDrag, handleDragEnd]);
|
|
3305
|
+
const handleMinInputFocus = () => {
|
|
3306
|
+
setMinInputFocused(true);
|
|
3307
|
+
setMinInputValue(value.min.toString());
|
|
3308
|
+
};
|
|
3309
|
+
const handleMaxInputFocus = () => {
|
|
3310
|
+
setMaxInputFocused(true);
|
|
3311
|
+
setMaxInputValue(value.max.toString());
|
|
3312
|
+
};
|
|
3313
|
+
const handleMinInputChange = (e) => {
|
|
3314
|
+
const val = e.target.value.replace(/[^0-9]/g, "");
|
|
3315
|
+
setMinInputValue(val);
|
|
3316
|
+
};
|
|
3317
|
+
const handleMaxInputChange = (e) => {
|
|
3318
|
+
const val = e.target.value.replace(/[^0-9]/g, "");
|
|
3319
|
+
setMaxInputValue(val);
|
|
3320
|
+
};
|
|
3321
|
+
const handleMinInputBlur = () => {
|
|
3322
|
+
setMinInputFocused(false);
|
|
3323
|
+
const numValue = parseInt(minInputValue, 10);
|
|
3324
|
+
if (!isNaN(numValue)) {
|
|
3325
|
+
const clampedValue = Math.max(minPrice, Math.min(numValue, value.max - 1));
|
|
3326
|
+
const newRange = { min: clampedValue, max: value.max };
|
|
3327
|
+
onChange(newRange);
|
|
3328
|
+
if (onApply) {
|
|
3329
|
+
triggerOnApply(newRange);
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
};
|
|
3333
|
+
const handleMaxInputBlur = () => {
|
|
3334
|
+
setMaxInputFocused(false);
|
|
3335
|
+
const numValue = parseInt(maxInputValue, 10);
|
|
3336
|
+
if (!isNaN(numValue)) {
|
|
3337
|
+
const clampedValue = Math.min(maxPrice, Math.max(numValue, value.min + 1));
|
|
3338
|
+
const newRange = { min: value.min, max: clampedValue };
|
|
3339
|
+
onChange(newRange);
|
|
3340
|
+
if (onApply) {
|
|
3341
|
+
triggerOnApply(newRange);
|
|
3342
|
+
}
|
|
3343
|
+
}
|
|
3344
|
+
};
|
|
3345
|
+
(0, import_react16.useEffect)(() => {
|
|
3346
|
+
return () => {
|
|
3347
|
+
if (timeoutRef.current) {
|
|
3348
|
+
clearTimeout(timeoutRef.current);
|
|
3349
|
+
}
|
|
3350
|
+
};
|
|
3351
|
+
}, []);
|
|
3352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: PriceRangeFilter_default.priceRangeWrapper, children: [
|
|
3353
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: PriceRangeFilter_default.priceInputs, children: [
|
|
3354
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: PriceRangeFilter_default.priceInputWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3355
|
+
"input",
|
|
3356
|
+
{
|
|
3357
|
+
type: "text",
|
|
3358
|
+
inputMode: "numeric",
|
|
3359
|
+
className: PriceRangeFilter_default.priceInput,
|
|
3360
|
+
value: minInputFocused ? minInputValue : `${displayCurrency} ${value.min}`,
|
|
3361
|
+
onChange: handleMinInputChange,
|
|
3362
|
+
onFocus: handleMinInputFocus,
|
|
3363
|
+
onBlur: handleMinInputBlur,
|
|
3364
|
+
"aria-label": t("filter.min-price", "Minimum price")
|
|
3365
|
+
}
|
|
3366
|
+
) }),
|
|
3367
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: PriceRangeFilter_default.priceInputDivider, children: "\u2014" }),
|
|
3368
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: PriceRangeFilter_default.priceInputWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3369
|
+
"input",
|
|
3370
|
+
{
|
|
3371
|
+
type: "text",
|
|
3372
|
+
inputMode: "numeric",
|
|
3373
|
+
className: PriceRangeFilter_default.priceInput,
|
|
3374
|
+
value: maxInputFocused ? maxInputValue : `${displayCurrency} ${value.max}`,
|
|
3375
|
+
onChange: handleMaxInputChange,
|
|
3376
|
+
onFocus: handleMaxInputFocus,
|
|
3377
|
+
onBlur: handleMaxInputBlur,
|
|
3378
|
+
"aria-label": t("filter.max-price", "Maximum price")
|
|
3379
|
+
}
|
|
3380
|
+
) })
|
|
3381
|
+
] }),
|
|
3382
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: PriceRangeFilter_default.histogram, children: histogram.map((histValue, index) => {
|
|
3383
|
+
const height = histValue / maxHistogramValue * 100;
|
|
3384
|
+
const isActive = getBarActive(index);
|
|
3385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3386
|
+
"div",
|
|
3387
|
+
{
|
|
3388
|
+
className: `${PriceRangeFilter_default.histogramBar} ${isActive ? PriceRangeFilter_default.histogramBarActive : ""}`,
|
|
3389
|
+
style: { height: `${Math.max(height, 10)}%` }
|
|
3390
|
+
},
|
|
3391
|
+
index
|
|
3392
|
+
);
|
|
3393
|
+
}) }),
|
|
3394
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: PriceRangeFilter_default.sliderContainer, ref: sliderRef, children: [
|
|
3395
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: PriceRangeFilter_default.sliderTrack }),
|
|
3396
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3397
|
+
"div",
|
|
3398
|
+
{
|
|
3399
|
+
className: PriceRangeFilter_default.sliderActiveTrack,
|
|
3400
|
+
style: {
|
|
3401
|
+
left: `calc(12px + (100% - 24px) * ${minPercent / 100})`,
|
|
3402
|
+
width: `calc((100% - 24px) * ${(maxPercent - minPercent) / 100})`
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
),
|
|
3406
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3407
|
+
"div",
|
|
3408
|
+
{
|
|
3409
|
+
className: `${PriceRangeFilter_default.sliderHandle} ${isDragging === "min" ? PriceRangeFilter_default.sliderHandleActive : ""}`,
|
|
3410
|
+
style: { left: `calc(12px + (100% - 24px) * ${minPercent / 100})` },
|
|
3411
|
+
onMouseDown: handleMouseDown("min"),
|
|
3412
|
+
onTouchStart: handleTouchStart("min"),
|
|
3413
|
+
role: "slider",
|
|
3414
|
+
"aria-label": t("filter.min-price", "Minimum price"),
|
|
3415
|
+
"aria-valuenow": value.min,
|
|
3416
|
+
"aria-valuemin": minPrice,
|
|
3417
|
+
"aria-valuemax": value.max,
|
|
3418
|
+
tabIndex: 0
|
|
3419
|
+
}
|
|
3420
|
+
),
|
|
3421
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3422
|
+
"div",
|
|
3423
|
+
{
|
|
3424
|
+
className: `${PriceRangeFilter_default.sliderHandle} ${isDragging === "max" ? PriceRangeFilter_default.sliderHandleActive : ""}`,
|
|
3425
|
+
style: { left: `calc(12px + (100% - 24px) * ${maxPercent / 100})` },
|
|
3426
|
+
onMouseDown: handleMouseDown("max"),
|
|
3427
|
+
onTouchStart: handleTouchStart("max"),
|
|
3428
|
+
role: "slider",
|
|
3429
|
+
"aria-label": t("filter.max-price", "Maximum price"),
|
|
3430
|
+
"aria-valuenow": value.max,
|
|
3431
|
+
"aria-valuemin": value.min,
|
|
3432
|
+
"aria-valuemax": maxPrice,
|
|
3433
|
+
tabIndex: 0
|
|
2452
3434
|
}
|
|
3435
|
+
)
|
|
3436
|
+
] })
|
|
3437
|
+
] });
|
|
3438
|
+
};
|
|
3439
|
+
|
|
3440
|
+
// src/components/Filters/HotelCategoryFilter.module.css
|
|
3441
|
+
var HotelCategoryFilter_default = {};
|
|
3442
|
+
|
|
3443
|
+
// src/components/Filters/HotelCategoryFilter.tsx
|
|
3444
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3445
|
+
var CATEGORY_OPTIONS = [
|
|
3446
|
+
{ value: "5", stars: 5, label: null },
|
|
3447
|
+
{ value: "4", stars: 4, label: null },
|
|
3448
|
+
{ value: "3", stars: 3, label: null },
|
|
3449
|
+
{ value: "2", stars: 2, label: null },
|
|
3450
|
+
{ value: "swiss_lodge", stars: 0, label: "Swiss Lodge" },
|
|
3451
|
+
{ value: "not_classified", stars: 0, label: "No category" }
|
|
3452
|
+
];
|
|
3453
|
+
var HotelCategoryFilter = ({
|
|
3454
|
+
selected,
|
|
3455
|
+
counts = {},
|
|
3456
|
+
onChange,
|
|
3457
|
+
className = ""
|
|
3458
|
+
}) => {
|
|
3459
|
+
const { t } = useUIContext();
|
|
3460
|
+
const handleToggle = (value) => {
|
|
3461
|
+
if (selected.includes(value)) {
|
|
3462
|
+
onChange(selected.filter((v) => v !== value));
|
|
3463
|
+
} else {
|
|
3464
|
+
onChange([...selected, value]);
|
|
3465
|
+
}
|
|
3466
|
+
};
|
|
3467
|
+
const getLabel = (option) => {
|
|
3468
|
+
if (option.stars > 0) return null;
|
|
3469
|
+
if (option.value === "swiss_lodge") return t("filter.swiss-lodge", "Swiss Lodge");
|
|
3470
|
+
if (option.value === "not_classified") return t("filter.no-category", "No category");
|
|
3471
|
+
return option.label;
|
|
3472
|
+
};
|
|
3473
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className, children: [
|
|
3474
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: HotelCategoryFilter_default.filterList, children: CATEGORY_OPTIONS.map((option) => {
|
|
3475
|
+
const count = counts[option.value];
|
|
3476
|
+
const isDisabled = count === 0 && !selected.includes(option.value);
|
|
3477
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3478
|
+
FilterCheckboxItem,
|
|
3479
|
+
{
|
|
3480
|
+
id: `category-${option.value}`,
|
|
3481
|
+
label: option.stars > 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: HotelCategoryFilter_default.starsContainer, children: Array.from({ length: option.stars }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("svg", { className: HotelCategoryFilter_default.starIcon, viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("path", { d: "M12 0L14.6942 8.2918H23.4127L16.3593 13.4164L19.0534 21.7082L12 16.5836L4.94658 21.7082L7.64074 13.4164L0.587322 8.2918H9.30583L12 0Z" }) }, i)) }) : getLabel(option),
|
|
3482
|
+
count,
|
|
3483
|
+
checked: selected.includes(option.value),
|
|
3484
|
+
disabled: isDisabled,
|
|
3485
|
+
onChange: () => handleToggle(option.value),
|
|
3486
|
+
trackName: `filter-category-${option.value}`
|
|
3487
|
+
},
|
|
3488
|
+
option.value
|
|
3489
|
+
);
|
|
3490
|
+
}) }),
|
|
3491
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: HotelCategoryFilter_default.footer, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: HotelCategoryFilter_default.footerText, children: t("filter.hotellerie-suisse", "Classification HotellerieSuisse") }) })
|
|
3492
|
+
] });
|
|
3493
|
+
};
|
|
3494
|
+
|
|
3495
|
+
// src/components/Filters/ReviewsFilter.module.css
|
|
3496
|
+
var ReviewsFilter_default = {};
|
|
3497
|
+
|
|
3498
|
+
// src/components/Filters/ReviewsFilter.tsx
|
|
3499
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3500
|
+
var REVIEW_OPTIONS = [
|
|
3501
|
+
{ value: "excellent", labelKey: "rating-excellent", range: "(4.4+)" },
|
|
3502
|
+
{ value: "very_good", labelKey: "rating-very-good", range: "(4.1 \u2013 4.3)" },
|
|
3503
|
+
{ value: "good", labelKey: "rating-good", range: "(3.8 \u2013 4.0)" },
|
|
3504
|
+
{ value: "fair", labelKey: "rating-fair", range: "(3.5 \u2013 3.7)" },
|
|
3505
|
+
{ value: "no_rating", labelKey: "rating-none", range: "" }
|
|
3506
|
+
];
|
|
3507
|
+
var ReviewsFilter = ({
|
|
3508
|
+
selected,
|
|
3509
|
+
counts = {},
|
|
3510
|
+
onChange,
|
|
3511
|
+
className = "",
|
|
3512
|
+
isPlaceSearchActive = false
|
|
3513
|
+
}) => {
|
|
3514
|
+
const { t } = useUIContext();
|
|
3515
|
+
const handleToggle = (value) => {
|
|
3516
|
+
if (selected.includes(value)) {
|
|
3517
|
+
onChange(selected.filter((v) => v !== value));
|
|
3518
|
+
} else {
|
|
3519
|
+
onChange([...selected, value]);
|
|
3520
|
+
}
|
|
3521
|
+
};
|
|
3522
|
+
const getRatingLabel = (labelKey) => {
|
|
3523
|
+
const labelMap = {
|
|
3524
|
+
"rating-excellent": t("label.rating-excellent", "Excellent"),
|
|
3525
|
+
"rating-very-good": t("label.rating-very-good", "Very Good"),
|
|
3526
|
+
"rating-good": t("label.rating-good", "Good"),
|
|
3527
|
+
"rating-fair": t("label.rating-fair", "Fair"),
|
|
3528
|
+
"rating-none": t("label.rating-none", "No rating")
|
|
3529
|
+
};
|
|
3530
|
+
return labelMap[labelKey] ?? labelKey;
|
|
3531
|
+
};
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className, children: [
|
|
3533
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: ReviewsFilter_default.filterList, children: REVIEW_OPTIONS.map((option) => {
|
|
3534
|
+
const count = counts[option.value];
|
|
3535
|
+
const isDisabled = !isPlaceSearchActive && count === 0 && !selected.includes(option.value);
|
|
3536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3537
|
+
FilterCheckboxItem,
|
|
3538
|
+
{
|
|
3539
|
+
id: `review-${option.value}`,
|
|
3540
|
+
label: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
3541
|
+
getRatingLabel(option.labelKey),
|
|
3542
|
+
option.range && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: ReviewsFilter_default.filterRange, children: [
|
|
3543
|
+
" ",
|
|
3544
|
+
option.range
|
|
3545
|
+
] })
|
|
3546
|
+
] }),
|
|
3547
|
+
count,
|
|
3548
|
+
checked: selected.includes(option.value),
|
|
3549
|
+
disabled: isDisabled,
|
|
3550
|
+
onChange: () => handleToggle(option.value),
|
|
3551
|
+
trackName: `filter-review-${option.value}`
|
|
3552
|
+
},
|
|
3553
|
+
option.value
|
|
3554
|
+
);
|
|
3555
|
+
}) }),
|
|
3556
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: ReviewsFilter_default.footer, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: ReviewsFilter_default.footerText, children: t("filter.trustyou", "Reviews from TrustYou\xAE") }) })
|
|
3557
|
+
] });
|
|
3558
|
+
};
|
|
3559
|
+
|
|
3560
|
+
// src/components/Filters/ExperienceFilter.tsx
|
|
3561
|
+
var import_react17 = require("react");
|
|
3562
|
+
|
|
3563
|
+
// src/components/Filters/ExperienceFilter.module.css
|
|
3564
|
+
var ExperienceFilter_default = {};
|
|
3565
|
+
|
|
3566
|
+
// src/components/Filters/ExperienceFilter.tsx
|
|
3567
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3568
|
+
var ExperienceFilter = ({
|
|
3569
|
+
selected,
|
|
3570
|
+
themes = [],
|
|
3571
|
+
onChange,
|
|
3572
|
+
className = ""
|
|
3573
|
+
}) => {
|
|
3574
|
+
const { t } = useUIContext();
|
|
3575
|
+
const [expanded, setExpanded] = (0, import_react17.useState)(false);
|
|
3576
|
+
const visibleThemes = expanded ? themes : themes.slice(0, 5);
|
|
3577
|
+
const hasMoreThemes = themes.length > 5;
|
|
3578
|
+
const handleToggle = (value) => {
|
|
3579
|
+
if (selected.includes(value)) {
|
|
3580
|
+
onChange(selected.filter((v) => v !== value));
|
|
3581
|
+
} else {
|
|
3582
|
+
onChange([...selected, value]);
|
|
3583
|
+
}
|
|
3584
|
+
};
|
|
3585
|
+
if (themes.length === 0) {
|
|
3586
|
+
return null;
|
|
3587
|
+
}
|
|
3588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: `${ExperienceFilter_default.filterList} ${className}`, children: [
|
|
3589
|
+
visibleThemes.map((theme) => {
|
|
3590
|
+
const themeIdStr = String(theme.id);
|
|
3591
|
+
const isDisabled = theme.count === 0 && !selected.includes(themeIdStr);
|
|
3592
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
3593
|
+
FilterCheckboxItem,
|
|
3594
|
+
{
|
|
3595
|
+
id: `experience-${theme.id}`,
|
|
3596
|
+
label: theme.name,
|
|
3597
|
+
count: theme.count > 0 ? theme.count : void 0,
|
|
3598
|
+
checked: selected.includes(themeIdStr),
|
|
3599
|
+
disabled: isDisabled,
|
|
3600
|
+
onChange: () => handleToggle(themeIdStr),
|
|
3601
|
+
trackName: `filter-experience-${theme.id}`
|
|
3602
|
+
},
|
|
3603
|
+
theme.id
|
|
3604
|
+
);
|
|
3605
|
+
}),
|
|
3606
|
+
hasMoreThemes && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
|
|
3607
|
+
"button",
|
|
3608
|
+
{
|
|
3609
|
+
type: "button",
|
|
3610
|
+
className: ExperienceFilter_default.showMoreBtn,
|
|
3611
|
+
onClick: () => setExpanded(!expanded),
|
|
3612
|
+
children: [
|
|
3613
|
+
expanded ? t("filter.show-less", "Show less") : t("filter.show-all", "Show all"),
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: `${ExperienceFilter_default.arrowIcon} ${expanded ? ExperienceFilter_default.arrowUp : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("path", { d: "M9.36927 13.9061C9.71908 14.2535 10.2847 14.2535 10.6308 13.9061L16.4069 8.1803C16.7567 7.83285 16.7567 7.27102 16.4069 6.92727C16.0571 6.58352 15.4915 6.57983 15.1454 6.92727L10.0019 12.0247L4.85845 6.92727C4.50864 6.57983 3.94299 6.57983 3.5969 6.92727C3.25081 7.27472 3.24709 7.83655 3.5969 8.1803L9.37299 13.9061H9.36927Z", fill: "currentColor" }) }) })
|
|
3615
|
+
]
|
|
2453
3616
|
}
|
|
2454
3617
|
)
|
|
2455
3618
|
] });
|
|
2456
3619
|
};
|
|
2457
3620
|
|
|
3621
|
+
// src/components/Filters/RegionsFilter.tsx
|
|
3622
|
+
var import_react18 = require("react");
|
|
3623
|
+
|
|
3624
|
+
// src/components/Filters/RegionsFilter.module.css
|
|
3625
|
+
var RegionsFilter_default = {};
|
|
3626
|
+
|
|
3627
|
+
// src/components/Filters/RegionsFilter.tsx
|
|
3628
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3629
|
+
var RegionsFilter = ({
|
|
3630
|
+
regions,
|
|
3631
|
+
selected,
|
|
3632
|
+
onChange,
|
|
3633
|
+
className = "",
|
|
3634
|
+
isPlaceSearchActive = false
|
|
3635
|
+
}) => {
|
|
3636
|
+
const { t } = useUIContext();
|
|
3637
|
+
const [expandedCountries, setExpandedCountries] = (0, import_react18.useState)(/* @__PURE__ */ new Set(["country_215"]));
|
|
3638
|
+
const hasInitializedRef = (0, import_react18.useRef)(false);
|
|
3639
|
+
(0, import_react18.useEffect)(() => {
|
|
3640
|
+
if (hasInitializedRef.current) return;
|
|
3641
|
+
if (regions.length === 0 || selected.length === 0) return;
|
|
3642
|
+
const countriesWithSelectedRegions = /* @__PURE__ */ new Set();
|
|
3643
|
+
regions.forEach((region) => {
|
|
3644
|
+
if (region.subRegions?.some((sub) => selected.includes(sub.value))) {
|
|
3645
|
+
countriesWithSelectedRegions.add(region.value);
|
|
3646
|
+
}
|
|
3647
|
+
});
|
|
3648
|
+
if (countriesWithSelectedRegions.size > 0) {
|
|
3649
|
+
setExpandedCountries(countriesWithSelectedRegions);
|
|
3650
|
+
hasInitializedRef.current = true;
|
|
3651
|
+
}
|
|
3652
|
+
}, [regions, selected]);
|
|
3653
|
+
const handleCountryToggle = (countryValue) => {
|
|
3654
|
+
setExpandedCountries((prev) => {
|
|
3655
|
+
const next = new Set(prev);
|
|
3656
|
+
if (next.has(countryValue)) {
|
|
3657
|
+
next.delete(countryValue);
|
|
3658
|
+
} else {
|
|
3659
|
+
next.add(countryValue);
|
|
3660
|
+
}
|
|
3661
|
+
return next;
|
|
3662
|
+
});
|
|
3663
|
+
};
|
|
3664
|
+
const handleRegionToggle = (regionValue) => {
|
|
3665
|
+
if (selected.includes(regionValue)) {
|
|
3666
|
+
onChange(selected.filter((r) => r !== regionValue));
|
|
3667
|
+
} else {
|
|
3668
|
+
onChange([...selected, regionValue]);
|
|
3669
|
+
}
|
|
3670
|
+
};
|
|
3671
|
+
if (regions.length === 0) {
|
|
3672
|
+
return null;
|
|
3673
|
+
}
|
|
3674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: `${RegionsFilter_default.filterList} ${className}`, children: regions.map((region) => {
|
|
3675
|
+
const hasSubRegions = region.subRegions && region.subRegions.length > 0;
|
|
3676
|
+
const isExpanded = expandedCountries.has(region.value);
|
|
3677
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: RegionsFilter_default.regionItem, children: [
|
|
3678
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
3679
|
+
"button",
|
|
3680
|
+
{
|
|
3681
|
+
type: "button",
|
|
3682
|
+
className: `${RegionsFilter_default.countryRow} ${isExpanded ? RegionsFilter_default.countryRowExpanded : ""}`,
|
|
3683
|
+
onClick: () => handleCountryToggle(region.value),
|
|
3684
|
+
"aria-expanded": isExpanded,
|
|
3685
|
+
disabled: isPlaceSearchActive,
|
|
3686
|
+
children: [
|
|
3687
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: RegionsFilter_default.countryInfo, children: [
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: RegionsFilter_default.countryName, children: region.label }),
|
|
3689
|
+
region.count !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: RegionsFilter_default.countBadge, children: region.count })
|
|
3690
|
+
] }),
|
|
3691
|
+
hasSubRegions && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3692
|
+
"svg",
|
|
3693
|
+
{
|
|
3694
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3695
|
+
width: "20",
|
|
3696
|
+
height: "20",
|
|
3697
|
+
viewBox: "0 0 20 20",
|
|
3698
|
+
fill: "none",
|
|
3699
|
+
className: `${RegionsFilter_default.chevron} ${isExpanded ? RegionsFilter_default.chevronExpanded : ""}`,
|
|
3700
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("path", { d: "M9.36927 13.9061C9.71908 14.2535 10.2847 14.2535 10.6308 13.9061L16.4069 8.18027C16.7567 7.83283 16.7567 7.271 16.4069 6.92725C16.0571 6.5835 15.4915 6.5798 15.1454 6.92725L10.0019 12.0247L4.85845 6.92725C4.50864 6.5798 3.94299 6.5798 3.5969 6.92725C3.25081 7.2747 3.24709 7.83652 3.5969 8.18027L9.37299 13.9061H9.36927Z", fill: "#6B7280" })
|
|
3701
|
+
}
|
|
3702
|
+
)
|
|
3703
|
+
]
|
|
3704
|
+
}
|
|
3705
|
+
),
|
|
3706
|
+
hasSubRegions && isExpanded && (() => {
|
|
3707
|
+
const hasSelectableRegions = region.subRegions.some(
|
|
3708
|
+
(sr) => sr.count === void 0 || sr.count > 0
|
|
3709
|
+
);
|
|
3710
|
+
const subValues = region.subRegions.map((sr) => sr.value);
|
|
3711
|
+
const hasSelectedRegions = subValues.some((v) => selected.includes(v));
|
|
3712
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: RegionsFilter_default.mobileSelectAllActions, children: [
|
|
3713
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3714
|
+
"button",
|
|
3715
|
+
{
|
|
3716
|
+
type: "button",
|
|
3717
|
+
className: RegionsFilter_default.selectAllBtn,
|
|
3718
|
+
disabled: !hasSelectableRegions,
|
|
3719
|
+
onClick: () => {
|
|
3720
|
+
const selectableSubValues = region.subRegions.filter((sr) => sr.count === void 0 || sr.count > 0).map((sr) => sr.value);
|
|
3721
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...selected, ...selectableSubValues]));
|
|
3722
|
+
onChange(merged);
|
|
3723
|
+
},
|
|
3724
|
+
children: t("filter.select-all", "Select all")
|
|
3725
|
+
}
|
|
3726
|
+
),
|
|
3727
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3728
|
+
"button",
|
|
3729
|
+
{
|
|
3730
|
+
type: "button",
|
|
3731
|
+
className: RegionsFilter_default.resetAllBtn,
|
|
3732
|
+
disabled: !hasSelectedRegions,
|
|
3733
|
+
onClick: () => {
|
|
3734
|
+
onChange(selected.filter((v) => !subValues.includes(v)));
|
|
3735
|
+
},
|
|
3736
|
+
children: t("filter.reset", "Reset")
|
|
3737
|
+
}
|
|
3738
|
+
)
|
|
3739
|
+
] });
|
|
3740
|
+
})(),
|
|
3741
|
+
hasSubRegions && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: RegionsFilter_default.subRegions, children: region.subRegions.map((subRegion) => {
|
|
3742
|
+
const isDisabled = subRegion.count === 0 && !selected.includes(subRegion.value) || isPlaceSearchActive && !selected.includes(subRegion.value);
|
|
3743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
3744
|
+
FilterCheckboxItem,
|
|
3745
|
+
{
|
|
3746
|
+
id: `region-${subRegion.value}`,
|
|
3747
|
+
label: subRegion.label,
|
|
3748
|
+
count: subRegion.count,
|
|
3749
|
+
checked: selected.includes(subRegion.value),
|
|
3750
|
+
disabled: isDisabled,
|
|
3751
|
+
onChange: () => handleRegionToggle(subRegion.value),
|
|
3752
|
+
trackName: `filter-region-${subRegion.value}`
|
|
3753
|
+
},
|
|
3754
|
+
subRegion.value
|
|
3755
|
+
);
|
|
3756
|
+
}) })
|
|
3757
|
+
] }, region.value);
|
|
3758
|
+
}) });
|
|
3759
|
+
};
|
|
3760
|
+
|
|
3761
|
+
// src/components/Filters/CheckboxFilter.module.css
|
|
3762
|
+
var CheckboxFilter_default = {};
|
|
3763
|
+
|
|
3764
|
+
// src/components/Filters/CheckboxFilter.tsx
|
|
3765
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
3766
|
+
var CheckboxFilter = ({
|
|
3767
|
+
selected,
|
|
3768
|
+
counts = {},
|
|
3769
|
+
options = [],
|
|
3770
|
+
onChange,
|
|
3771
|
+
className = "",
|
|
3772
|
+
trackPrefix = "filter"
|
|
3773
|
+
}) => {
|
|
3774
|
+
const handleToggle = (value) => {
|
|
3775
|
+
if (selected.includes(value)) {
|
|
3776
|
+
onChange(selected.filter((v) => v !== value));
|
|
3777
|
+
} else {
|
|
3778
|
+
onChange([...selected, value]);
|
|
3779
|
+
}
|
|
3780
|
+
};
|
|
3781
|
+
if (options.length === 0) {
|
|
3782
|
+
return null;
|
|
3783
|
+
}
|
|
3784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: `${CheckboxFilter_default.filterList} ${className}`, children: options.map((option) => {
|
|
3785
|
+
const count = counts[option.key];
|
|
3786
|
+
const isDisabled = count === 0 && !selected.includes(option.key);
|
|
3787
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
3788
|
+
FilterCheckboxItem,
|
|
3789
|
+
{
|
|
3790
|
+
id: `${trackPrefix}-${option.key}`,
|
|
3791
|
+
label: option.name,
|
|
3792
|
+
count,
|
|
3793
|
+
checked: selected.includes(option.key),
|
|
3794
|
+
disabled: isDisabled,
|
|
3795
|
+
onChange: () => handleToggle(option.key),
|
|
3796
|
+
trackName: `filter-${trackPrefix}-${option.key}`
|
|
3797
|
+
},
|
|
3798
|
+
option.key
|
|
3799
|
+
);
|
|
3800
|
+
}) });
|
|
3801
|
+
};
|
|
3802
|
+
var MealsFilter = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CheckboxFilter, { ...props, trackPrefix: "meals" });
|
|
3803
|
+
var TransportFilter = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CheckboxFilter, { ...props, trackPrefix: "transport" });
|
|
3804
|
+
var WellnessFilter = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CheckboxFilter, { ...props, trackPrefix: "wellness" });
|
|
3805
|
+
|
|
3806
|
+
// src/components/Filters/SelectedFiltersRow.module.css
|
|
3807
|
+
var SelectedFiltersRow_default = {};
|
|
3808
|
+
|
|
3809
|
+
// src/components/Filters/SelectedFiltersRow.tsx
|
|
3810
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3811
|
+
var SelectedFiltersRow = ({
|
|
3812
|
+
filters,
|
|
3813
|
+
onRemove,
|
|
3814
|
+
onClearAll,
|
|
3815
|
+
className = ""
|
|
3816
|
+
}) => {
|
|
3817
|
+
const { t } = useUIContext();
|
|
3818
|
+
if (filters.length === 0) {
|
|
3819
|
+
return null;
|
|
3820
|
+
}
|
|
3821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `${SelectedFiltersRow_default.container} ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: SelectedFiltersRow_default.chipsWrapper, children: [
|
|
3822
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: SelectedFiltersRow_default.selectedText, children: [
|
|
3823
|
+
t("filter.selected", "Selected:"),
|
|
3824
|
+
" "
|
|
3825
|
+
] }),
|
|
3826
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: SelectedFiltersRow_default.chips, children: [
|
|
3827
|
+
filters.map((filter) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3828
|
+
Chip,
|
|
3829
|
+
{
|
|
3830
|
+
label: filter.label,
|
|
3831
|
+
size: "small",
|
|
3832
|
+
state: "idle",
|
|
3833
|
+
removable: true,
|
|
3834
|
+
onRemove: () => onRemove(filter)
|
|
3835
|
+
},
|
|
3836
|
+
filter.id
|
|
3837
|
+
)),
|
|
3838
|
+
onClearAll && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3839
|
+
Button,
|
|
3840
|
+
{
|
|
3841
|
+
variant: "link",
|
|
3842
|
+
className: SelectedFiltersRow_default.clearAllBtn,
|
|
3843
|
+
onClick: onClearAll,
|
|
3844
|
+
children: t("filter.clear-all", "Clear all")
|
|
3845
|
+
}
|
|
3846
|
+
)
|
|
3847
|
+
] })
|
|
3848
|
+
] }) });
|
|
3849
|
+
};
|
|
3850
|
+
|
|
2458
3851
|
// src/components/icons/HeartIcon.tsx
|
|
2459
|
-
var
|
|
2460
|
-
var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__ */ (0,
|
|
3852
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3853
|
+
var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
2461
3854
|
"svg",
|
|
2462
3855
|
{
|
|
2463
3856
|
width: size,
|
|
@@ -2469,14 +3862,14 @@ var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__
|
|
|
2469
3862
|
strokeWidth: 2,
|
|
2470
3863
|
strokeLinecap: "round",
|
|
2471
3864
|
strokeLinejoin: "round",
|
|
2472
|
-
children: /* @__PURE__ */ (0,
|
|
3865
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { d: "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" })
|
|
2473
3866
|
}
|
|
2474
3867
|
);
|
|
2475
3868
|
HeartIcon3.displayName = "HeartIcon";
|
|
2476
3869
|
|
|
2477
3870
|
// src/components/icons/StarIcon.tsx
|
|
2478
|
-
var
|
|
2479
|
-
var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */ (0,
|
|
3871
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3872
|
+
var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
2480
3873
|
"svg",
|
|
2481
3874
|
{
|
|
2482
3875
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2486,22 +3879,22 @@ var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */
|
|
|
2486
3879
|
fill: "none",
|
|
2487
3880
|
className,
|
|
2488
3881
|
children: [
|
|
2489
|
-
/* @__PURE__ */ (0,
|
|
3882
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("g", { clipPath: "url(#clip0_star_icon)", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
2490
3883
|
"path",
|
|
2491
3884
|
{
|
|
2492
3885
|
d: "M4.80018 0.366577C4.93104 0.366577 5.05173 0.440968 5.11135 0.557659L6.18011 2.66102L8.50521 3.03152C8.63462 3.05194 8.74222 3.14383 8.78294 3.26927C8.82365 3.39472 8.79021 3.53183 8.6986 3.62518L7.03366 5.29533L7.40155 7.6277C7.42191 7.75752 7.3681 7.88879 7.26195 7.9661C7.15581 8.04341 7.01476 8.05508 6.89843 7.99528L4.80018 6.92463L2.70192 7.99528C2.58559 8.05508 2.44454 8.04341 2.33839 7.9661C2.23225 7.88879 2.17844 7.75898 2.1988 7.6277L2.56523 5.29533L0.901751 3.62518C0.808689 3.53183 0.776699 3.39472 0.817413 3.26927C0.858128 3.14383 0.964277 3.05194 1.09515 3.03152L3.42024 2.66102L4.49045 0.557659C4.55007 0.440968 4.67076 0.366577 4.80163 0.366577H4.80018Z",
|
|
2493
3886
|
fill: filled ? "#1F2937" : "#D1D5DB"
|
|
2494
3887
|
}
|
|
2495
3888
|
) }),
|
|
2496
|
-
/* @__PURE__ */ (0,
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("clipPath", { id: "clip0_star_icon", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("rect", { width: "8", height: "8", fill: "white", transform: "translate(0.800049 0.199951)" }) }) })
|
|
2497
3890
|
]
|
|
2498
3891
|
}
|
|
2499
3892
|
);
|
|
2500
3893
|
StarIcon4.displayName = "StarIcon";
|
|
2501
3894
|
|
|
2502
3895
|
// src/components/icons/ChevronLeftIcon.tsx
|
|
2503
|
-
var
|
|
2504
|
-
var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0,
|
|
3896
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3897
|
+
var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
2505
3898
|
"svg",
|
|
2506
3899
|
{
|
|
2507
3900
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2514,14 +3907,14 @@ var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, imp
|
|
|
2514
3907
|
strokeLinecap: "round",
|
|
2515
3908
|
strokeLinejoin: "round",
|
|
2516
3909
|
className,
|
|
2517
|
-
children: /* @__PURE__ */ (0,
|
|
3910
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("polyline", { points: "15 18 9 12 15 6" })
|
|
2518
3911
|
}
|
|
2519
3912
|
);
|
|
2520
3913
|
ChevronLeftIcon.displayName = "ChevronLeftIcon";
|
|
2521
3914
|
|
|
2522
3915
|
// src/components/icons/ChevronRightIcon.tsx
|
|
2523
|
-
var
|
|
2524
|
-
var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0,
|
|
3916
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3917
|
+
var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
2525
3918
|
"svg",
|
|
2526
3919
|
{
|
|
2527
3920
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2534,14 +3927,14 @@ var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, i
|
|
|
2534
3927
|
strokeLinecap: "round",
|
|
2535
3928
|
strokeLinejoin: "round",
|
|
2536
3929
|
className,
|
|
2537
|
-
children: /* @__PURE__ */ (0,
|
|
3930
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("polyline", { points: "9 18 15 12 9 6" })
|
|
2538
3931
|
}
|
|
2539
3932
|
);
|
|
2540
3933
|
ChevronRightIcon2.displayName = "ChevronRightIcon";
|
|
2541
3934
|
|
|
2542
3935
|
// src/components/icons/PinIcon.tsx
|
|
2543
|
-
var
|
|
2544
|
-
var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0,
|
|
3936
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3937
|
+
var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
2545
3938
|
"svg",
|
|
2546
3939
|
{
|
|
2547
3940
|
xmlns: "http://www.w3.org/2000/svg",
|
|
@@ -2551,7 +3944,7 @@ var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx
|
|
|
2551
3944
|
fill: "none",
|
|
2552
3945
|
className,
|
|
2553
3946
|
children: [
|
|
2554
|
-
/* @__PURE__ */ (0,
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
2555
3948
|
"path",
|
|
2556
3949
|
{
|
|
2557
3950
|
fillRule: "evenodd",
|
|
@@ -2560,7 +3953,7 @@ var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx
|
|
|
2560
3953
|
fill: "currentColor"
|
|
2561
3954
|
}
|
|
2562
3955
|
),
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
3956
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
2564
3957
|
"path",
|
|
2565
3958
|
{
|
|
2566
3959
|
fillRule: "evenodd",
|
|
@@ -2609,36 +4002,51 @@ var calculateDiscount = (originalPrice, discountedPrice) => {
|
|
|
2609
4002
|
Benefits,
|
|
2610
4003
|
Block,
|
|
2611
4004
|
Button,
|
|
4005
|
+
CATEGORY_OPTIONS,
|
|
2612
4006
|
Card,
|
|
2613
4007
|
Checkbox,
|
|
4008
|
+
CheckboxFilter,
|
|
2614
4009
|
ChevronLeftIcon,
|
|
2615
4010
|
ChevronRightIcon,
|
|
2616
4011
|
Chip,
|
|
4012
|
+
CollapsibleFilterSection,
|
|
2617
4013
|
DateSelector,
|
|
2618
4014
|
Divider,
|
|
2619
4015
|
Dropdown,
|
|
2620
4016
|
DualCalendar,
|
|
4017
|
+
ExperienceFilter,
|
|
2621
4018
|
FAQ,
|
|
4019
|
+
FilterCheckboxItem,
|
|
2622
4020
|
GuestContent,
|
|
2623
4021
|
HeartIcon,
|
|
2624
4022
|
HotelCard,
|
|
2625
4023
|
HotelCardContent,
|
|
2626
4024
|
HotelCardImage,
|
|
2627
4025
|
HotelCardUIProvider,
|
|
4026
|
+
HotelCategoryFilter,
|
|
2628
4027
|
Input,
|
|
4028
|
+
MealsFilter,
|
|
2629
4029
|
Modal,
|
|
2630
4030
|
Pin,
|
|
2631
4031
|
PinIcon,
|
|
4032
|
+
PriceRangeFilter,
|
|
4033
|
+
REVIEW_OPTIONS,
|
|
2632
4034
|
RadioButton,
|
|
2633
4035
|
Rating,
|
|
4036
|
+
RegionsFilter,
|
|
2634
4037
|
ReviewCard,
|
|
4038
|
+
ReviewsFilter,
|
|
2635
4039
|
SectionHeader,
|
|
4040
|
+
SelectedFiltersRow,
|
|
2636
4041
|
StarIcon,
|
|
4042
|
+
TransportFilter,
|
|
4043
|
+
WellnessFilter,
|
|
2637
4044
|
WhenContent,
|
|
2638
4045
|
calculateDiscount,
|
|
2639
4046
|
formatDate,
|
|
2640
4047
|
formatDateRange,
|
|
2641
4048
|
formatPrice,
|
|
4049
|
+
translations,
|
|
2642
4050
|
useDebounce,
|
|
2643
4051
|
useResponsive,
|
|
2644
4052
|
useTranslation,
|