@qite/tide-booking-component 1.4.74 → 1.4.76
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 +148 -86
- package/build/build-cjs/src/qsm/store/qsm-slice.d.ts +3 -3
- package/build/build-cjs/src/qsm/types.d.ts +2 -2
- package/build/build-cjs/src/search-results/types.d.ts +2 -2
- package/build/build-cjs/src/shared/components/flyin/flyin.d.ts +2 -2
- package/build/build-cjs/src/shared/types.d.ts +13 -12
- package/build/build-esm/index.js +145 -86
- package/build/build-esm/src/qsm/store/qsm-slice.d.ts +3 -3
- package/build/build-esm/src/qsm/types.d.ts +2 -2
- package/build/build-esm/src/search-results/types.d.ts +2 -2
- package/build/build-esm/src/shared/components/flyin/flyin.d.ts +2 -2
- package/build/build-esm/src/shared/types.d.ts +13 -12
- package/package.json +2 -2
- package/src/content/features/content-page/content-page-self-contained.tsx +2 -2
- package/src/qsm/components/QSMContainer/qsm-container.tsx +59 -29
- package/src/qsm/components/travel-input/index.tsx +2 -1
- package/src/qsm/components/travel-input-group/index.tsx +2 -1
- package/src/qsm/qsm-configuration-context.ts +2 -1
- package/src/qsm/store/qsm-slice.ts +4 -4
- package/src/qsm/types.ts +2 -2
- package/src/search-results/components/filters/utility.tsx +10 -10
- package/src/search-results/components/search-results-container/flight-search-results.tsx +3 -2
- package/src/search-results/components/search-results-container/search-results-container.tsx +39 -18
- package/src/search-results/features/flights/flight-search-results-self-contained.tsx +2 -2
- package/src/search-results/features/hotels/hotel-flight-search-results-self-contained.tsx +2 -2
- package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +2 -2
- package/src/search-results/features/roundtrips/roundtrip-search-results-self-contained.tsx +2 -2
- package/src/search-results/types.ts +2 -2
- package/src/shared/components/flyin/flyin.tsx +7 -5
- package/src/shared/types.ts +13 -12
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FlightSearchResponseItem } from '@qite/tide-client';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { PortalQsmType } from '../shared/types';
|
|
4
4
|
export type FlightSelectionMode = 'paired' | 'independent';
|
|
5
5
|
export interface SearchResultsConfiguration {
|
|
6
|
-
type:
|
|
6
|
+
type: PortalQsmType;
|
|
7
7
|
tideConnection: {
|
|
8
8
|
host: string;
|
|
9
9
|
apiKey: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { PortalQsmType } from '../../types';
|
|
3
3
|
type FlyInProps = {
|
|
4
4
|
title: string;
|
|
5
|
-
srpType:
|
|
5
|
+
srpType: PortalQsmType;
|
|
6
6
|
isOpen: boolean;
|
|
7
7
|
setIsOpen: (open: boolean) => void;
|
|
8
8
|
className?: string;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
export declare enum PortalQsmType {
|
|
3
|
+
Multidestination = 0,
|
|
4
|
+
Accommodation = 1,
|
|
5
|
+
AccommodationAndFlight = 2,
|
|
6
|
+
Flight = 3,
|
|
7
|
+
RoundTrip = 4,
|
|
8
|
+
GroupTour = 5,
|
|
9
|
+
Package = 6,
|
|
10
|
+
Ticket = 7,
|
|
11
|
+
Car = 8,
|
|
12
|
+
Transfer = 9,
|
|
13
|
+
Cruise = 10
|
|
14
|
+
}
|
|
14
15
|
export interface ApiSettingsState {
|
|
15
16
|
apiUrl: string;
|
|
16
17
|
apiKey: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qite/tide-booking-component",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.76",
|
|
4
4
|
"description": "React Booking wizard & Booking product component for Tide",
|
|
5
5
|
"main": "build/build-cjs/index.js",
|
|
6
6
|
"types": "build/build-cjs/src/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@jsonurl/jsonurl": "^1.1.4",
|
|
31
31
|
"@popperjs/core": "^2.10.2",
|
|
32
|
-
"@qite/tide-client": "^1.1.
|
|
32
|
+
"@qite/tide-client": "^1.1.146",
|
|
33
33
|
"@reduxjs/toolkit": "^2.8.2",
|
|
34
34
|
"@rollup/plugin-commonjs": "^19.0.1",
|
|
35
35
|
"@rollup/plugin-json": "^4.1.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Navbar } from '../../../../src';
|
|
2
|
+
import { Navbar, PortalQsmType } from '../../../../src';
|
|
3
3
|
import { TideLogo, language, languages, topLinks, navItems } from '../../../../src/content/navbar/placeholderData';
|
|
4
4
|
import Icon from '../../components/icon';
|
|
5
5
|
import ContactForm from '../../components/contact';
|
|
@@ -53,7 +53,7 @@ const travelClasses = [
|
|
|
53
53
|
];
|
|
54
54
|
|
|
55
55
|
let configuration: QSMConfiguration = {
|
|
56
|
-
type:
|
|
56
|
+
type: PortalQsmType.Accommodation,
|
|
57
57
|
askTravelers: true,
|
|
58
58
|
askNationality: true,
|
|
59
59
|
askTravelClass: true,
|
|
@@ -17,7 +17,7 @@ import { DateRange } from '../../../booking-product/types';
|
|
|
17
17
|
import { QSMState, setFromDate, setSelectedQsmType, setToDate, setTripType } from '../../store/qsm-slice';
|
|
18
18
|
import { BaseFieldConfig, DoubleFieldConfig } from '../../types';
|
|
19
19
|
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
20
|
-
import {
|
|
20
|
+
import { PortalQsmType } from '../../../shared/types';
|
|
21
21
|
|
|
22
22
|
const QSMContainer: React.FC = () => {
|
|
23
23
|
const dispatch = useDispatch();
|
|
@@ -50,7 +50,7 @@ const QSMContainer: React.FC = () => {
|
|
|
50
50
|
let startDate = addMonths(new Date(), 1);
|
|
51
51
|
let endDate = addDays(startDate, 7);
|
|
52
52
|
|
|
53
|
-
if (qsmType ===
|
|
53
|
+
if (qsmType === PortalQsmType.GroupTour) {
|
|
54
54
|
startDate = new Date();
|
|
55
55
|
endDate = addYears(startDate, 1);
|
|
56
56
|
}
|
|
@@ -77,13 +77,13 @@ const QSMContainer: React.FC = () => {
|
|
|
77
77
|
dispatch(setTripType(value));
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
const handleQsmTypeChange = (value:
|
|
80
|
+
const handleQsmTypeChange = (value: PortalQsmType) => {
|
|
81
81
|
dispatch(setSelectedQsmType(value));
|
|
82
82
|
|
|
83
83
|
let startDate = addMonths(new Date(), 1);
|
|
84
84
|
let endDate = addDays(startDate, 7);
|
|
85
85
|
|
|
86
|
-
if (value ===
|
|
86
|
+
if (value === PortalQsmType.GroupTour) {
|
|
87
87
|
startDate = new Date();
|
|
88
88
|
endDate = addYears(startDate, 1);
|
|
89
89
|
}
|
|
@@ -110,7 +110,7 @@ const QSMContainer: React.FC = () => {
|
|
|
110
110
|
tripType
|
|
111
111
|
} as any;
|
|
112
112
|
|
|
113
|
-
if (askRooms && qsmType !==
|
|
113
|
+
if (askRooms && qsmType !== PortalQsmType.Flight) {
|
|
114
114
|
payload.rooms = rooms;
|
|
115
115
|
} else {
|
|
116
116
|
payload.travelers = { adults, kids, babies };
|
|
@@ -186,14 +186,17 @@ const QSMContainer: React.FC = () => {
|
|
|
186
186
|
<div className="qsm__tabs">
|
|
187
187
|
<button
|
|
188
188
|
type="button"
|
|
189
|
-
className={`qsm__tab ${qsmType ==
|
|
190
|
-
onClick={() => handleQsmTypeChange(
|
|
189
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Multidestination ? 'qsm__tab--active' : ''}`}
|
|
190
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Multidestination)}>
|
|
191
191
|
<span className="qsm__tab__icons">
|
|
192
192
|
<Icon name="ui-location" height={16} />
|
|
193
193
|
</span>
|
|
194
194
|
{translations.QSM.MULTIDESTINATION}
|
|
195
195
|
</button>
|
|
196
|
-
<button
|
|
196
|
+
<button
|
|
197
|
+
type="button"
|
|
198
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Package ? 'qsm__tab--active' : ''}`}
|
|
199
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Package)}>
|
|
197
200
|
<span className="qsm__tab__icons">
|
|
198
201
|
<Icon name="ui-suitcase" height={16} />
|
|
199
202
|
</span>
|
|
@@ -201,8 +204,8 @@ const QSMContainer: React.FC = () => {
|
|
|
201
204
|
</button>
|
|
202
205
|
<button
|
|
203
206
|
type="button"
|
|
204
|
-
className={`qsm__tab ${qsmType ==
|
|
205
|
-
onClick={() => handleQsmTypeChange(
|
|
207
|
+
className={`qsm__tab ${qsmType == PortalQsmType.AccommodationAndFlight ? 'qsm__tab--active' : ''}`}
|
|
208
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.AccommodationAndFlight)}>
|
|
206
209
|
<span className="qsm__tab__icons">
|
|
207
210
|
<Icon name="ui-backforward" height={14} />
|
|
208
211
|
+
|
|
@@ -210,43 +213,64 @@ const QSMContainer: React.FC = () => {
|
|
|
210
213
|
</span>
|
|
211
214
|
{translations.QSM.TRANSPORT_HOTEL}
|
|
212
215
|
</button>
|
|
213
|
-
<button
|
|
216
|
+
<button
|
|
217
|
+
type="button"
|
|
218
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Accommodation ? 'qsm__tab--active' : ''}`}
|
|
219
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Accommodation)}>
|
|
214
220
|
<span className="qsm__tab__icons">
|
|
215
221
|
<Icon name="ui-bed" height={16} />
|
|
216
222
|
</span>
|
|
217
223
|
{translations.QSM.ACCOMMODATION}
|
|
218
224
|
</button>
|
|
219
|
-
<button
|
|
225
|
+
<button
|
|
226
|
+
type="button"
|
|
227
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Flight ? 'qsm__tab--active' : ''}`}
|
|
228
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Flight)}>
|
|
220
229
|
<span className="qsm__tab__icons">
|
|
221
230
|
<Icon name="ui-flight" height={16} />
|
|
222
231
|
</span>
|
|
223
232
|
{translations.QSM.TRANSPORTS}
|
|
224
233
|
</button>
|
|
225
|
-
<button
|
|
234
|
+
<button
|
|
235
|
+
type="button"
|
|
236
|
+
className={`qsm__tab ${qsmType == PortalQsmType.GroupTour ? 'qsm__tab--active' : ''}`}
|
|
237
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.GroupTour)}>
|
|
226
238
|
<span className="qsm__tab__icons">
|
|
227
239
|
<Icon name="ui-group" height={16} />
|
|
228
240
|
</span>
|
|
229
241
|
{translations.QSM.GROUP_TOUR}
|
|
230
242
|
</button>
|
|
231
|
-
<button
|
|
243
|
+
<button
|
|
244
|
+
type="button"
|
|
245
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Ticket ? 'qsm__tab--active' : ''}`}
|
|
246
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Ticket)}>
|
|
232
247
|
<span className="qsm__tab__icons">
|
|
233
248
|
<Icon name="ui-ticket" height={16} />
|
|
234
249
|
</span>
|
|
235
250
|
{translations.QSM.TICKET_ONLY}
|
|
236
251
|
</button>
|
|
237
|
-
<button
|
|
252
|
+
<button
|
|
253
|
+
type="button"
|
|
254
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Car ? 'qsm__tab--active' : ''}`}
|
|
255
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Car)}>
|
|
238
256
|
<span className="qsm__tab__icons">
|
|
239
257
|
<Icon name="ui-car" height={16} />
|
|
240
258
|
</span>
|
|
241
259
|
{translations.QSM.RENT_A_CAR}
|
|
242
260
|
</button>
|
|
243
|
-
<button
|
|
261
|
+
<button
|
|
262
|
+
type="button"
|
|
263
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Transfer ? 'qsm__tab--active' : ''}`}
|
|
264
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Transfer)}>
|
|
244
265
|
<span className="qsm__tab__icons">
|
|
245
266
|
<Icon name="ui-backforward" height={16} />
|
|
246
267
|
</span>
|
|
247
268
|
{translations.QSM.TRANSFERS}
|
|
248
269
|
</button>
|
|
249
|
-
<button
|
|
270
|
+
<button
|
|
271
|
+
type="button"
|
|
272
|
+
className={`qsm__tab ${qsmType == PortalQsmType.Cruise ? 'qsm__tab--active' : ''}`}
|
|
273
|
+
onClick={() => handleQsmTypeChange(PortalQsmType.Cruise)}>
|
|
250
274
|
<span className="qsm__tab__icons">
|
|
251
275
|
<Icon name="ui-ship" height={16} />
|
|
252
276
|
</span>
|
|
@@ -254,7 +278,7 @@ const QSMContainer: React.FC = () => {
|
|
|
254
278
|
</button>
|
|
255
279
|
</div>
|
|
256
280
|
<div className="qsm__filter">
|
|
257
|
-
{(qsmType ===
|
|
281
|
+
{(qsmType === PortalQsmType.Accommodation || qsmType === PortalQsmType.AccommodationAndFlight || qsmType === PortalQsmType.GroupTour) && (
|
|
258
282
|
<div className="radiobutton-group qsm__filter__inputgroup">
|
|
259
283
|
<div className="radiobutton">
|
|
260
284
|
<label className="radiobutton__label">
|
|
@@ -287,7 +311,7 @@ const QSMContainer: React.FC = () => {
|
|
|
287
311
|
</div>
|
|
288
312
|
</div>
|
|
289
313
|
)}
|
|
290
|
-
{qsmType ===
|
|
314
|
+
{qsmType === PortalQsmType.Flight && (
|
|
291
315
|
<div className="radiobutton-group qsm__filter__inputgroup">
|
|
292
316
|
{allowOneWay && (
|
|
293
317
|
<div className="radiobutton">
|
|
@@ -339,26 +363,32 @@ const QSMContainer: React.FC = () => {
|
|
|
339
363
|
</div>
|
|
340
364
|
)}
|
|
341
365
|
<div className="qsm__filter__classgroup">
|
|
342
|
-
{qsmType !==
|
|
343
|
-
qsmType !==
|
|
344
|
-
qsmType !==
|
|
345
|
-
qsmType !==
|
|
346
|
-
qsmType !==
|
|
347
|
-
qsmType !==
|
|
366
|
+
{qsmType !== PortalQsmType.Accommodation &&
|
|
367
|
+
qsmType !== PortalQsmType.Car &&
|
|
368
|
+
qsmType !== PortalQsmType.Ticket &&
|
|
369
|
+
qsmType !== PortalQsmType.Cruise &&
|
|
370
|
+
qsmType !== PortalQsmType.Transfer &&
|
|
371
|
+
qsmType !== PortalQsmType.GroupTour &&
|
|
348
372
|
askTravelClass && <TravelClassPicker />}
|
|
349
|
-
{qsmType !==
|
|
373
|
+
{qsmType !== PortalQsmType.Multidestination &&
|
|
374
|
+
qsmType !== PortalQsmType.Car &&
|
|
375
|
+
qsmType !== PortalQsmType.Flight &&
|
|
376
|
+
qsmType !== PortalQsmType.Transfer &&
|
|
377
|
+
askTravelType && <TravelTypePicker />}
|
|
350
378
|
{askNationality && <TravelNationalityPicker />}
|
|
351
379
|
</div>
|
|
352
380
|
</div>
|
|
353
381
|
<div className="qsm__input-group">
|
|
354
382
|
{/* TODO, determine which fields to show for what type of QSM */}
|
|
355
|
-
{(qsmType ==
|
|
383
|
+
{(qsmType == PortalQsmType.Flight || qsmType == PortalQsmType.AccommodationAndFlight) && originDestinationField && (
|
|
356
384
|
<DoubleSearchInputGroup fieldConfig={originDestinationField} showReverse={originDestinationField.showReverse} />
|
|
357
385
|
)}
|
|
358
|
-
{qsmType ==
|
|
386
|
+
{qsmType == PortalQsmType.Flight && tripType == 'openjaw' && openJawReturnDestinationField && (
|
|
359
387
|
<DoubleSearchInputGroup fieldConfig={openJawReturnDestinationField} showReverse={openJawReturnDestinationField.showReverse} />
|
|
360
388
|
)}
|
|
361
|
-
{(qsmType ==
|
|
389
|
+
{(qsmType == PortalQsmType.Accommodation || qsmType == PortalQsmType.AccommodationAndFlight || qsmType == PortalQsmType.GroupTour) && destination && (
|
|
390
|
+
<SearchInputGroup fieldConfig={destination} />
|
|
391
|
+
)}
|
|
362
392
|
|
|
363
393
|
<Dates value={dateRange} onChange={handleDateChange} />
|
|
364
394
|
|
|
@@ -7,13 +7,14 @@ import { getTranslations } from '../../../shared/utils/localization-util';
|
|
|
7
7
|
import TravelClassPicker from '../travel-class-picker';
|
|
8
8
|
import TravelTypePicker from '../travel-type-picker';
|
|
9
9
|
import Icon from '../icon';
|
|
10
|
+
import { PortalQsmType } from '../../../shared/types';
|
|
10
11
|
|
|
11
12
|
const TravelInput: React.FC = () => {
|
|
12
13
|
const dispatch = useDispatch();
|
|
13
14
|
const { askRooms, maxTravelers, defaultTravelers, maxChildAge, maxInfantAge, askTravelType, askTravelClass, languageCode } =
|
|
14
15
|
useContext(QSMConfigurationContext);
|
|
15
16
|
const { adults, kids, babies, rooms, qsmType } = useSelector((state: QSMRootState) => state.qsm);
|
|
16
|
-
const areTravelersInRooms = qsmType !==
|
|
17
|
+
const areTravelersInRooms = qsmType !== PortalQsmType.Flight && askRooms;
|
|
17
18
|
|
|
18
19
|
const translations = getTranslations(languageCode ?? 'en-GB');
|
|
19
20
|
|
|
@@ -7,6 +7,7 @@ import { QSMRootState } from '../../store/qsm-store';
|
|
|
7
7
|
import QSMConfigurationContext from '../../qsm-configuration-context';
|
|
8
8
|
import Icon from '../icon';
|
|
9
9
|
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
10
|
+
import { PortalQsmType } from '../../../shared/types';
|
|
10
11
|
|
|
11
12
|
const selectTravelerSummary = (state: QSMRootState, areTravelersInRooms: boolean | undefined) => {
|
|
12
13
|
const { adults, kids, babies, rooms, selectedTravelType } = state.qsm;
|
|
@@ -35,7 +36,7 @@ const TravelInputGroup: React.FC = () => {
|
|
|
35
36
|
|
|
36
37
|
const translations = getTranslations(languageCode ?? 'en-GB');
|
|
37
38
|
|
|
38
|
-
const areTravelersInRooms = qsmType !==
|
|
39
|
+
const areTravelersInRooms = qsmType !== PortalQsmType.Flight && askRooms;
|
|
39
40
|
|
|
40
41
|
const initDone = useRef(false);
|
|
41
42
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { QSMConfiguration } from './types';
|
|
3
|
+
import { PortalQsmType } from '../shared/types';
|
|
3
4
|
|
|
4
5
|
const QSMConfigurationContext = React.createContext<QSMConfiguration>({
|
|
5
|
-
type:
|
|
6
|
+
type: PortalQsmType.Accommodation,
|
|
6
7
|
askTravelers: false,
|
|
7
8
|
askNationality: false,
|
|
8
9
|
askTravelClass: false,
|
|
@@ -2,10 +2,10 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
|
2
2
|
|
|
3
3
|
import { MobileFilterType, Room, TravelerType, TypeaheadOption } from '../types';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
|
-
import { TravelType, TravelClass,
|
|
5
|
+
import { TravelType, TravelClass, PortalQsmType } from '../../shared/types';
|
|
6
6
|
|
|
7
7
|
export interface QSMState {
|
|
8
|
-
qsmType?:
|
|
8
|
+
qsmType?: PortalQsmType;
|
|
9
9
|
selectedOrigin?: string;
|
|
10
10
|
selectedDestination?: string;
|
|
11
11
|
selectedAirport?: string;
|
|
@@ -50,7 +50,7 @@ export interface QSMState {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const initialState: QSMState = {
|
|
53
|
-
qsmType:
|
|
53
|
+
qsmType: PortalQsmType.AccommodationAndFlight,
|
|
54
54
|
selectedOrigin: undefined,
|
|
55
55
|
selectedDestination: undefined,
|
|
56
56
|
selectedAirport: undefined,
|
|
@@ -93,7 +93,7 @@ const qsmSlice = createSlice({
|
|
|
93
93
|
name: 'qsm',
|
|
94
94
|
initialState,
|
|
95
95
|
reducers: {
|
|
96
|
-
setSelectedQsmType: (state, action: PayloadAction<
|
|
96
|
+
setSelectedQsmType: (state, action: PayloadAction<PortalQsmType>) => {
|
|
97
97
|
state.qsmType = action.payload;
|
|
98
98
|
},
|
|
99
99
|
setOrigin: (state, action: PayloadAction<string>) => {
|
package/src/qsm/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { PortalQsmType, TravelClass, TravelType } from '../shared/types';
|
|
3
3
|
|
|
4
4
|
export interface QSMConfiguration {
|
|
5
|
-
type?:
|
|
5
|
+
type?: PortalQsmType;
|
|
6
6
|
// Type specification and dedicated parameters
|
|
7
7
|
askRooms?: boolean; // hotel || roundTrip
|
|
8
8
|
askTravelType?: boolean; // hotel || roundTrip
|
|
@@ -6,12 +6,14 @@ export const enrichFiltersWithResults = (results: BookingPackageItem[], filters:
|
|
|
6
6
|
return filters ?? [];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
return filters.map((filter) => {
|
|
10
|
+
let updatedFilter = { ...filter };
|
|
11
|
+
|
|
10
12
|
if (filter.property === 'price' && (filter.min == null || filter.max == null)) {
|
|
11
13
|
const prices = results.map((r) => r.price ?? 0).filter((p) => p > 0);
|
|
12
14
|
if (prices.length > 0) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
updatedFilter.min = Math.floor(Math.min(...prices));
|
|
16
|
+
updatedFilter.max = Math.ceil(Math.max(...prices));
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
|
|
@@ -27,9 +29,7 @@ export const enrichFiltersWithResults = (results: BookingPackageItem[], filters:
|
|
|
27
29
|
}
|
|
28
30
|
});
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
filter.options = Array.from(map.values()).map((accommodation) => ({
|
|
32
|
+
updatedFilter.options = Array.from(map.values()).map((accommodation) => ({
|
|
33
33
|
label: accommodation.name ?? accommodation.code,
|
|
34
34
|
value: accommodation.code,
|
|
35
35
|
isChecked: false
|
|
@@ -48,7 +48,7 @@ export const enrichFiltersWithResults = (results: BookingPackageItem[], filters:
|
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
updatedFilter.options = Array.from(map.values()).map((regime) => ({
|
|
52
52
|
label: regime.name ?? regime.code,
|
|
53
53
|
value: regime.code,
|
|
54
54
|
isChecked: false
|
|
@@ -67,13 +67,13 @@ export const enrichFiltersWithResults = (results: BookingPackageItem[], filters:
|
|
|
67
67
|
});
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
updatedFilter.options = Array.from(map.values()).map((theme) => ({
|
|
71
71
|
label: theme.name,
|
|
72
72
|
value: theme.id,
|
|
73
73
|
isChecked: false
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
|
-
}
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
return updatedFilter;
|
|
78
|
+
});
|
|
79
79
|
};
|
|
@@ -11,6 +11,7 @@ import FlightFilters from '../filters/flight-filters';
|
|
|
11
11
|
import { ExtendedFlightSearchResponseItem, FlightSelectionMode } from '../../types';
|
|
12
12
|
import { getSortingName } from '../../utils/flight-utils';
|
|
13
13
|
import Spinner from '../spinner/spinner';
|
|
14
|
+
import { PortalQsmType } from '../../../shared/types';
|
|
14
15
|
|
|
15
16
|
interface FlightResultsContainerProps {
|
|
16
17
|
isMobile: boolean;
|
|
@@ -42,7 +43,7 @@ const FlightResultsContainer: React.FC<FlightResultsContainerProps> = ({ isMobil
|
|
|
42
43
|
|
|
43
44
|
useEffect(() => {
|
|
44
45
|
if (!context?.showMockup) {
|
|
45
|
-
if (context?.type ===
|
|
46
|
+
if (context?.type === PortalQsmType.Flight && isHubReady) {
|
|
46
47
|
onFlightSearch();
|
|
47
48
|
}
|
|
48
49
|
}
|
|
@@ -128,7 +129,7 @@ const FlightResultsContainer: React.FC<FlightResultsContainerProps> = ({ isMobil
|
|
|
128
129
|
|
|
129
130
|
<div className="search__results__wrapper">
|
|
130
131
|
{flightsLoading && <Spinner />}
|
|
131
|
-
{context?.type ==
|
|
132
|
+
{context?.type == PortalQsmType.Flight && context?.showFlightAccommodationResults && results && results.length > 0 && (
|
|
132
133
|
<FlightSelection searchResults={results} flightSelectionType={flightSelectionType} />
|
|
133
134
|
)}
|
|
134
135
|
</div>
|
|
@@ -44,6 +44,7 @@ import FlightResultsContainer from './flight-search-results';
|
|
|
44
44
|
import Filters from '../filters/filters';
|
|
45
45
|
import GroupTourResults from '../group-tour/group-tour-results';
|
|
46
46
|
import { applyFilters } from '../../utils/search-results-utils';
|
|
47
|
+
import { PortalQsmType } from '../../../shared/types';
|
|
47
48
|
|
|
48
49
|
const SearchResultsContainer: React.FC = () => {
|
|
49
50
|
const dispatch = useDispatch();
|
|
@@ -121,7 +122,14 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
121
122
|
officeId: 1,
|
|
122
123
|
payload: {
|
|
123
124
|
catalogueIds: context!.tideConnection.catalogueIds ?? [],
|
|
124
|
-
serviceType:
|
|
125
|
+
serviceType:
|
|
126
|
+
context!.type === PortalQsmType.Accommodation || context!.type === PortalQsmType.AccommodationAndFlight
|
|
127
|
+
? 3
|
|
128
|
+
: context!.type === PortalQsmType.Flight
|
|
129
|
+
? 7
|
|
130
|
+
: context!.type === PortalQsmType.RoundTrip
|
|
131
|
+
? 1
|
|
132
|
+
: 0,
|
|
125
133
|
searchType: 0,
|
|
126
134
|
destination: {
|
|
127
135
|
id: Number(destinationId),
|
|
@@ -192,8 +200,14 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
192
200
|
payload: {
|
|
193
201
|
catalogueIds: context!.tideConnection.catalogueIds ?? [],
|
|
194
202
|
serviceType:
|
|
195
|
-
context!.type ===
|
|
196
|
-
|
|
203
|
+
context!.type === PortalQsmType.Accommodation || context!.type === PortalQsmType.AccommodationAndFlight
|
|
204
|
+
? 3
|
|
205
|
+
: context!.type === PortalQsmType.Flight
|
|
206
|
+
? 7
|
|
207
|
+
: context!.type === PortalQsmType.RoundTrip
|
|
208
|
+
? 1
|
|
209
|
+
: undefined,
|
|
210
|
+
searchType: context!.type === PortalQsmType.GroupTour ? 1 : 0,
|
|
197
211
|
destination: {
|
|
198
212
|
id: Number(destinationId),
|
|
199
213
|
isCountry: destinationIsCountry,
|
|
@@ -206,7 +220,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
206
220
|
toDate: to,
|
|
207
221
|
earliestFromOffset: 0,
|
|
208
222
|
latestToOffset: 0,
|
|
209
|
-
includeFlights: context!.type ===
|
|
223
|
+
includeFlights: context!.type === PortalQsmType.AccommodationAndFlight ? true : false,
|
|
210
224
|
// regimeCodes:
|
|
211
225
|
// filters
|
|
212
226
|
// .find((f) => f.property === 'regime')
|
|
@@ -214,7 +228,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
214
228
|
// .flatMap((o) => o.value.toString()) || [],
|
|
215
229
|
// minPrice: filters.find((f) => f.property === 'price')?.selectedMin,
|
|
216
230
|
// maxPrice: filters.find((f) => f.property === 'price')?.selectedMax,
|
|
217
|
-
useExactDates: context?.type ===
|
|
231
|
+
useExactDates: context?.type === PortalQsmType.GroupTour ? false : true,
|
|
218
232
|
onlyCachedResults: false,
|
|
219
233
|
includeAllAllotments: true,
|
|
220
234
|
productIds: hotel ? [hotel] : [],
|
|
@@ -348,7 +362,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
348
362
|
dispatch(setSelectedSearchResult(matching.productId));
|
|
349
363
|
}
|
|
350
364
|
} else {
|
|
351
|
-
if (context.type ===
|
|
365
|
+
if (context.type === PortalQsmType.AccommodationAndFlight) {
|
|
352
366
|
dispatch(setSelectedSearchResult(packageSearchResults[0]?.productId));
|
|
353
367
|
}
|
|
354
368
|
}
|
|
@@ -362,7 +376,11 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
362
376
|
};
|
|
363
377
|
|
|
364
378
|
if (!context?.showMockup) {
|
|
365
|
-
if (
|
|
379
|
+
if (
|
|
380
|
+
context?.type === PortalQsmType.AccommodationAndFlight ||
|
|
381
|
+
context?.type === PortalQsmType.Accommodation ||
|
|
382
|
+
context?.type === PortalQsmType.GroupTour
|
|
383
|
+
) {
|
|
366
384
|
runSearch();
|
|
367
385
|
}
|
|
368
386
|
}
|
|
@@ -373,7 +391,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
373
391
|
const fetchPackageDetails = async () => {
|
|
374
392
|
if (!selectedSearchResultId || !context) return;
|
|
375
393
|
|
|
376
|
-
if (context?.type ===
|
|
394
|
+
if (context?.type === PortalQsmType.Accommodation || context?.type === PortalQsmType.GroupTour) {
|
|
377
395
|
handleFlyInToggle(true);
|
|
378
396
|
}
|
|
379
397
|
|
|
@@ -409,7 +427,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
409
427
|
productCode: selectedItem.code,
|
|
410
428
|
fromDate: selectedItem.fromDate,
|
|
411
429
|
toDate: selectedItem.toDate,
|
|
412
|
-
includeFlights: context!.type ===
|
|
430
|
+
includeFlights: context!.type === PortalQsmType.AccommodationAndFlight ? true : false,
|
|
413
431
|
includeHotels: true,
|
|
414
432
|
includePaxTypes: true,
|
|
415
433
|
checkExternalAvailability: true,
|
|
@@ -449,7 +467,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
449
467
|
{context && (
|
|
450
468
|
<div className="search">
|
|
451
469
|
<div className="search__container">
|
|
452
|
-
{context.type ===
|
|
470
|
+
{context.type === PortalQsmType.Flight && (
|
|
453
471
|
<FlightSearchProvider tideConnection={context.tideConnection}>
|
|
454
472
|
<FlightResultsContainer isMobile={isMobile} />
|
|
455
473
|
<FlyIn
|
|
@@ -461,9 +479,12 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
461
479
|
/>
|
|
462
480
|
</FlightSearchProvider>
|
|
463
481
|
)}
|
|
464
|
-
{(context.type ===
|
|
482
|
+
{(context.type === PortalQsmType.AccommodationAndFlight ||
|
|
483
|
+
context.type === PortalQsmType.Accommodation ||
|
|
484
|
+
context.type === PortalQsmType.GroupTour ||
|
|
485
|
+
context.type === PortalQsmType.RoundTrip) && (
|
|
465
486
|
<>
|
|
466
|
-
{context.type !=
|
|
487
|
+
{context.type != PortalQsmType.AccommodationAndFlight && context.showFilters && (
|
|
467
488
|
<Filters
|
|
468
489
|
initialFilters={initialFilters}
|
|
469
490
|
filters={filters}
|
|
@@ -473,7 +494,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
473
494
|
isLoading={isLoading}
|
|
474
495
|
/>
|
|
475
496
|
)}
|
|
476
|
-
{context.type ===
|
|
497
|
+
{context.type === PortalQsmType.AccommodationAndFlight && (
|
|
477
498
|
<Itinerary isOpen={itineraryOpen} handleSetIsOpen={() => setItineraryOpen(!itineraryOpen)} isLoading={isLoading} />
|
|
478
499
|
)}
|
|
479
500
|
{/* ---------------- Results ---------------- */}
|
|
@@ -481,13 +502,13 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
481
502
|
{isMobile && (
|
|
482
503
|
<div className="search__result-row">
|
|
483
504
|
<div className="search__results__actions">
|
|
484
|
-
{context.type !=
|
|
505
|
+
{context.type != PortalQsmType.AccommodationAndFlight && context.showFilters && (
|
|
485
506
|
<div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
|
|
486
507
|
<Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
|
|
487
508
|
{translations.SRP.FILTERS}
|
|
488
509
|
</div>
|
|
489
510
|
)}
|
|
490
|
-
{context.type ===
|
|
511
|
+
{context.type === PortalQsmType.AccommodationAndFlight && (
|
|
491
512
|
<div className="cta cta--filter" onClick={() => setItineraryOpen(true)}>
|
|
492
513
|
<Icon name="ui-calendar" className="mobile-filters-button__icon" height={16} />
|
|
493
514
|
{translations.SRP.SHOW_ITINERARY}
|
|
@@ -533,15 +554,15 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
533
554
|
|
|
534
555
|
{context.showRoundTripResults && context.showMockup && <RoundTripResults />}
|
|
535
556
|
|
|
536
|
-
{context.type ===
|
|
557
|
+
{context.type === PortalQsmType.GroupTour && <GroupTourResults isLoading={isLoading} />}
|
|
537
558
|
|
|
538
|
-
{context.type ===
|
|
559
|
+
{context.type === PortalQsmType.AccommodationAndFlight && context.showFlightResults && bookingPackageDetails?.outwardFlights && (
|
|
539
560
|
<FlightResults flights={bookingPackageDetails?.outwardFlights} isDeparture={true} />
|
|
540
561
|
)}
|
|
541
562
|
|
|
542
563
|
{context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} />}
|
|
543
564
|
|
|
544
|
-
{context.type ===
|
|
565
|
+
{context.type === PortalQsmType.AccommodationAndFlight && context.showFlightResults && bookingPackageDetails?.returnFlights && (
|
|
545
566
|
<FlightResults flights={bookingPackageDetails?.returnFlights} isDeparture={false} />
|
|
546
567
|
)}
|
|
547
568
|
</div>
|