@hotelcard/ui 0.0.15 → 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.
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,31 +34,45 @@ __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,
@@ -2973,9 +2997,860 @@ var HotelCard = ({
2973
2997
  ] });
2974
2998
  };
2975
2999
 
2976
- // src/components/icons/HeartIcon.tsx
3000
+ // src/components/Filters/FilterCheckboxItem.module.css
3001
+ var FilterCheckboxItem_default = {};
3002
+
3003
+ // src/components/Filters/FilterCheckboxItem.tsx
2977
3004
  var import_jsx_runtime26 = require("react/jsx-runtime");
2978
- var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
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
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
+ ]
3616
+ }
3617
+ )
3618
+ ] });
3619
+ };
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
+
3851
+ // src/components/icons/HeartIcon.tsx
3852
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3853
+ var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2979
3854
  "svg",
2980
3855
  {
2981
3856
  width: size,
@@ -2987,14 +3862,14 @@ var HeartIcon3 = ({ filled = false, className = "", size = 24 }) => /* @__PURE__
2987
3862
  strokeWidth: 2,
2988
3863
  strokeLinecap: "round",
2989
3864
  strokeLinejoin: "round",
2990
- children: /* @__PURE__ */ (0, import_jsx_runtime26.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" })
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" })
2991
3866
  }
2992
3867
  );
2993
3868
  HeartIcon3.displayName = "HeartIcon";
2994
3869
 
2995
3870
  // src/components/icons/StarIcon.tsx
2996
- var import_jsx_runtime27 = require("react/jsx-runtime");
2997
- var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
3871
+ var import_jsx_runtime36 = require("react/jsx-runtime");
3872
+ var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2998
3873
  "svg",
2999
3874
  {
3000
3875
  xmlns: "http://www.w3.org/2000/svg",
@@ -3004,22 +3879,22 @@ var StarIcon4 = ({ filled = true, className = "", size = 9 }) => /* @__PURE__ */
3004
3879
  fill: "none",
3005
3880
  className,
3006
3881
  children: [
3007
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("g", { clipPath: "url(#clip0_star_icon)", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3882
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("g", { clipPath: "url(#clip0_star_icon)", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
3008
3883
  "path",
3009
3884
  {
3010
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",
3011
3886
  fill: filled ? "#1F2937" : "#D1D5DB"
3012
3887
  }
3013
3888
  ) }),
3014
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("clipPath", { id: "clip0_star_icon", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { width: "8", height: "8", fill: "white", transform: "translate(0.800049 0.199951)" }) }) })
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)" }) }) })
3015
3890
  ]
3016
3891
  }
3017
3892
  );
3018
3893
  StarIcon4.displayName = "StarIcon";
3019
3894
 
3020
3895
  // src/components/icons/ChevronLeftIcon.tsx
3021
- var import_jsx_runtime28 = require("react/jsx-runtime");
3022
- var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3896
+ var import_jsx_runtime37 = require("react/jsx-runtime");
3897
+ var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3023
3898
  "svg",
3024
3899
  {
3025
3900
  xmlns: "http://www.w3.org/2000/svg",
@@ -3032,14 +3907,14 @@ var ChevronLeftIcon = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, imp
3032
3907
  strokeLinecap: "round",
3033
3908
  strokeLinejoin: "round",
3034
3909
  className,
3035
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("polyline", { points: "15 18 9 12 15 6" })
3910
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("polyline", { points: "15 18 9 12 15 6" })
3036
3911
  }
3037
3912
  );
3038
3913
  ChevronLeftIcon.displayName = "ChevronLeftIcon";
3039
3914
 
3040
3915
  // src/components/icons/ChevronRightIcon.tsx
3041
- var import_jsx_runtime29 = require("react/jsx-runtime");
3042
- var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
3916
+ var import_jsx_runtime38 = require("react/jsx-runtime");
3917
+ var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3043
3918
  "svg",
3044
3919
  {
3045
3920
  xmlns: "http://www.w3.org/2000/svg",
@@ -3052,14 +3927,14 @@ var ChevronRightIcon2 = ({ className = "", size = 20 }) => /* @__PURE__ */ (0, i
3052
3927
  strokeLinecap: "round",
3053
3928
  strokeLinejoin: "round",
3054
3929
  className,
3055
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("polyline", { points: "9 18 15 12 9 6" })
3930
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("polyline", { points: "9 18 15 12 9 6" })
3056
3931
  }
3057
3932
  );
3058
3933
  ChevronRightIcon2.displayName = "ChevronRightIcon";
3059
3934
 
3060
3935
  // src/components/icons/PinIcon.tsx
3061
- var import_jsx_runtime30 = require("react/jsx-runtime");
3062
- var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3936
+ var import_jsx_runtime39 = require("react/jsx-runtime");
3937
+ var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
3063
3938
  "svg",
3064
3939
  {
3065
3940
  xmlns: "http://www.w3.org/2000/svg",
@@ -3069,7 +3944,7 @@ var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx
3069
3944
  fill: "none",
3070
3945
  className,
3071
3946
  children: [
3072
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3947
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3073
3948
  "path",
3074
3949
  {
3075
3950
  fillRule: "evenodd",
@@ -3078,7 +3953,7 @@ var PinIcon2 = ({ className = "", size = 16 }) => /* @__PURE__ */ (0, import_jsx
3078
3953
  fill: "currentColor"
3079
3954
  }
3080
3955
  ),
3081
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3956
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
3082
3957
  "path",
3083
3958
  {
3084
3959
  fillRule: "evenodd",
@@ -3127,31 +4002,45 @@ var calculateDiscount = (originalPrice, discountedPrice) => {
3127
4002
  Benefits,
3128
4003
  Block,
3129
4004
  Button,
4005
+ CATEGORY_OPTIONS,
3130
4006
  Card,
3131
4007
  Checkbox,
4008
+ CheckboxFilter,
3132
4009
  ChevronLeftIcon,
3133
4010
  ChevronRightIcon,
3134
4011
  Chip,
4012
+ CollapsibleFilterSection,
3135
4013
  DateSelector,
3136
4014
  Divider,
3137
4015
  Dropdown,
3138
4016
  DualCalendar,
4017
+ ExperienceFilter,
3139
4018
  FAQ,
4019
+ FilterCheckboxItem,
3140
4020
  GuestContent,
3141
4021
  HeartIcon,
3142
4022
  HotelCard,
3143
4023
  HotelCardContent,
3144
4024
  HotelCardImage,
3145
4025
  HotelCardUIProvider,
4026
+ HotelCategoryFilter,
3146
4027
  Input,
4028
+ MealsFilter,
3147
4029
  Modal,
3148
4030
  Pin,
3149
4031
  PinIcon,
4032
+ PriceRangeFilter,
4033
+ REVIEW_OPTIONS,
3150
4034
  RadioButton,
3151
4035
  Rating,
4036
+ RegionsFilter,
3152
4037
  ReviewCard,
4038
+ ReviewsFilter,
3153
4039
  SectionHeader,
4040
+ SelectedFiltersRow,
3154
4041
  StarIcon,
4042
+ TransportFilter,
4043
+ WellnessFilter,
3155
4044
  WhenContent,
3156
4045
  calculateDiscount,
3157
4046
  formatDate,