@qite/tide-booking-component 1.4.39 → 1.4.40
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/build/build-cjs/booking-wizard/types.d.ts +1 -0
- package/build/build-cjs/index.js +7173 -1533
- package/build/build-cjs/qsm/store/qsm-slice.d.ts +4 -2
- package/build/build-cjs/qsm/types.d.ts +2 -1
- package/build/build-cjs/search-results/components/filters/flight-filters.d.ts +8 -0
- package/build/build-cjs/search-results/components/flight/flight-accommodation-results.d.ts +4 -1
- package/build/build-cjs/search-results/components/flight/flight-option.d.ts +7 -0
- package/build/build-cjs/search-results/components/flight/flight-search-context/index.d.ts +36 -0
- package/build/build-cjs/search-results/components/icon.d.ts +1 -0
- package/build/build-cjs/search-results/components/item-picker/index.d.ts +5 -3
- package/build/build-cjs/search-results/components/search-results-container/flight-search-results.d.ts +6 -0
- package/build/build-cjs/search-results/store/search-results-slice.d.ts +2 -0
- package/build/build-cjs/search-results/types.d.ts +31 -1
- package/build/build-cjs/search-results/utils/flight-utils.d.ts +16 -0
- package/build/build-cjs/shared/components/flyin.d.ts +9 -0
- package/build/build-cjs/shared/types.d.ts +6 -0
- package/build/build-cjs/shared/utils/localization-util.d.ts +21 -0
- package/build/build-esm/booking-wizard/types.d.ts +1 -0
- package/build/build-esm/index.js +7157 -1485
- package/build/build-esm/qsm/store/qsm-slice.d.ts +4 -2
- package/build/build-esm/qsm/types.d.ts +2 -1
- package/build/build-esm/search-results/components/filters/flight-filters.d.ts +8 -0
- package/build/build-esm/search-results/components/flight/flight-accommodation-results.d.ts +4 -1
- package/build/build-esm/search-results/components/flight/flight-option.d.ts +7 -0
- package/build/build-esm/search-results/components/flight/flight-search-context/index.d.ts +36 -0
- package/build/build-esm/search-results/components/icon.d.ts +1 -0
- package/build/build-esm/search-results/components/item-picker/index.d.ts +5 -3
- package/build/build-esm/search-results/components/search-results-container/flight-search-results.d.ts +6 -0
- package/build/build-esm/search-results/store/search-results-slice.d.ts +2 -0
- package/build/build-esm/search-results/types.d.ts +31 -1
- package/build/build-esm/search-results/utils/flight-utils.d.ts +16 -0
- package/build/build-esm/shared/components/flyin.d.ts +9 -0
- package/build/build-esm/shared/types.d.ts +6 -0
- package/build/build-esm/shared/utils/localization-util.d.ts +21 -0
- package/package.json +4 -3
- package/rollup.config.js +2 -2
- package/src/booking-product/components/dates.tsx +1 -1
- package/src/booking-wizard/features/booking/booking-slice.ts +4 -2
- package/src/booking-wizard/types.ts +1 -0
- package/src/content/components/slider.tsx +1 -1
- package/src/qsm/components/QSMContainer/qsm-container.tsx +38 -26
- package/src/qsm/components/search-input-group/index.tsx +0 -1
- package/src/qsm/components/travel-input/index.tsx +4 -4
- package/src/qsm/components/travel-input-group/index.tsx +4 -3
- package/src/qsm/store/qsm-slice.ts +7 -1
- package/src/qsm/types.ts +3 -1
- package/src/search-results/components/filters/flight-filters.tsx +671 -0
- package/src/search-results/components/flight/flight-accommodation-results.tsx +20 -562
- package/src/search-results/components/flight/flight-option.tsx +243 -0
- package/src/search-results/components/flight/flight-search-context/index.tsx +508 -0
- package/src/search-results/components/hotel/hotel-card.tsx +0 -1
- package/src/search-results/components/icon.tsx +84 -44
- package/src/search-results/components/item-picker/index.tsx +16 -11
- package/src/search-results/components/search-results-container/flight-search-results.tsx +120 -0
- package/src/search-results/components/search-results-container/search-results-container.tsx +85 -70
- package/src/search-results/store/search-results-slice.ts +6 -0
- package/src/search-results/types.ts +37 -1
- package/src/search-results/utils/flight-utils.ts +106 -0
- package/src/shared/components/flyin.tsx +334 -0
- package/src/shared/translations/ar-SA.json +13 -1
- package/src/shared/translations/da-DK.json +13 -1
- package/src/shared/translations/de-DE.json +13 -1
- package/src/shared/translations/en-GB.json +13 -1
- package/src/shared/translations/es-ES.json +13 -1
- package/src/shared/translations/fr-BE.json +13 -1
- package/src/shared/translations/fr-FR.json +13 -1
- package/src/shared/translations/is-IS.json +13 -1
- package/src/shared/translations/it-IT.json +13 -1
- package/src/shared/translations/ja-JP.json +13 -1
- package/src/shared/translations/nl-BE.json +13 -1
- package/src/shared/translations/nl-NL.json +13 -1
- package/src/shared/translations/no-NO.json +13 -1
- package/src/shared/translations/pl-PL.json +13 -1
- package/src/shared/translations/pt-PT.json +13 -1
- package/src/shared/translations/sv-SE.json +13 -1
- package/src/shared/types.ts +7 -0
- package/src/shared/utils/localization-util.ts +71 -0
- package/styles/booking-search-results.scss +1 -0
- package/styles/components/_flyin.scss +550 -0
|
@@ -9,14 +9,19 @@ interface IconProps {
|
|
|
9
9
|
title?: string;
|
|
10
10
|
width?: number;
|
|
11
11
|
height?: number;
|
|
12
|
+
fill?: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) => {
|
|
15
|
+
const Icon: React.FC<IconProps> = ({ name, className, title, width, height, fill }) => {
|
|
15
16
|
const { icons } = { icons: '' }; // useContext(SettingsContext);
|
|
16
17
|
|
|
17
18
|
if (icons) {
|
|
18
19
|
return (
|
|
19
|
-
<svg
|
|
20
|
+
<svg
|
|
21
|
+
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
22
|
+
width={width}
|
|
23
|
+
height={height}
|
|
24
|
+
fill={fill ?? 'currentColor'}>
|
|
20
25
|
{title && <title>{title}</title>}
|
|
21
26
|
<use href={`${icons}#${name}`}></use>
|
|
22
27
|
</svg>
|
|
@@ -30,7 +35,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
30
35
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
31
36
|
width={width}
|
|
32
37
|
height={height}
|
|
33
|
-
viewBox="0 0 384 512"
|
|
38
|
+
viewBox="0 0 384 512"
|
|
39
|
+
fill={fill ?? 'currentColor'}>
|
|
34
40
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
35
41
|
{title && <title>{title}</title>}
|
|
36
42
|
<path
|
|
@@ -46,7 +52,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
46
52
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
47
53
|
width={width}
|
|
48
54
|
height={height}
|
|
49
|
-
viewBox="0 0 448 512"
|
|
55
|
+
viewBox="0 0 448 512"
|
|
56
|
+
fill={fill ?? 'currentColor'}>
|
|
50
57
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
51
58
|
{title && <title>{title}</title>}
|
|
52
59
|
<path d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z" />
|
|
@@ -59,7 +66,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
59
66
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
60
67
|
width={width}
|
|
61
68
|
height={height}
|
|
62
|
-
viewBox="0 0 448 512"
|
|
69
|
+
viewBox="0 0 448 512"
|
|
70
|
+
fill={fill ?? 'currentColor'}>
|
|
63
71
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
64
72
|
{title && <title>{title}</title>}
|
|
65
73
|
<path d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z" />
|
|
@@ -72,7 +80,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
72
80
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
73
81
|
width={width}
|
|
74
82
|
height={height}
|
|
75
|
-
viewBox="0 0 320 512"
|
|
83
|
+
viewBox="0 0 320 512"
|
|
84
|
+
fill={fill ?? 'currentColor'}>
|
|
76
85
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
77
86
|
{title && <title>{title}</title>}
|
|
78
87
|
<path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" />
|
|
@@ -85,7 +94,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
85
94
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
86
95
|
width={width}
|
|
87
96
|
height={height}
|
|
88
|
-
viewBox="0 0 512 512"
|
|
97
|
+
viewBox="0 0 512 512"
|
|
98
|
+
fill={fill ?? 'currentColor'}>
|
|
89
99
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
90
100
|
{title && <title>{title}</title>}
|
|
91
101
|
<path
|
|
@@ -101,7 +111,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
101
111
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
102
112
|
width={width}
|
|
103
113
|
height={height}
|
|
104
|
-
viewBox="0 0 448 512"
|
|
114
|
+
viewBox="0 0 448 512"
|
|
115
|
+
fill={fill ?? 'currentColor'}>
|
|
105
116
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
106
117
|
{title && <title>{title}</title>}
|
|
107
118
|
<path
|
|
@@ -117,7 +128,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
117
128
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
118
129
|
width={width}
|
|
119
130
|
height={height}
|
|
120
|
-
viewBox="0 0 640 512"
|
|
131
|
+
viewBox="0 0 640 512"
|
|
132
|
+
fill={fill ?? 'currentColor'}>
|
|
121
133
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
122
134
|
{title && <title>{title}</title>}
|
|
123
135
|
<path
|
|
@@ -133,7 +145,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
133
145
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
134
146
|
width={width}
|
|
135
147
|
height={height}
|
|
136
|
-
viewBox="0 0 416 512"
|
|
148
|
+
viewBox="0 0 416 512"
|
|
149
|
+
fill={fill ?? 'currentColor'}>
|
|
137
150
|
<HTMLComment text="!Font Awesome Free v5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc." />
|
|
138
151
|
{title && <title>{title}</title>}
|
|
139
152
|
<path d="M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z" />
|
|
@@ -146,13 +159,11 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
146
159
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
147
160
|
width={width}
|
|
148
161
|
height={height}
|
|
149
|
-
viewBox="0 0 576 512"
|
|
162
|
+
viewBox="0 0 576 512"
|
|
163
|
+
fill={fill ?? 'currentColor'}>
|
|
150
164
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
151
165
|
{title && <title>{title}</title>}
|
|
152
|
-
<path
|
|
153
|
-
d="M482.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64l-116.6 0L265.2 495.9c-5.7 10-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.2-15.4-20.4l49-171.6L112 320 68.8 377.6c-3 4-7.8 6.4-12.8 6.4l-42 0c-7.8 0-14-6.3-14-14c0-1.3 .2-2.6 .5-3.9L32 256 .5 145.9c-.4-1.3-.5-2.6-.5-3.9c0-7.8 6.3-14 14-14l42 0c5 0 9.8 2.4 12.8 6.4L112 192l102.9 0-49-171.6C162.9 10.2 170.6 0 181.2 0l56.2 0c11.5 0 22.1 6.2 27.8 16.1L365.7 192l116.6 0z"
|
|
154
|
-
fill="currentColor"
|
|
155
|
-
/>
|
|
166
|
+
<path d="M482.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64l-116.6 0L265.2 495.9c-5.7 10-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.2-15.4-20.4l49-171.6L112 320 68.8 377.6c-3 4-7.8 6.4-12.8 6.4l-42 0c-7.8 0-14-6.3-14-14c0-1.3 .2-2.6 .5-3.9L32 256 .5 145.9c-.4-1.3-.5-2.6-.5-3.9c0-7.8 6.3-14 14-14l42 0c5 0 9.8 2.4 12.8 6.4L112 192l102.9 0-49-171.6C162.9 10.2 170.6 0 181.2 0l56.2 0c11.5 0 22.1 6.2 27.8 16.1L365.7 192l116.6 0z" />
|
|
156
167
|
</svg>
|
|
157
168
|
);
|
|
158
169
|
|
|
@@ -162,7 +173,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
162
173
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
163
174
|
width={width}
|
|
164
175
|
height={height}
|
|
165
|
-
viewBox="0 0 512 512"
|
|
176
|
+
viewBox="0 0 512 512"
|
|
177
|
+
fill={fill ?? 'currentColor'}>
|
|
166
178
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
167
179
|
{title && <title>{title}</title>}
|
|
168
180
|
<path
|
|
@@ -178,7 +190,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
178
190
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
179
191
|
width={width}
|
|
180
192
|
height={height}
|
|
181
|
-
viewBox="0 0 576 512"
|
|
193
|
+
viewBox="0 0 576 512"
|
|
194
|
+
fill={fill ?? 'currentColor'}>
|
|
182
195
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
183
196
|
{title && <title>{title}</title>}
|
|
184
197
|
<path d="M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z" />
|
|
@@ -191,7 +204,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
191
204
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
192
205
|
width={width}
|
|
193
206
|
height={height}
|
|
194
|
-
viewBox="0 0 576 512"
|
|
207
|
+
viewBox="0 0 576 512"
|
|
208
|
+
fill={fill ?? 'currentColor'}>
|
|
195
209
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
196
210
|
{title && <title>{title}</title>}
|
|
197
211
|
<path d="M288 0c-12.2 .1-23.3 7-28.6 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3L288 439.8 288 0zM429.9 512c1.1 .1 2.1 .1 3.2 0l-3.2 0z" />
|
|
@@ -204,7 +218,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
204
218
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
205
219
|
width={width}
|
|
206
220
|
height={height}
|
|
207
|
-
viewBox="0 0 448 512"
|
|
221
|
+
viewBox="0 0 448 512"
|
|
222
|
+
fill={fill ?? 'currentColor'}>
|
|
208
223
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
209
224
|
{title && <title>{title}</title>}
|
|
210
225
|
<path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512l388.6 0c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304l-91.4 0z" />
|
|
@@ -217,7 +232,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
217
232
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
218
233
|
width={width}
|
|
219
234
|
height={height}
|
|
220
|
-
viewBox="0 0 512 512"
|
|
235
|
+
viewBox="0 0 512 512"
|
|
236
|
+
fill={fill ?? 'currentColor'}>
|
|
221
237
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
222
238
|
{title && <title>{title}</title>}
|
|
223
239
|
<path d="M410.3 231l11.3-11.3-33.9-33.9-62.1-62.1L291.7 89.8l-11.3 11.3-22.6 22.6L58.6 322.9c-10.4 10.4-18 23.3-22.2 37.4L1 480.7c-2.5 8.4-.2 17.5 6.1 23.7s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L387.7 253.7 410.3 231zM160 399.4l-9.1 22.7c-4 3.1-8.5 5.4-13.3 6.9L59.4 452l23-78.1c1.4-4.9 3.8-9.4 6.9-13.3l22.7-9.1 0 32c0 8.8 7.2 16 16 16l32 0zM362.7 18.7L348.3 33.2 325.7 55.8 314.3 67.1l33.9 33.9 62.1 62.1 33.9 33.9 11.3-11.3 22.6-22.6 14.5-14.5c25-25 25-65.5 0-90.5L453.3 18.7c-25-25-65.5-25-90.5 0zm-47.4 168l-144 144c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l144-144c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" />
|
|
@@ -230,7 +246,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
230
246
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
231
247
|
width={width}
|
|
232
248
|
height={height}
|
|
233
|
-
viewBox="0 0 448 512"
|
|
249
|
+
viewBox="0 0 448 512"
|
|
250
|
+
fill={fill ?? 'currentColor'}>
|
|
234
251
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
235
252
|
{title && <title>{title}</title>}
|
|
236
253
|
<path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z" />
|
|
@@ -243,7 +260,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
243
260
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
244
261
|
width={width}
|
|
245
262
|
height={height}
|
|
246
|
-
viewBox="0 0 640 640"
|
|
263
|
+
viewBox="0 0 640 640"
|
|
264
|
+
fill={fill ?? 'currentColor'}>
|
|
247
265
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
248
266
|
{title && <title>{title}</title>}
|
|
249
267
|
<path
|
|
@@ -259,7 +277,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
259
277
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
260
278
|
width={width}
|
|
261
279
|
height={height}
|
|
262
|
-
viewBox="0 0 384 512"
|
|
280
|
+
viewBox="0 0 384 512"
|
|
281
|
+
fill={fill ?? 'currentColor'}>
|
|
263
282
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
264
283
|
{title && <title>{title}</title>}
|
|
265
284
|
<path
|
|
@@ -275,7 +294,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
275
294
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
276
295
|
width={width}
|
|
277
296
|
height={height}
|
|
278
|
-
viewBox="0 0 512 512"
|
|
297
|
+
viewBox="0 0 512 512"
|
|
298
|
+
fill={fill ?? 'currentColor'}>
|
|
279
299
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
280
300
|
{title && <title>{title}</title>}
|
|
281
301
|
<path
|
|
@@ -291,7 +311,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
291
311
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
292
312
|
width={width}
|
|
293
313
|
height={height}
|
|
294
|
-
viewBox="0 0 576 512"
|
|
314
|
+
viewBox="0 0 576 512"
|
|
315
|
+
fill={fill ?? 'currentColor'}>
|
|
295
316
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
296
317
|
{title && <title>{title}</title>}
|
|
297
318
|
<path
|
|
@@ -307,7 +328,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
307
328
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
308
329
|
width={width}
|
|
309
330
|
height={height}
|
|
310
|
-
viewBox="0 0 512 512"
|
|
331
|
+
viewBox="0 0 512 512"
|
|
332
|
+
fill={fill ?? 'currentColor'}>
|
|
311
333
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
312
334
|
{title && <title>{title}</title>}
|
|
313
335
|
<path
|
|
@@ -323,7 +345,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
323
345
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
324
346
|
width={width}
|
|
325
347
|
height={height}
|
|
326
|
-
viewBox="0 0 512 512"
|
|
348
|
+
viewBox="0 0 512 512"
|
|
349
|
+
fill={fill ?? 'currentColor'}>
|
|
327
350
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
328
351
|
{title && <title>{title}</title>}
|
|
329
352
|
<path
|
|
@@ -339,7 +362,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
339
362
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
340
363
|
width={width}
|
|
341
364
|
height={height}
|
|
342
|
-
viewBox="0 0 640 512"
|
|
365
|
+
viewBox="0 0 640 512"
|
|
366
|
+
fill={fill ?? 'currentColor'}>
|
|
343
367
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
344
368
|
{title && <title>{title}</title>}
|
|
345
369
|
<path
|
|
@@ -355,7 +379,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
355
379
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
356
380
|
width={width}
|
|
357
381
|
height={height}
|
|
358
|
-
viewBox="0 0 448 512"
|
|
382
|
+
viewBox="0 0 448 512"
|
|
383
|
+
fill={fill ?? 'currentColor'}>
|
|
359
384
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
360
385
|
{title && <title>{title}</title>}
|
|
361
386
|
<path
|
|
@@ -371,7 +396,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
371
396
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
372
397
|
width={width}
|
|
373
398
|
height={height}
|
|
374
|
-
viewBox="0 0 576 512"
|
|
399
|
+
viewBox="0 0 576 512"
|
|
400
|
+
fill={fill ?? 'currentColor'}>
|
|
375
401
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
376
402
|
{title && <title>{title}</title>}
|
|
377
403
|
<path
|
|
@@ -387,7 +413,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
387
413
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
388
414
|
width={width}
|
|
389
415
|
height={height}
|
|
390
|
-
viewBox="0 0 10.701 9.698"
|
|
416
|
+
viewBox="0 0 10.701 9.698"
|
|
417
|
+
fill={fill ?? 'currentColor'}>
|
|
391
418
|
{/* <HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." /> */}
|
|
392
419
|
{title && <title>{title}</title>}
|
|
393
420
|
<g id="filter-solid" transform="translate(-2.667 -5.333)">
|
|
@@ -413,7 +440,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
413
440
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
414
441
|
width={width}
|
|
415
442
|
height={height}
|
|
416
|
-
viewBox="0 0 576 512"
|
|
443
|
+
viewBox="0 0 576 512"
|
|
444
|
+
fill={fill ?? 'currentColor'}>
|
|
417
445
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
418
446
|
{title && <title>{title}</title>}
|
|
419
447
|
<path
|
|
@@ -429,7 +457,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
429
457
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
430
458
|
width={width}
|
|
431
459
|
height={height}
|
|
432
|
-
viewBox="0 0 640 512"
|
|
460
|
+
viewBox="0 0 640 512"
|
|
461
|
+
fill={fill ?? 'currentColor'}>
|
|
433
462
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
434
463
|
{title && <title>{title}</title>}
|
|
435
464
|
<path d="M381 114.9L186.1 41.8c-16.7-6.2-35.2-5.3-51.1 2.7L89.1 67.4C78 73 77.2 88.5 87.6 95.2l146.9 94.5L136 240 77.8 214.1c-8.7-3.9-18.8-3.7-27.3 .6L18.3 230.8c-9.3 4.7-11.8 16.8-5 24.7l73.1 85.3c6.1 7.1 15 11.2 24.3 11.2l137.7 0c5 0 9.9-1.2 14.3-3.4L535.6 212.2c46.5-23.3 82.5-63.3 100.8-112C645.9 75 627.2 48 600.2 48l-57.4 0c-20.2 0-40.2 4.8-58.2 14L381 114.9zM0 480c0 17.7 14.3 32 32 32l576 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 448c-17.7 0-32 14.3-32 32z" />
|
|
@@ -442,7 +471,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
442
471
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
443
472
|
width={width}
|
|
444
473
|
height={height}
|
|
445
|
-
viewBox="0 0 640 512"
|
|
474
|
+
viewBox="0 0 640 512"
|
|
475
|
+
fill={fill ?? 'currentColor'}>
|
|
446
476
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
447
477
|
{title && <title>{title}</title>}
|
|
448
478
|
<path d="M.3 166.9L0 68C0 57.7 9.5 50.1 19.5 52.3l35.6 7.9c10.6 2.3 19.2 9.9 23 20L96 128l127.3 37.6L181.8 20.4C178.9 10.2 186.6 0 197.2 0l40.1 0c11.6 0 22.2 6.2 27.9 16.3l109 193.8 107.2 31.7c15.9 4.7 30.8 12.5 43.7 22.8l34.4 27.6c24 19.2 18.1 57.3-10.7 68.2c-41.2 15.6-86.2 18.1-128.8 7L121.7 289.8c-11.1-2.9-21.2-8.7-29.3-16.9L9.5 189.4c-5.9-6-9.3-14.1-9.3-22.5zM32 448l576 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32s14.3-32 32-32zm96-80a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm128-16a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" />
|
|
@@ -455,7 +485,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
455
485
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
456
486
|
width={width}
|
|
457
487
|
height={height}
|
|
458
|
-
viewBox="0 0 19 19"
|
|
488
|
+
viewBox="0 0 19 19"
|
|
489
|
+
fill={fill ?? 'currentColor'}>
|
|
459
490
|
{/* <HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." /> */}
|
|
460
491
|
{title && <title>{title}</title>}
|
|
461
492
|
<g id="Group_56" data-name="Group 56" transform="translate(-390 -665)">
|
|
@@ -479,7 +510,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
479
510
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
480
511
|
width={width}
|
|
481
512
|
height={height}
|
|
482
|
-
viewBox="0 0 448 512"
|
|
513
|
+
viewBox="0 0 448 512"
|
|
514
|
+
fill={fill ?? 'currentColor'}>
|
|
483
515
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
484
516
|
{title && <title>{title}</title>}
|
|
485
517
|
<path
|
|
@@ -495,7 +527,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
495
527
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
496
528
|
width={width}
|
|
497
529
|
height={height}
|
|
498
|
-
viewBox="0 0 512 512"
|
|
530
|
+
viewBox="0 0 512 512"
|
|
531
|
+
fill={fill ?? 'currentColor'}>
|
|
499
532
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
500
533
|
{title && <title>{title}</title>}
|
|
501
534
|
<path
|
|
@@ -511,7 +544,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
511
544
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
512
545
|
width={width}
|
|
513
546
|
height={height}
|
|
514
|
-
viewBox="0 0 448 512"
|
|
547
|
+
viewBox="0 0 448 512"
|
|
548
|
+
fill={fill ?? 'currentColor'}>
|
|
515
549
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
516
550
|
{title && <title>{title}</title>}
|
|
517
551
|
<path
|
|
@@ -527,7 +561,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
527
561
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
528
562
|
width={width}
|
|
529
563
|
height={height}
|
|
530
|
-
viewBox="0 0 448 512"
|
|
564
|
+
viewBox="0 0 448 512"
|
|
565
|
+
fill={fill ?? 'currentColor'}>
|
|
531
566
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
532
567
|
{title && <title>{title}</title>}
|
|
533
568
|
<path
|
|
@@ -543,7 +578,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
543
578
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
544
579
|
width={width}
|
|
545
580
|
height={height}
|
|
546
|
-
viewBox="0 0 512 512"
|
|
581
|
+
viewBox="0 0 512 512"
|
|
582
|
+
fill={fill ?? 'currentColor'}>
|
|
547
583
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
548
584
|
{title && <title>{title}</title>}
|
|
549
585
|
<path
|
|
@@ -559,7 +595,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
559
595
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
560
596
|
width={width}
|
|
561
597
|
height={height}
|
|
562
|
-
viewBox="0 0 512 512"
|
|
598
|
+
viewBox="0 0 512 512"
|
|
599
|
+
fill={fill ?? 'currentColor'}>
|
|
563
600
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
564
601
|
{title && <title>{title}</title>}
|
|
565
602
|
<path
|
|
@@ -575,7 +612,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
575
612
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
576
613
|
width={width}
|
|
577
614
|
height={height}
|
|
578
|
-
viewBox="0 0 512 512"
|
|
615
|
+
viewBox="0 0 512 512"
|
|
616
|
+
fill={fill ?? 'currentColor'}>
|
|
579
617
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
580
618
|
{title && <title>{title}</title>}
|
|
581
619
|
<path d="M448 256c0-106-86-192-192-192l0 384c106 0 192-86 192-192zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z" fill="currentColor" />
|
|
@@ -588,7 +626,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
588
626
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
589
627
|
width={width}
|
|
590
628
|
height={height}
|
|
591
|
-
viewBox="0 0 512 512"
|
|
629
|
+
viewBox="0 0 512 512"
|
|
630
|
+
fill={fill ?? 'currentColor'}>
|
|
592
631
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
593
632
|
{title && <title>{title}</title>}
|
|
594
633
|
<path
|
|
@@ -604,7 +643,8 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
604
643
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
605
644
|
width={width}
|
|
606
645
|
height={height}
|
|
607
|
-
viewBox="0 0 384 512"
|
|
646
|
+
viewBox="0 0 384 512"
|
|
647
|
+
fill={fill ?? 'currentColor'}>
|
|
608
648
|
<HTMLComment text="!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc." />
|
|
609
649
|
{title && <title>{title}</title>}
|
|
610
650
|
<path
|
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { TravelClass, TravelType } from '../../types';
|
|
2
|
+
import { SortByType, TravelClass, TravelType } from '../../types';
|
|
3
3
|
|
|
4
4
|
interface ItemPickerProps {
|
|
5
|
-
items: TravelType[] | TravelClass[];
|
|
5
|
+
items: TravelType[] | TravelClass[] | SortByType[];
|
|
6
6
|
selection: string | undefined;
|
|
7
|
+
selectedSortByType?: SortByType;
|
|
7
8
|
label: string;
|
|
8
9
|
placeholder: string;
|
|
9
10
|
classModifier: string;
|
|
10
|
-
|
|
11
|
+
valueFormatter?: (value: string, direction?: string) => string;
|
|
12
|
+
onPick: (picked: string, direction?: string) => void;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
const ItemPicker: React.FC<ItemPickerProps> = ({ items, selection, label, placeholder, classModifier, onPick }) => {
|
|
15
|
+
const ItemPicker: React.FC<ItemPickerProps> = ({ items, selection, selectedSortByType, label, placeholder, classModifier, onPick, valueFormatter }) => {
|
|
14
16
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
15
17
|
const [openDirection, setOpenDirection] = useState<'down' | 'up'>('down');
|
|
16
18
|
const dropdownRef = useRef<HTMLDivElement | null>(null);
|
|
17
19
|
const dropdownMenuRef = useRef<HTMLUListElement | null>(null);
|
|
18
20
|
const toggleButtonRef = useRef<HTMLButtonElement | null>(null);
|
|
19
21
|
|
|
20
|
-
const handlePick = (picked: string) => {
|
|
22
|
+
const handlePick = (picked: string, direction?: string) => {
|
|
21
23
|
setIsDropdownOpen(false);
|
|
22
|
-
onPick(picked);
|
|
24
|
+
onPick(picked, direction);
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
useEffect(() => {
|
|
@@ -54,15 +56,18 @@ const ItemPicker: React.FC<ItemPickerProps> = ({ items, selection, label, placeh
|
|
|
54
56
|
className={`dropdown-toggle ${isDropdownOpen ? 'dropdown-toggle--open' : ''}`}
|
|
55
57
|
onClick={() => setIsDropdownOpen((prev) => !prev)}
|
|
56
58
|
ref={toggleButtonRef}>
|
|
57
|
-
<span>{selection || placeholder}</span>
|
|
59
|
+
<span>{selectedSortByType ? valueFormatter?.(selectedSortByType.label, selectedSortByType?.direction) : selection || placeholder}</span>
|
|
58
60
|
<span className="arrow">▾</span>
|
|
59
61
|
</button>
|
|
60
62
|
{isDropdownOpen && (
|
|
61
63
|
<ul className={`dropdown-menu dropdown-menu--${openDirection}`} ref={dropdownMenuRef}>
|
|
62
|
-
{items.map((
|
|
63
|
-
<li
|
|
64
|
-
|
|
65
|
-
{label}
|
|
64
|
+
{items.map((item, index) => (
|
|
65
|
+
<li
|
|
66
|
+
key={`${item.label}-${index}`}
|
|
67
|
+
onClick={() => handlePick(item.label, 'direction' in item ? item.direction : undefined)}
|
|
68
|
+
className={`dropdown-menu__item${selection === item.label ? ' dropdown-menu__item--selected' : ''}`}>
|
|
69
|
+
{item.icon && <span className="travel-class-icon">{item.icon}</span>}
|
|
70
|
+
{valueFormatter ? valueFormatter(item.label, 'direction' in item ? item.direction : undefined) : item.label}
|
|
66
71
|
</li>
|
|
67
72
|
))}
|
|
68
73
|
</ul>
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
2
|
+
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
|
|
3
|
+
|
|
4
|
+
import ItemPicker from '../item-picker';
|
|
5
|
+
|
|
6
|
+
import Icon from '../icon';
|
|
7
|
+
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
8
|
+
import FlightAccommodationResults from '../flight/flight-accommodation-results';
|
|
9
|
+
import { useFlightSearch } from '../flight/flight-search-context';
|
|
10
|
+
import FlightFilters from '../filters/flight-filters';
|
|
11
|
+
import { ExtendedFlightSearchResponseItem } from '../../types';
|
|
12
|
+
import { getSortingName } from '../../utils/flight-utils';
|
|
13
|
+
|
|
14
|
+
interface FlightResultsContainerProps {
|
|
15
|
+
isMobile: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const FlightResultsContainer: React.FC<FlightResultsContainerProps> = ({ isMobile }) => {
|
|
19
|
+
const context = useContext(SearchResultsConfigurationContext);
|
|
20
|
+
const translations = getTranslations(context?.languageCode ?? 'en-GB');
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
flightsLoading,
|
|
24
|
+
onFlightSearch,
|
|
25
|
+
flightSearchResults,
|
|
26
|
+
filteredResults,
|
|
27
|
+
isHubReady,
|
|
28
|
+
sortByTypes,
|
|
29
|
+
selectedSortByType,
|
|
30
|
+
setSelectedSortByType,
|
|
31
|
+
currentRequestId
|
|
32
|
+
} = useFlightSearch();
|
|
33
|
+
const [filtersOpen, setFiltersOpen] = useState(false);
|
|
34
|
+
const [results, setResults] = React.useState<ExtendedFlightSearchResponseItem[]>([]);
|
|
35
|
+
|
|
36
|
+
const findSortByType = (sortKey: string, direction: string) => {
|
|
37
|
+
return sortByTypes.find((s) => s.label === sortKey && s.direction === direction) || sortByTypes[0];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleSortChange = (sortKey: string, direction?: string) => {
|
|
41
|
+
setSelectedSortByType(findSortByType(sortKey, direction ?? 'asc'));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!context?.showMockup) {
|
|
46
|
+
if (context?.type === 'flight' && isHubReady) {
|
|
47
|
+
onFlightSearch();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, [location.search, isHubReady]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
setResults(filteredResults.filter((item) => item.requestId === currentRequestId));
|
|
54
|
+
}, [filteredResults, currentRequestId]);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<>
|
|
58
|
+
{context?.showFilters && <FlightFilters isOpen={filtersOpen} handleSetIsOpen={() => setFiltersOpen(!filtersOpen)} isLoading={flightsLoading} />}
|
|
59
|
+
{/* ---------------- Results ---------------- */}
|
|
60
|
+
<div className="search__results">
|
|
61
|
+
{isMobile && (
|
|
62
|
+
<div className="search__result-row">
|
|
63
|
+
<div className="search__results__actions">
|
|
64
|
+
{context?.showFilters && (
|
|
65
|
+
<div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
|
|
66
|
+
<Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
|
|
67
|
+
{translations.SRP.FILTERS}
|
|
68
|
+
</div>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
{sortByTypes && sortByTypes.length > 0 && (
|
|
72
|
+
<ItemPicker
|
|
73
|
+
items={sortByTypes}
|
|
74
|
+
selection={selectedSortByType?.label || undefined}
|
|
75
|
+
selectedSortByType={selectedSortByType || undefined}
|
|
76
|
+
label={translations.SRP.SORTBY}
|
|
77
|
+
placeholder={translations.SRP.SORTBY}
|
|
78
|
+
classModifier="travel-class-picker__items"
|
|
79
|
+
valueFormatter={(value, direction) => getSortingName(translations, findSortByType(value, direction ?? 'asc'))}
|
|
80
|
+
onPick={handleSortChange}
|
|
81
|
+
/>
|
|
82
|
+
)}
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
<div className="search__result-row">
|
|
87
|
+
<span className="search__result-row-text">
|
|
88
|
+
{!flightsLoading && (
|
|
89
|
+
<>
|
|
90
|
+
{results?.length && results.length} {translations.SRP.TOTAL_RESULTS_LABEL}
|
|
91
|
+
</>
|
|
92
|
+
)}
|
|
93
|
+
</span>
|
|
94
|
+
{!isMobile && sortByTypes && sortByTypes.length > 0 && (
|
|
95
|
+
<div className="search__result-row-filter">
|
|
96
|
+
<ItemPicker
|
|
97
|
+
items={sortByTypes}
|
|
98
|
+
selection={selectedSortByType?.label || undefined}
|
|
99
|
+
selectedSortByType={selectedSortByType || undefined}
|
|
100
|
+
label={translations.SRP.SORTBY}
|
|
101
|
+
placeholder={translations.SRP.SORTBY}
|
|
102
|
+
classModifier="travel-class-picker__items"
|
|
103
|
+
valueFormatter={(value, direction) => getSortingName(translations, findSortByType(value, direction ?? 'asc'))}
|
|
104
|
+
onPick={handleSortChange}
|
|
105
|
+
/>
|
|
106
|
+
</div>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div className="search__results__wrapper">
|
|
111
|
+
{context?.type == 'flight' && context?.showFlightAccommodationResults && results && results.length > 0 && (
|
|
112
|
+
<FlightAccommodationResults searchResults={results} />
|
|
113
|
+
)}
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default FlightResultsContainer;
|