@qite/tide-booking-component 1.4.53 → 1.4.54
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/index.js +530 -102
- package/build/build-esm/index.js +530 -102
- package/package.json +1 -1
- package/src/qsm/components/QSMContainer/qsm-container.tsx +32 -34
- package/src/search-results/components/search-results-container/search-results-container.tsx +48 -41
- package/src/search-results/features/flights/flight-search-results-self-contained.tsx +1 -1
package/package.json
CHANGED
|
@@ -99,7 +99,6 @@ const QSMContainer: React.FC = () => {
|
|
|
99
99
|
|
|
100
100
|
// Filter out undefined fields before passing to addSearchFieldsToPayload
|
|
101
101
|
const searchFields = [departureAirport, destinationAirport, returnAirport, destination].filter((field): field is BaseFieldConfig => field !== undefined);
|
|
102
|
-
|
|
103
102
|
addSearchFieldsToPayload(payload, searchFields, qsmState);
|
|
104
103
|
onSubmit(payload);
|
|
105
104
|
console.log('Submitted QSM data:', payload);
|
|
@@ -219,40 +218,39 @@ const QSMContainer: React.FC = () => {
|
|
|
219
218
|
</button>
|
|
220
219
|
</div>
|
|
221
220
|
<div className="qsm__filter">
|
|
222
|
-
{qsmType === 'hotel' ||
|
|
223
|
-
|
|
224
|
-
<div className="radiobutton
|
|
225
|
-
<
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
<
|
|
241
|
-
<
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
</label>
|
|
253
|
-
</div>
|
|
221
|
+
{(qsmType === 'hotel' || qsmType === 'hotel-flight') && (
|
|
222
|
+
<div className="radiobutton-group qsm__filter__inputgroup">
|
|
223
|
+
<div className="radiobutton">
|
|
224
|
+
<label className="radiobutton__label">
|
|
225
|
+
<input
|
|
226
|
+
type="radio"
|
|
227
|
+
name="numberOfAccommodations"
|
|
228
|
+
// onChange={handleMainBookerChange}
|
|
229
|
+
// onBlur={formik.handleBlur}
|
|
230
|
+
value=""
|
|
231
|
+
checked={true}
|
|
232
|
+
readOnly
|
|
233
|
+
className="radiobutton__input"
|
|
234
|
+
/>
|
|
235
|
+
<span>{translations.QSM.ONE_ACCOMMODATION}</span>
|
|
236
|
+
</label>
|
|
237
|
+
</div>
|
|
238
|
+
<div className="radiobutton">
|
|
239
|
+
<label className="radiobutton__label">
|
|
240
|
+
<input
|
|
241
|
+
type="radio"
|
|
242
|
+
name="numberOfAccommodations"
|
|
243
|
+
// onChange={handleMainBookerChange}
|
|
244
|
+
// onBlur={formik.handleBlur}
|
|
245
|
+
value=""
|
|
246
|
+
className="radiobutton__input"
|
|
247
|
+
disabled={true}
|
|
248
|
+
/>
|
|
249
|
+
<span>{translations.QSM.MULTIPLE_ACCOMMODATIONS}</span>
|
|
250
|
+
</label>
|
|
254
251
|
</div>
|
|
255
|
-
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
256
254
|
{qsmType === 'flight' && (
|
|
257
255
|
<div className="radiobutton-group qsm__filter__inputgroup">
|
|
258
256
|
{allowOneWay && (
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
setEntry,
|
|
14
14
|
setFlyInIsOpen
|
|
15
15
|
} from '../../store/search-results-slice';
|
|
16
|
-
import { Filter, SortingOption } from '../../types';
|
|
16
|
+
import { Filter, SortByType, SortingOption } from '../../types';
|
|
17
17
|
import useMediaQuery from '../../../shared/utils/use-media-query-util';
|
|
18
18
|
import ItemPicker from '../item-picker';
|
|
19
19
|
|
|
@@ -42,6 +42,7 @@ import FlightResults from '../flight/flight-results';
|
|
|
42
42
|
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
43
43
|
import { FlightSearchProvider } from '../flight/flight-search-context';
|
|
44
44
|
import FlightResultsContainer from './flight-search-results';
|
|
45
|
+
import Filters from '../filters/filters';
|
|
45
46
|
|
|
46
47
|
const SearchResultsContainer: React.FC = () => {
|
|
47
48
|
const dispatch = useDispatch();
|
|
@@ -63,10 +64,11 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
63
64
|
|
|
64
65
|
const panelRef = useRef<HTMLDivElement | null>(null);
|
|
65
66
|
|
|
66
|
-
const
|
|
67
|
-
{
|
|
68
|
-
{
|
|
69
|
-
{
|
|
67
|
+
const sortByTypes: SortByType[] = [
|
|
68
|
+
{ direction: 'asc', label: 'price' } as SortByType,
|
|
69
|
+
{ direction: 'desc', label: 'price' } as SortByType,
|
|
70
|
+
{ direction: 'asc', label: 'departure' } as SortByType,
|
|
71
|
+
{ direction: 'desc', label: 'departure' } as SortByType
|
|
70
72
|
];
|
|
71
73
|
|
|
72
74
|
const handleFlyInToggle = (isOpen: boolean) => {
|
|
@@ -144,7 +146,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
144
146
|
return searchRequest;
|
|
145
147
|
};
|
|
146
148
|
|
|
147
|
-
const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> => {
|
|
149
|
+
const buildSearchFromQueryParams = (params: URLSearchParams): BookingPackageRequest<BookingPackageSearchRequest> | null => {
|
|
148
150
|
let from = getDateFromParams(params, 'fromDate');
|
|
149
151
|
let to = getDateFromParams(params, 'toDate');
|
|
150
152
|
const rooms = getRoomsFromParams(params, 'rooms');
|
|
@@ -157,11 +159,9 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
157
159
|
|
|
158
160
|
// temp hardcoded params
|
|
159
161
|
if (!from || !to) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (!country && !region && !oord && !city) {
|
|
164
|
-
region = 1;
|
|
162
|
+
console.error('Missing fromDate or toDate in query params, using default values');
|
|
163
|
+
|
|
164
|
+
return null;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
if (typeof window !== 'undefined') {
|
|
@@ -206,14 +206,14 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
206
206
|
toDate: to,
|
|
207
207
|
earliestFromOffset: 0,
|
|
208
208
|
latestToOffset: 0,
|
|
209
|
-
includeFlights: true,
|
|
210
|
-
regimeCodes:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
|
|
216
|
-
maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
|
|
209
|
+
includeFlights: context!.type === 'hotel-flight' ? true : false,
|
|
210
|
+
// regimeCodes:
|
|
211
|
+
// filters
|
|
212
|
+
// .find((f) => f.property === 'regime')
|
|
213
|
+
// ?.options?.filter((o) => o.isChecked)
|
|
214
|
+
// .flatMap((o) => o.value.toString()) || [],
|
|
215
|
+
// minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
|
|
216
|
+
// maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
|
|
217
217
|
useExactDates: true,
|
|
218
218
|
onlyCachedResults: false,
|
|
219
219
|
includeAllAllotments: true,
|
|
@@ -290,7 +290,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
290
290
|
|
|
291
291
|
// seperate Search
|
|
292
292
|
useEffect(() => {
|
|
293
|
-
const
|
|
293
|
+
const runHotelSearch = async () => {
|
|
294
294
|
dispatch(setIsLoading(true));
|
|
295
295
|
try {
|
|
296
296
|
if (!context) {
|
|
@@ -315,7 +315,13 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
315
315
|
dispatch(setEntry({ entry: entryLight }));
|
|
316
316
|
searchRequest = buildSearchFromEntry(entryLight);
|
|
317
317
|
} else {
|
|
318
|
-
|
|
318
|
+
const rq = buildSearchFromQueryParams(params);
|
|
319
|
+
|
|
320
|
+
if (!rq) {
|
|
321
|
+
throw new Error('Invalid search parameters');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
searchRequest = rq;
|
|
319
325
|
}
|
|
320
326
|
|
|
321
327
|
const packageSearchResults = await search(config, searchRequest);
|
|
@@ -350,8 +356,8 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
350
356
|
};
|
|
351
357
|
|
|
352
358
|
if (!context?.showMockup) {
|
|
353
|
-
if (context?.type === 'hotel-flight') {
|
|
354
|
-
|
|
359
|
+
if (context?.type === 'hotel-flight' || context?.type === 'hotel') {
|
|
360
|
+
runHotelSearch();
|
|
355
361
|
}
|
|
356
362
|
}
|
|
357
363
|
}, [location.search, searchTrigger]);
|
|
@@ -393,7 +399,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
393
399
|
productCode: selectedItem.code,
|
|
394
400
|
fromDate: selectedItem.fromDate,
|
|
395
401
|
toDate: selectedItem.toDate,
|
|
396
|
-
includeFlights: true,
|
|
402
|
+
includeFlights: context!.type === 'hotel-flight' ? true : false,
|
|
397
403
|
includeHotels: true,
|
|
398
404
|
includePaxTypes: true,
|
|
399
405
|
checkExternalAvailability: true,
|
|
@@ -434,24 +440,26 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
434
440
|
<FlyIn srpType={context.type} isOpen={flyInIsOpen} setIsOpen={handleFlyInToggle} onPanelRef={(el) => (panelRef.current = el)} />
|
|
435
441
|
</FlightSearchProvider>
|
|
436
442
|
)}
|
|
437
|
-
{context.type === 'hotel-flight' && (
|
|
443
|
+
{(context.type === 'hotel-flight' || context.type === 'hotel' || context.type === 'roundTrip') && (
|
|
438
444
|
<>
|
|
439
|
-
{
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
445
|
+
{context.type != 'hotel-flight' && context.showFilters && (
|
|
446
|
+
<Filters
|
|
447
|
+
filters={filters}
|
|
448
|
+
isOpen={filtersOpen}
|
|
449
|
+
handleSetIsOpen={() => setFiltersOpen(!filtersOpen)}
|
|
450
|
+
handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
|
|
451
|
+
isLoading={isLoading}
|
|
452
|
+
/>
|
|
453
|
+
)}
|
|
454
|
+
{context.type === 'hotel-flight' && (
|
|
455
|
+
<Itinerary isOpen={itineraryOpen} handleSetIsOpen={() => setItineraryOpen(!itineraryOpen)} isLoading={isLoading} />
|
|
456
|
+
)}
|
|
449
457
|
{/* ---------------- Results ---------------- */}
|
|
450
458
|
<div className="search__results">
|
|
451
459
|
{isMobile && (
|
|
452
460
|
<div className="search__result-row">
|
|
453
461
|
<div className="search__results__actions">
|
|
454
|
-
{context.showFilters && (
|
|
462
|
+
{context.type != 'hotel-flight' && context.showFilters && (
|
|
455
463
|
<div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
|
|
456
464
|
<Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
|
|
457
465
|
{translations.SRP.FILTERS}
|
|
@@ -464,9 +472,9 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
464
472
|
</div>
|
|
465
473
|
)}
|
|
466
474
|
</div>
|
|
467
|
-
{
|
|
475
|
+
{sortByTypes && sortByTypes.length > 0 && (
|
|
468
476
|
<ItemPicker
|
|
469
|
-
items={
|
|
477
|
+
items={sortByTypes}
|
|
470
478
|
selection={sortKey || undefined}
|
|
471
479
|
label={translations.SRP.SORTBY}
|
|
472
480
|
placeholder={translations.SRP.SORTBY}
|
|
@@ -476,7 +484,6 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
476
484
|
)}
|
|
477
485
|
</div>
|
|
478
486
|
)}
|
|
479
|
-
|
|
480
487
|
<div className="search__result-row">
|
|
481
488
|
<span className="search__result-row-text">
|
|
482
489
|
{!isLoading && (
|
|
@@ -485,10 +492,10 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
485
492
|
</>
|
|
486
493
|
)}
|
|
487
494
|
</span>
|
|
488
|
-
{!isMobile &&
|
|
495
|
+
{!isMobile && sortByTypes && sortByTypes.length > 0 && (
|
|
489
496
|
<div className="search__result-row-filter">
|
|
490
497
|
<ItemPicker
|
|
491
|
-
items={
|
|
498
|
+
items={sortByTypes}
|
|
492
499
|
selection={sortKey || undefined}
|
|
493
500
|
label={translations.SRP.SORTBY}
|
|
494
501
|
placeholder={translations.SRP.SORTBY}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
-
import { Filter, SearchResult, SearchResultsConfiguration
|
|
2
|
+
import { Filter, SearchResult, SearchResultsConfiguration } from '../../types';
|
|
3
3
|
import SearchResults from '../..';
|
|
4
4
|
import { Footer, Navbar } from '../../../../src';
|
|
5
5
|
import { TideLogo, language, languages, topLinks, navItems } from '../../../../src/content/navbar/placeholderData';
|