@qite/tide-booking-component 1.4.33 → 1.4.34

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.
@@ -1,337 +1,341 @@
1
- import React, { useContext, useEffect, useState } from 'react';
2
- import { useDispatch, useSelector } from 'react-redux';
3
- import { SearchResultsRootState } from '../../store/search-results-store';
4
- import SearchResultsConfigurationContext from '../../search-results-configuration-context';
5
-
6
- import { resetFilters, setSortKey, setResults, setIsLoading, setSelectedHotel } from '../../store/search-results-slice';
7
- import { Filter, SortingOption } from '../../types';
8
- import useMediaQuery from '../../../shared/utils/use-media-query-util';
9
- import Filters from '../filters/filters';
10
- import ItemPicker from '../item-picker';
11
-
12
- import { TideClientConfig, details, search } from '@qite/tide-client';
13
- import {
14
- BookingPackageDestination,
15
- BookingPackageDetailsRequest,
16
- BookingPackagePax,
17
- BookingPackageRequest,
18
- BookingPackageRequestRoom,
19
- BookingPackageSearchRequest
20
- } from '@qite/tide-client/build/types';
21
- import { getDateFromParams, getNumberFromParams, getRoomsFromParams } from '../../../shared/utils/query-string-util';
22
- import { range } from 'lodash';
23
- import { Room } from '../../../booking-wizard/types';
24
- import Icon from '../icon';
25
- import Itinerary from '../itinerary';
26
- import TabViews from '../tab-views';
27
- import HotelAccommodationResults from '../hotel/hotel-accommodation-results';
28
- import RoundTripResults from '../round-trip/round-trip-results';
29
- import { enrichFiltersWithResults } from '../filters/utility';
30
-
31
- const SearchResultsContainer: React.FC = () => {
32
- const isMobile = useMediaQuery('(max-width: 1200px)');
33
- const dispatch = useDispatch();
34
- const context = useContext(SearchResultsConfigurationContext);
35
- const { results, isLoading, filters, sortKey, selectedHotelId } = useSelector((state: SearchResultsRootState) => state.searchResults);
36
-
37
- const [searchTrigger, setSearchTrigger] = useState(0);
38
- const [initialFiltersSet, setInitialFiltersSet] = useState(false);
39
- const [initialFilters, setInitialFilters] = useState<Filter[]>([]);
40
-
41
- useEffect(() => {
42
- const runSearch = async () => {
43
- dispatch(setIsLoading(true));
44
- try {
45
- if (!context) {
46
- return;
47
- }
48
-
49
- const params = new URLSearchParams(location.search);
50
- let from = getDateFromParams(params, 'fromDate');
51
- let to = getDateFromParams(params, 'toDate');
52
- const rooms = getRoomsFromParams(params, 'rooms');
53
- let country = getNumberFromParams(params, 'country');
54
- let region = getNumberFromParams(params, 'region');
55
- let oord = getNumberFromParams(params, 'oord');
56
- let city = getNumberFromParams(params, 'location');
57
-
58
- // temp hardcoded params
59
- if (!from || !to) {
60
- from = '2026-04-07';
61
- to = '2026-04-13';
62
- }
63
- if (!country && !region && !oord && !city) {
64
- region = 1;
65
- }
66
-
67
- if (typeof window !== 'undefined') {
68
- window.scrollTo(0, 0);
69
- }
70
-
71
- let destinationId: number | null = null;
72
- let destinationIsCountry = false;
73
- let destinationIsRegion = false;
74
- let destinationIsOord = false;
75
- let destinationIsLocation = false;
76
-
77
- if (country) {
78
- destinationId = country;
79
- destinationIsCountry = true;
80
- } else if (region) {
81
- destinationId = region;
82
- destinationIsRegion = true;
83
- } else if (oord) {
84
- destinationId = oord;
85
- destinationIsOord = true;
86
- } else if (city) {
87
- destinationId = city;
88
- destinationIsLocation = true;
89
- }
90
-
91
- const searchRequest: BookingPackageRequest<BookingPackageSearchRequest> = {
92
- officeId: 1,
93
- payload: {
94
- catalogueIds: context.tideConnection.catalogueIds ?? [],
95
- serviceType:
96
- context?.type === 'hotel' || context?.type === 'hotel-flight' ? 3 : context?.type === 'flight' ? 7 : context?.type === 'roundTrip' ? 1 : 0,
97
- searchType: 0,
98
- destination: {
99
- id: Number(destinationId),
100
- isCountry: destinationIsCountry,
101
- isRegion: destinationIsRegion,
102
- isOord: destinationIsOord,
103
- isLocation: destinationIsLocation
104
- } as BookingPackageDestination,
105
- rooms: getRequestRooms(rooms),
106
- fromDate: from,
107
- toDate: to,
108
- earliestFromOffset: 0,
109
- latestToOffset: 0,
110
- includeFlights: true,
111
- regimeCodes:
112
- filters
113
- .find((f) => f.property === 'regime')
114
- ?.options?.filter((o) => o.isChecked)
115
- .flatMap((o) => o.value.toString()) || [],
116
- minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
117
- maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
118
- useExactDates: true,
119
- onlyCachedResults: false,
120
- includeAllAllotments: true
121
- }
122
- };
123
-
124
- const config: TideClientConfig = {
125
- host: context.tideConnection.host,
126
- apiKey: context.tideConnection.apiKey
127
- };
128
-
129
- const packageSearchResults = await search(config, searchRequest);
130
-
131
- console.log('Search results', packageSearchResults);
132
-
133
- const enrichedFilters = enrichFiltersWithResults(packageSearchResults, context.filters);
134
- if (!initialFiltersSet) {
135
- dispatch(resetFilters(enrichedFilters));
136
- setInitialFilters(enrichedFilters);
137
- setInitialFiltersSet(true);
138
- }
139
-
140
- dispatch(setResults({ results: packageSearchResults }));
141
- if (packageSearchResults?.length > 0) {
142
- dispatch(setSelectedHotel(packageSearchResults[0].productId));
143
- }
144
- dispatch(setIsLoading(false));
145
- } catch (err) {
146
- console.error('Search failed', err);
147
- dispatch(setIsLoading(false));
148
- }
149
- };
150
-
151
- runSearch();
152
- }, [location.search, searchTrigger]);
153
-
154
- useEffect(() => {
155
- const fetchPackageDetails = async () => {
156
- if (!selectedHotelId || !context) return;
157
-
158
- try {
159
- const config: TideClientConfig = {
160
- host: context.tideConnection.host,
161
- apiKey: context.tideConnection.apiKey
162
- };
163
-
164
- const selectedItem = results.find((r) => r.productId === selectedHotelId);
165
- if (!selectedItem) return;
166
-
167
- const params = new URLSearchParams(location.search);
168
- const rooms = getRoomsFromParams(params, 'rooms');
169
- const requestRooms = getRequestRooms(rooms);
170
-
171
- const detailsRequest: BookingPackageRequest<BookingPackageDetailsRequest> = {
172
- officeId: 1,
173
- payload: {
174
- catalogueId: selectedItem.catalogueId,
175
- rooms: requestRooms,
176
- searchType: 0, // same as search
177
- productCode: selectedItem.code,
178
- fromDate: selectedItem.fromDate,
179
- toDate: selectedItem.toDate,
180
- includeFlights: true,
181
- includeHotels: true,
182
- includePaxTypes: true,
183
- checkExternalAvailability: true,
184
- expectedPrice: selectedItem.price,
185
- duration: null,
186
- preNights: null,
187
- postNights: null
188
- }
189
- };
190
-
191
- const detailsResponse = await details(config, detailsRequest);
192
-
193
- console.log('Package details:', detailsResponse);
194
-
195
- // TODO: store flights / details in redux
196
- // dispatch(setSelectedHotelDetails(details));
197
- } catch (err) {
198
- console.error('Failed to fetch package details', err);
199
- }
200
- };
201
-
202
- fetchPackageDetails();
203
- }, [selectedHotelId]);
204
-
205
- const getRequestRooms = (rooms: Room[] | null) => {
206
- if (!rooms) {
207
- // Fall back to 2 adults
208
- var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
209
- range(0, 2).forEach(() => {
210
- room.pax.push({
211
- age: 30
212
- } as BookingPackagePax);
213
- });
214
- return [room];
215
- }
216
-
217
- const requestRooms = rooms?.map((x, i) => {
218
- var room = { index: i, pax: [] } as BookingPackageRequestRoom;
219
- range(0, x.adults).forEach(() => {
220
- room.pax.push({
221
- age: 30
222
- } as BookingPackagePax);
223
- });
224
- x.childAges.forEach((x) => {
225
- room.pax.push({
226
- age: x
227
- } as BookingPackagePax);
228
- });
229
- return room;
230
- });
231
-
232
- return requestRooms;
233
- };
234
-
235
- const [isMobileFiltersOpen, setIsMobileFiltersOpen] = useState(false);
236
-
237
- const handleSortChange = (newSortKey: string) => {
238
- dispatch(setSortKey(newSortKey));
239
- };
240
-
241
- const handleSetIsMobileFiltersOpen = () => {
242
- setIsMobileFiltersOpen(!isMobileFiltersOpen);
243
- };
244
-
245
- useEffect(() => {
246
- if (typeof document !== 'undefined') {
247
- document.body.classList.toggle('has-overlay', isMobileFiltersOpen);
248
- }
249
- }, [isMobileFiltersOpen]);
250
-
251
- const sortingOptions: SortingOption[] = [
252
- { key: 'price-asc', label: 'Price: Low to High' },
253
- { key: 'price-desc', label: 'Price: High to Low' },
254
- { key: 'departure-date', label: 'Departure Date' }
255
- ];
256
-
257
- return (
258
- <div id="tide-booking" className="search__bg">
259
- {context && (
260
- <div className="search">
261
- <div className="search__container">
262
- {context.showFilters && (
263
- <Filters
264
- filters={filters}
265
- isMobileFiltersOpen={isMobileFiltersOpen}
266
- handleSetIsMobileFiltersOpen={handleSetIsMobileFiltersOpen}
267
- handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
268
- isLoading={isLoading}
269
- />
270
- )}
271
- {context.type === 'hotel-flight' && (
272
- <Itinerary isMobileFiltersOpen={isMobileFiltersOpen} handleSetIsMobileFiltersOpen={handleSetIsMobileFiltersOpen} isLoading={isLoading} />
273
- )}
274
- {/* ---------------- Results ---------------- */}
275
- <div className="search__results">
276
- {isMobile && (
277
- <div className="search__result-row">
278
- <div className="cta cta--filter" onClick={() => setIsMobileFiltersOpen(true)}>
279
- <Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
280
- {context.translations?.filters}
281
- </div>
282
- {sortingOptions && sortingOptions.length > 0 && (
283
- <ItemPicker
284
- items={sortingOptions}
285
- selection={sortKey || undefined}
286
- label="Sort by"
287
- placeholder="Sort by"
288
- classModifier="travel-class-picker__items"
289
- onPick={handleSortChange}
290
- />
291
- )}
292
- </div>
293
- )}
294
-
295
- <div className="search__result-row">
296
- <span className="search__result-row-text">
297
- {!isLoading && (
298
- <>
299
- {results?.length ?? 4} {context.translations?.totalResultsLabel}
300
- </>
301
- )}
302
- </span>
303
- {!isMobile && sortingOptions && sortingOptions.length > 0 && (
304
- <div className="search__result-row-filter">
305
- <ItemPicker
306
- items={sortingOptions}
307
- selection={sortKey || undefined}
308
- label="Sort by"
309
- placeholder="Sort by"
310
- classModifier="travel-class-picker__items"
311
- onPick={handleSortChange}
312
- />
313
- </div>
314
- )}
315
- </div>
316
-
317
- <div className="search__results__wrapper">
318
- {context.showTabViews && <TabViews />}
319
-
320
- {context.showRoundTripResults && <RoundTripResults />}
321
-
322
- {/* {context.showFlightResults && <FlightResults isDeparture={true} />} */}
323
-
324
- {context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} context={context} />}
325
- {/* {context.showFlightAccommodationResults && <FlightAccommodationResults />} */}
326
-
327
- {/* {context.showFlightResults && <FlightResults isDeparture={false} />} */}
328
- </div>
329
- </div>
330
- </div>
331
- </div>
332
- )}
333
- </div>
334
- );
335
- };
336
-
337
- export default SearchResultsContainer;
1
+ import React, { useContext, useEffect, useState } from 'react';
2
+ import { useDispatch, useSelector } from 'react-redux';
3
+ import { SearchResultsRootState } from '../../store/search-results-store';
4
+ import SearchResultsConfigurationContext from '../../search-results-configuration-context';
5
+
6
+ import { resetFilters, setSortKey, setResults, setIsLoading, setSelectedHotel } from '../../store/search-results-slice';
7
+ import { Filter, SortingOption } from '../../types';
8
+ import useMediaQuery from '../../../shared/utils/use-media-query-util';
9
+ import Filters from '../filters/filters';
10
+ import ItemPicker from '../item-picker';
11
+
12
+ import { TideClientConfig, details, search } from '@qite/tide-client';
13
+ import {
14
+ BookingPackageDestination,
15
+ BookingPackageDetailsRequest,
16
+ BookingPackagePax,
17
+ BookingPackageRequest,
18
+ BookingPackageRequestRoom,
19
+ BookingPackageSearchRequest
20
+ } from '@qite/tide-client/build/types';
21
+ import { getDateFromParams, getNumberFromParams, getRoomsFromParams } from '../../../shared/utils/query-string-util';
22
+ import { range } from 'lodash';
23
+ import { Room } from '../../../booking-wizard/types';
24
+ import Icon from '../icon';
25
+ import Itinerary from '../itinerary';
26
+ import TabViews from '../tab-views';
27
+ import HotelAccommodationResults from '../hotel/hotel-accommodation-results';
28
+ import RoundTripResults from '../round-trip/round-trip-results';
29
+ import { enrichFiltersWithResults } from '../filters/utility';
30
+
31
+ const SearchResultsContainer: React.FC = () => {
32
+ const isMobile = useMediaQuery('(max-width: 1200px)');
33
+ const dispatch = useDispatch();
34
+ const context = useContext(SearchResultsConfigurationContext);
35
+ const { results, isLoading, filters, sortKey, selectedHotelId } = useSelector((state: SearchResultsRootState) => state.searchResults);
36
+
37
+ const [searchTrigger, setSearchTrigger] = useState(0);
38
+ const [initialFiltersSet, setInitialFiltersSet] = useState(false);
39
+ const [initialFilters, setInitialFilters] = useState<Filter[]>([]);
40
+
41
+ useEffect(() => {
42
+ const runSearch = async () => {
43
+ dispatch(setIsLoading(true));
44
+ try {
45
+ if (!context) {
46
+ return;
47
+ }
48
+
49
+ const params = new URLSearchParams(location.search);
50
+ let from = getDateFromParams(params, 'fromDate');
51
+ let to = getDateFromParams(params, 'toDate');
52
+ const rooms = getRoomsFromParams(params, 'rooms');
53
+ let country = getNumberFromParams(params, 'country');
54
+ let region = getNumberFromParams(params, 'region');
55
+ let oord = getNumberFromParams(params, 'oord');
56
+ let city = getNumberFromParams(params, 'location');
57
+ let hotel = getNumberFromParams(params, 'hotel');
58
+ let tagId = getNumberFromParams(params, 'tagId');
59
+
60
+ // temp hardcoded params
61
+ if (!from || !to) {
62
+ from = '2026-04-07';
63
+ to = '2026-04-13';
64
+ }
65
+ if (!country && !region && !oord && !city) {
66
+ region = 1;
67
+ }
68
+
69
+ if (typeof window !== 'undefined') {
70
+ window.scrollTo(0, 0);
71
+ }
72
+
73
+ let destinationId: number | null = null;
74
+ let destinationIsCountry = false;
75
+ let destinationIsRegion = false;
76
+ let destinationIsOord = false;
77
+ let destinationIsLocation = false;
78
+
79
+ if (country) {
80
+ destinationId = country;
81
+ destinationIsCountry = true;
82
+ } else if (region) {
83
+ destinationId = region;
84
+ destinationIsRegion = true;
85
+ } else if (oord) {
86
+ destinationId = oord;
87
+ destinationIsOord = true;
88
+ } else if (city) {
89
+ destinationId = city;
90
+ destinationIsLocation = true;
91
+ }
92
+
93
+ const searchRequest: BookingPackageRequest<BookingPackageSearchRequest> = {
94
+ officeId: 1,
95
+ payload: {
96
+ catalogueIds: context.tideConnection.catalogueIds ?? [],
97
+ serviceType:
98
+ context?.type === 'hotel' || context?.type === 'hotel-flight' ? 3 : context?.type === 'flight' ? 7 : context?.type === 'roundTrip' ? 1 : 0,
99
+ searchType: 0,
100
+ destination: {
101
+ id: Number(destinationId),
102
+ isCountry: destinationIsCountry,
103
+ isRegion: destinationIsRegion,
104
+ isOord: destinationIsOord,
105
+ isLocation: destinationIsLocation
106
+ } as BookingPackageDestination,
107
+ rooms: getRequestRooms(rooms),
108
+ fromDate: from,
109
+ toDate: to,
110
+ earliestFromOffset: 0,
111
+ latestToOffset: 0,
112
+ includeFlights: true,
113
+ regimeCodes:
114
+ filters
115
+ .find((f) => f.property === 'regime')
116
+ ?.options?.filter((o) => o.isChecked)
117
+ .flatMap((o) => o.value.toString()) || [],
118
+ minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
119
+ maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
120
+ useExactDates: true,
121
+ onlyCachedResults: false,
122
+ includeAllAllotments: true,
123
+ productIds: hotel ? [hotel] : [],
124
+ productTagIds: tagId ? [tagId] : []
125
+ }
126
+ };
127
+
128
+ const config: TideClientConfig = {
129
+ host: context.tideConnection.host,
130
+ apiKey: context.tideConnection.apiKey
131
+ };
132
+
133
+ const packageSearchResults = await search(config, searchRequest);
134
+
135
+ console.log('Search results', packageSearchResults);
136
+
137
+ const enrichedFilters = enrichFiltersWithResults(packageSearchResults, context.filters);
138
+ if (!initialFiltersSet) {
139
+ dispatch(resetFilters(enrichedFilters));
140
+ setInitialFilters(enrichedFilters);
141
+ setInitialFiltersSet(true);
142
+ }
143
+
144
+ dispatch(setResults({ results: packageSearchResults }));
145
+ if (packageSearchResults?.length > 0) {
146
+ dispatch(setSelectedHotel(packageSearchResults[0].productId));
147
+ }
148
+ dispatch(setIsLoading(false));
149
+ } catch (err) {
150
+ console.error('Search failed', err);
151
+ dispatch(setIsLoading(false));
152
+ }
153
+ };
154
+
155
+ runSearch();
156
+ }, [location.search, searchTrigger]);
157
+
158
+ useEffect(() => {
159
+ const fetchPackageDetails = async () => {
160
+ if (!selectedHotelId || !context) return;
161
+
162
+ try {
163
+ const config: TideClientConfig = {
164
+ host: context.tideConnection.host,
165
+ apiKey: context.tideConnection.apiKey
166
+ };
167
+
168
+ const selectedItem = results.find((r) => r.productId === selectedHotelId);
169
+ if (!selectedItem) return;
170
+
171
+ const params = new URLSearchParams(location.search);
172
+ const rooms = getRoomsFromParams(params, 'rooms');
173
+ const requestRooms = getRequestRooms(rooms);
174
+
175
+ const detailsRequest: BookingPackageRequest<BookingPackageDetailsRequest> = {
176
+ officeId: 1,
177
+ payload: {
178
+ catalogueId: selectedItem.catalogueId,
179
+ rooms: requestRooms,
180
+ searchType: 0, // same as search
181
+ productCode: selectedItem.code,
182
+ fromDate: selectedItem.fromDate,
183
+ toDate: selectedItem.toDate,
184
+ includeFlights: true,
185
+ includeHotels: true,
186
+ includePaxTypes: true,
187
+ checkExternalAvailability: true,
188
+ expectedPrice: selectedItem.price,
189
+ duration: null,
190
+ preNights: null,
191
+ postNights: null
192
+ }
193
+ };
194
+
195
+ const detailsResponse = await details(config, detailsRequest);
196
+
197
+ console.log('Package details:', detailsResponse);
198
+
199
+ // TODO: store flights / details in redux
200
+ // dispatch(setSelectedHotelDetails(details));
201
+ } catch (err) {
202
+ console.error('Failed to fetch package details', err);
203
+ }
204
+ };
205
+
206
+ fetchPackageDetails();
207
+ }, [selectedHotelId]);
208
+
209
+ const getRequestRooms = (rooms: Room[] | null) => {
210
+ if (!rooms) {
211
+ // Fall back to 2 adults
212
+ var room = { index: 0, pax: [] } as BookingPackageRequestRoom;
213
+ range(0, 2).forEach(() => {
214
+ room.pax.push({
215
+ age: 30
216
+ } as BookingPackagePax);
217
+ });
218
+ return [room];
219
+ }
220
+
221
+ const requestRooms = rooms?.map((x, i) => {
222
+ var room = { index: i, pax: [] } as BookingPackageRequestRoom;
223
+ range(0, x.adults).forEach(() => {
224
+ room.pax.push({
225
+ age: 30
226
+ } as BookingPackagePax);
227
+ });
228
+ x.childAges.forEach((x) => {
229
+ room.pax.push({
230
+ age: x
231
+ } as BookingPackagePax);
232
+ });
233
+ return room;
234
+ });
235
+
236
+ return requestRooms;
237
+ };
238
+
239
+ const [isMobileFiltersOpen, setIsMobileFiltersOpen] = useState(false);
240
+
241
+ const handleSortChange = (newSortKey: string) => {
242
+ dispatch(setSortKey(newSortKey));
243
+ };
244
+
245
+ const handleSetIsMobileFiltersOpen = () => {
246
+ setIsMobileFiltersOpen(!isMobileFiltersOpen);
247
+ };
248
+
249
+ useEffect(() => {
250
+ if (typeof document !== 'undefined') {
251
+ document.body.classList.toggle('has-overlay', isMobileFiltersOpen);
252
+ }
253
+ }, [isMobileFiltersOpen]);
254
+
255
+ const sortingOptions: SortingOption[] = [
256
+ { key: 'price-asc', label: 'Price: Low to High' },
257
+ { key: 'price-desc', label: 'Price: High to Low' },
258
+ { key: 'departure-date', label: 'Departure Date' }
259
+ ];
260
+
261
+ return (
262
+ <div id="tide-booking" className="search__bg">
263
+ {context && (
264
+ <div className="search">
265
+ <div className="search__container">
266
+ {context.showFilters && (
267
+ <Filters
268
+ filters={filters}
269
+ isMobileFiltersOpen={isMobileFiltersOpen}
270
+ handleSetIsMobileFiltersOpen={handleSetIsMobileFiltersOpen}
271
+ handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
272
+ isLoading={isLoading}
273
+ />
274
+ )}
275
+ {context.type === 'hotel-flight' && (
276
+ <Itinerary isMobileFiltersOpen={isMobileFiltersOpen} handleSetIsMobileFiltersOpen={handleSetIsMobileFiltersOpen} isLoading={isLoading} />
277
+ )}
278
+ {/* ---------------- Results ---------------- */}
279
+ <div className="search__results">
280
+ {isMobile && (
281
+ <div className="search__result-row">
282
+ <div className="cta cta--filter" onClick={() => setIsMobileFiltersOpen(true)}>
283
+ <Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
284
+ {context.translations?.filters}
285
+ </div>
286
+ {sortingOptions && sortingOptions.length > 0 && (
287
+ <ItemPicker
288
+ items={sortingOptions}
289
+ selection={sortKey || undefined}
290
+ label="Sort by"
291
+ placeholder="Sort by"
292
+ classModifier="travel-class-picker__items"
293
+ onPick={handleSortChange}
294
+ />
295
+ )}
296
+ </div>
297
+ )}
298
+
299
+ <div className="search__result-row">
300
+ <span className="search__result-row-text">
301
+ {!isLoading && (
302
+ <>
303
+ {results?.length ?? 4} {context.translations?.totalResultsLabel}
304
+ </>
305
+ )}
306
+ </span>
307
+ {!isMobile && sortingOptions && sortingOptions.length > 0 && (
308
+ <div className="search__result-row-filter">
309
+ <ItemPicker
310
+ items={sortingOptions}
311
+ selection={sortKey || undefined}
312
+ label="Sort by"
313
+ placeholder="Sort by"
314
+ classModifier="travel-class-picker__items"
315
+ onPick={handleSortChange}
316
+ />
317
+ </div>
318
+ )}
319
+ </div>
320
+
321
+ <div className="search__results__wrapper">
322
+ {context.showTabViews && <TabViews />}
323
+
324
+ {context.showRoundTripResults && <RoundTripResults />}
325
+
326
+ {/* {context.showFlightResults && <FlightResults isDeparture={true} />} */}
327
+
328
+ {context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} context={context} />}
329
+ {/* {context.showFlightAccommodationResults && <FlightAccommodationResults />} */}
330
+
331
+ {/* {context.showFlightResults && <FlightResults isDeparture={false} />} */}
332
+ </div>
333
+ </div>
334
+ </div>
335
+ </div>
336
+ )}
337
+ </div>
338
+ );
339
+ };
340
+
341
+ export default SearchResultsContainer;