@qite/tide-booking-component 1.4.39 → 1.4.41
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/content/image-card-grid/index.d.ts +4 -0
- package/build/build-cjs/content/image-card-grid/types.d.ts +12 -0
- package/build/build-cjs/index.d.ts +2 -1
- package/build/build-cjs/index.js +9620 -2315
- 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/components/icon.d.ts +10 -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/content/image-card-grid/index.d.ts +4 -0
- package/build/build-esm/content/image-card-grid/types.d.ts +12 -0
- package/build/build-esm/index.d.ts +2 -1
- package/build/build-esm/index.js +9496 -2304
- 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/components/icon.d.ts +10 -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/content/image-card-grid/index.tsx +34 -0
- package/src/content/image-card-grid/types.ts +13 -0
- package/src/index.ts +2 -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 +622 -0
- package/src/shared/components/icon.tsx +826 -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 +541 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useState } from 'react';
|
|
1
|
+
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { useDispatch, useSelector } from 'react-redux';
|
|
3
3
|
import { SearchResultsRootState } from '../../store/search-results-store';
|
|
4
4
|
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
|
|
@@ -6,7 +6,6 @@ import SearchResultsConfigurationContext from '../../search-results-configuratio
|
|
|
6
6
|
import { resetFilters, setSortKey, setResults, setIsLoading, setSelectedHotel, setBookingPackageDetails, setEntry } from '../../store/search-results-slice';
|
|
7
7
|
import { Filter, SortingOption } from '../../types';
|
|
8
8
|
import useMediaQuery from '../../../shared/utils/use-media-query-util';
|
|
9
|
-
import Filters from '../filters/filters';
|
|
10
9
|
import ItemPicker from '../item-picker';
|
|
11
10
|
|
|
12
11
|
import { TideClientConfig, details, detailsWL, getEntryLight, search } from '@qite/tide-client';
|
|
@@ -26,13 +25,14 @@ import { Room } from '../../../booking-wizard/types';
|
|
|
26
25
|
import Icon from '../icon';
|
|
27
26
|
import Itinerary from '../itinerary';
|
|
28
27
|
import TabViews from '../tab-views';
|
|
28
|
+
import FlyIn from '../../../shared/components/flyin';
|
|
29
29
|
import HotelAccommodationResults from '../hotel/hotel-accommodation-results';
|
|
30
30
|
import RoundTripResults from '../round-trip/round-trip-results';
|
|
31
31
|
import { enrichFiltersWithResults } from '../filters/utility';
|
|
32
32
|
import FlightResults from '../flight/flight-results';
|
|
33
33
|
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
34
|
-
import
|
|
35
|
-
import
|
|
34
|
+
import { FlightSearchProvider } from '../flight/flight-search-context';
|
|
35
|
+
import FlightResultsContainer from './flight-search-results';
|
|
36
36
|
|
|
37
37
|
const SearchResultsContainer: React.FC = () => {
|
|
38
38
|
const dispatch = useDispatch();
|
|
@@ -52,6 +52,9 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
52
52
|
const [filtersOpen, setFiltersOpen] = useState(false);
|
|
53
53
|
const [itineraryOpen, setItineraryOpen] = useState(false);
|
|
54
54
|
|
|
55
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
56
|
+
const panelRef = useRef<HTMLDivElement | null>(null);
|
|
57
|
+
|
|
55
58
|
const sortingOptions: SortingOption[] = [
|
|
56
59
|
{ key: 'price-asc', label: translations.SRP.PRICE_ASC },
|
|
57
60
|
{ key: 'price-desc', label: translations.SRP.PRICE_DESC },
|
|
@@ -275,7 +278,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
275
278
|
|
|
276
279
|
// seperate Search
|
|
277
280
|
useEffect(() => {
|
|
278
|
-
const
|
|
281
|
+
const runHotelFlightSearch = async () => {
|
|
279
282
|
dispatch(setIsLoading(true));
|
|
280
283
|
try {
|
|
281
284
|
if (!context) {
|
|
@@ -335,7 +338,9 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
335
338
|
};
|
|
336
339
|
|
|
337
340
|
if (!context?.showMockup) {
|
|
338
|
-
|
|
341
|
+
if (context?.type === 'hotel-flight') {
|
|
342
|
+
runHotelFlightSearch();
|
|
343
|
+
}
|
|
339
344
|
}
|
|
340
345
|
}, [location.search, searchTrigger]);
|
|
341
346
|
|
|
@@ -411,7 +416,14 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
411
416
|
{context && (
|
|
412
417
|
<div className="search">
|
|
413
418
|
<div className="search__container">
|
|
414
|
-
{context.
|
|
419
|
+
{context.type === 'flight' && (
|
|
420
|
+
<FlightSearchProvider tideConnection={context.tideConnection}>
|
|
421
|
+
<FlightResultsContainer isMobile={isMobile} />
|
|
422
|
+
</FlightSearchProvider>
|
|
423
|
+
)}
|
|
424
|
+
{context.type === 'hotel-flight' && (
|
|
425
|
+
<>
|
|
426
|
+
{/* {context.showFilters && (
|
|
415
427
|
<Filters
|
|
416
428
|
filters={filters}
|
|
417
429
|
isOpen={filtersOpen}
|
|
@@ -419,78 +431,81 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
419
431
|
handleApplyFilters={() => setSearchTrigger((prev) => prev + 1)}
|
|
420
432
|
isLoading={isLoading}
|
|
421
433
|
/>
|
|
422
|
-
)}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
434
|
+
)} */}
|
|
435
|
+
<Itinerary isOpen={itineraryOpen} handleSetIsOpen={() => setItineraryOpen(!itineraryOpen)} isLoading={isLoading} />
|
|
436
|
+
{/* ---------------- Results ---------------- */}
|
|
437
|
+
<div className="search__results">
|
|
438
|
+
{isMobile && (
|
|
439
|
+
<div className="search__result-row">
|
|
440
|
+
<div className="search__results__actions">
|
|
441
|
+
{context.showFilters && (
|
|
442
|
+
<div className="cta cta--filter" onClick={() => setFiltersOpen(true)}>
|
|
443
|
+
<Icon name="ui-filter" className="mobile-filters-button__icon" height={16} />
|
|
444
|
+
{translations.SRP.FILTERS}
|
|
445
|
+
</div>
|
|
446
|
+
)}
|
|
447
|
+
{context.type === 'hotel-flight' && (
|
|
448
|
+
<div className="cta cta--filter" onClick={() => setItineraryOpen(true)}>
|
|
449
|
+
<Icon name="ui-calendar" className="mobile-filters-button__icon" height={16} />
|
|
450
|
+
{translations.SRP.SHOW_ITINERARY}
|
|
451
|
+
</div>
|
|
452
|
+
)}
|
|
435
453
|
</div>
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
454
|
+
{sortingOptions && sortingOptions.length > 0 && (
|
|
455
|
+
<ItemPicker
|
|
456
|
+
items={sortingOptions}
|
|
457
|
+
selection={sortKey || undefined}
|
|
458
|
+
label={translations.SRP.SORTBY}
|
|
459
|
+
placeholder={translations.SRP.SORTBY}
|
|
460
|
+
classModifier="travel-class-picker__items"
|
|
461
|
+
onPick={handleSortChange}
|
|
462
|
+
/>
|
|
463
|
+
)}
|
|
440
464
|
</div>
|
|
441
|
-
</div>
|
|
442
|
-
{sortingOptions && sortingOptions.length > 0 && (
|
|
443
|
-
<ItemPicker
|
|
444
|
-
items={sortingOptions}
|
|
445
|
-
selection={sortKey || undefined}
|
|
446
|
-
label={translations.SRP.SORTBY}
|
|
447
|
-
placeholder={translations.SRP.SORTBY}
|
|
448
|
-
classModifier="travel-class-picker__items"
|
|
449
|
-
onPick={handleSortChange}
|
|
450
|
-
/>
|
|
451
465
|
)}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
466
|
+
|
|
467
|
+
<div className="search__result-row">
|
|
468
|
+
<span className="search__result-row-text">
|
|
469
|
+
{!isLoading && (
|
|
470
|
+
<>
|
|
471
|
+
{results?.length && results.length} {translations.SRP.TOTAL_RESULTS_LABEL}
|
|
472
|
+
</>
|
|
473
|
+
)}
|
|
474
|
+
</span>
|
|
475
|
+
{!isMobile && sortingOptions && sortingOptions.length > 0 && (
|
|
476
|
+
<div className="search__result-row-filter">
|
|
477
|
+
<ItemPicker
|
|
478
|
+
items={sortingOptions}
|
|
479
|
+
selection={sortKey || undefined}
|
|
480
|
+
label={translations.SRP.SORTBY}
|
|
481
|
+
placeholder={translations.SRP.SORTBY}
|
|
482
|
+
classModifier="travel-class-picker__items"
|
|
483
|
+
onPick={handleSortChange}
|
|
484
|
+
/>
|
|
485
|
+
</div>
|
|
486
|
+
)}
|
|
473
487
|
</div>
|
|
474
|
-
)}
|
|
475
|
-
</div>
|
|
476
488
|
|
|
477
|
-
|
|
478
|
-
|
|
489
|
+
<div className="search__results__wrapper">
|
|
490
|
+
{context.showTabViews && <TabViews />}
|
|
479
491
|
|
|
480
|
-
|
|
492
|
+
{context.showRoundTripResults && context.showMockup && <RoundTripResults />}
|
|
481
493
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
494
|
+
{context.showFlightResults && bookingPackageDetails?.outwardFlights && (
|
|
495
|
+
<FlightResults flights={bookingPackageDetails?.outwardFlights} isDeparture={true} />
|
|
496
|
+
)}
|
|
485
497
|
|
|
486
|
-
|
|
487
|
-
{context.showFlightAccommodationResults && context.showMockup && <FlightAccommodationResults />}
|
|
498
|
+
{context.showHotelAccommodationResults && <HotelAccommodationResults isLoading={isLoading} context={context} />}
|
|
488
499
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
500
|
+
{context.showFlightResults && bookingPackageDetails?.returnFlights && (
|
|
501
|
+
<FlightResults flights={bookingPackageDetails?.returnFlights} isDeparture={false} />
|
|
502
|
+
)}
|
|
503
|
+
</div>
|
|
504
|
+
</div>
|
|
505
|
+
</>
|
|
506
|
+
)}
|
|
507
|
+
<button onClick={() => setIsOpen(!isOpen)}>Toggle FlyIn</button>
|
|
508
|
+
<FlyIn isOpen={isOpen} setIsOpen={setIsOpen} onPanelRef={(el) => (panelRef.current = el)} />
|
|
494
509
|
</div>
|
|
495
510
|
</div>
|
|
496
511
|
)}
|
|
@@ -5,6 +5,7 @@ import { BookingPackage, BookingPackageItem, EntryLight } from '@qite/tide-clien
|
|
|
5
5
|
export interface SearchResultsState {
|
|
6
6
|
results: BookingPackageItem[];
|
|
7
7
|
selectedHotelId: number | null;
|
|
8
|
+
selectedFlightId: string | null;
|
|
8
9
|
bookingPackageDetails: BookingPackage | null;
|
|
9
10
|
entry: EntryLight | null;
|
|
10
11
|
isLoading: boolean;
|
|
@@ -17,6 +18,7 @@ export interface SearchResultsState {
|
|
|
17
18
|
const initialState: SearchResultsState = {
|
|
18
19
|
results: [],
|
|
19
20
|
selectedHotelId: null,
|
|
21
|
+
selectedFlightId: null,
|
|
20
22
|
bookingPackageDetails: null,
|
|
21
23
|
entry: null,
|
|
22
24
|
isLoading: false,
|
|
@@ -36,6 +38,9 @@ const searchResultsSlice = createSlice({
|
|
|
36
38
|
setSelectedHotel(state, action: PayloadAction<number | null>) {
|
|
37
39
|
state.selectedHotelId = action.payload;
|
|
38
40
|
},
|
|
41
|
+
setSelectedFlight(state, action: PayloadAction<string | null>) {
|
|
42
|
+
state.selectedFlightId = action.payload;
|
|
43
|
+
},
|
|
39
44
|
setBookingPackageDetails(state, action: PayloadAction<{ details: BookingPackage }>) {
|
|
40
45
|
state.bookingPackageDetails = action.payload.details;
|
|
41
46
|
},
|
|
@@ -95,6 +100,7 @@ const searchResultsSlice = createSlice({
|
|
|
95
100
|
export const {
|
|
96
101
|
setResults,
|
|
97
102
|
setSelectedHotel,
|
|
103
|
+
setSelectedFlight,
|
|
98
104
|
setBookingPackageDetails,
|
|
99
105
|
setEntry,
|
|
100
106
|
selectFlight,
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { FlightSearchResponseItem } from '@qite/tide-client';
|
|
1
2
|
import { ReactNode } from 'react';
|
|
2
3
|
|
|
4
|
+
export type SRPType = 'hotel' | 'flight' | 'hotel-flight' | 'roundTrip';
|
|
5
|
+
|
|
3
6
|
export interface SearchResultsConfiguration {
|
|
4
|
-
type:
|
|
7
|
+
type: SRPType;
|
|
5
8
|
|
|
6
9
|
// Tide connection
|
|
7
10
|
tideConnection: {
|
|
8
11
|
host: string;
|
|
9
12
|
apiKey: string;
|
|
10
13
|
catalogueIds?: number[]; // Optional, used for multiple catalogues
|
|
14
|
+
officeId?: number;
|
|
11
15
|
};
|
|
12
16
|
|
|
13
17
|
// Filter settings
|
|
@@ -141,3 +145,35 @@ export interface SortingOption {
|
|
|
141
145
|
label: string;
|
|
142
146
|
icon?: ReactNode;
|
|
143
147
|
}
|
|
148
|
+
|
|
149
|
+
export interface ExtendedFlightSearchResponseItem extends FlightSearchResponseItem {
|
|
150
|
+
requestId: number; // Unique identifier for the search request
|
|
151
|
+
guid: string; // Unique identifier for the item
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface Sequence {
|
|
155
|
+
requestId: number;
|
|
156
|
+
sequenceId: number;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface FilterValue {
|
|
160
|
+
name: string;
|
|
161
|
+
id: number | string;
|
|
162
|
+
lowestPrice: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface Filters {
|
|
166
|
+
airlines: FilterValue[];
|
|
167
|
+
numberOfStops: FilterValue[];
|
|
168
|
+
departureRanges: FilterValue[];
|
|
169
|
+
departureAirports: FilterValue[];
|
|
170
|
+
arrivalAirports: FilterValue[];
|
|
171
|
+
travelTimes: FilterValue[];
|
|
172
|
+
prices: FilterValue[];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface SortByType {
|
|
176
|
+
direction: 'asc' | 'desc';
|
|
177
|
+
label: string;
|
|
178
|
+
icon?: ReactNode;
|
|
179
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { first, isEmpty, last } from 'lodash';
|
|
2
|
+
import { FlightSearchResponseFlight, FlightSearchResponseFlightSegment, VendorType } from '@qite/tide-client';
|
|
3
|
+
import { ExtendedFlightSearchResponseItem, SortByType } from '../types';
|
|
4
|
+
import { DepartureRange } from '../../shared/types';
|
|
5
|
+
|
|
6
|
+
export const getOutwardFlight = (flightResult: ExtendedFlightSearchResponseItem): FlightSearchResponseFlight | undefined => {
|
|
7
|
+
return flightResult?.outward;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
// export const getAirportName = (airport: TideAirport | undefined, language: string): string => {
|
|
11
|
+
// if (!airport || !airport.name) {
|
|
12
|
+
// return "";
|
|
13
|
+
// }
|
|
14
|
+
// const airportName = airport.localizedNames?.find((name) => name?.languageCode === language);
|
|
15
|
+
// return airportName && airportName?.value ? airportName.value : airport.name;
|
|
16
|
+
// };
|
|
17
|
+
|
|
18
|
+
// export const getAirportLocationName = (airport: TideAirport | undefined, language: string): string => {
|
|
19
|
+
// if (!airport || !airport.locationName) {
|
|
20
|
+
// return "";
|
|
21
|
+
// }
|
|
22
|
+
// const locationName = airport.localizedLocations?.find((name) => name?.languageCode === language);
|
|
23
|
+
// return locationName && locationName?.value ? locationName.value : airport.locationName;
|
|
24
|
+
// };
|
|
25
|
+
|
|
26
|
+
// export const getCountryName = (country: TideCountry | undefined | null, language: string): Maybe<string> | undefined => {
|
|
27
|
+
// if (!country) {
|
|
28
|
+
// return "";
|
|
29
|
+
// }
|
|
30
|
+
|
|
31
|
+
// const countryName = country.localizedNames?.find((name) => name?.languageCode === language);
|
|
32
|
+
// return countryName && countryName.value !== "" ? countryName.value : country.name;
|
|
33
|
+
// };
|
|
34
|
+
|
|
35
|
+
export const getFlightSegments = (flight: FlightSearchResponseFlight | undefined): FlightSearchResponseFlightSegment[] => {
|
|
36
|
+
if (!flight) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
return flight?.segments;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const getDepartureSegment = (flight: FlightSearchResponseFlight | undefined): FlightSearchResponseFlightSegment | undefined => {
|
|
43
|
+
const segments = getFlightSegments(flight);
|
|
44
|
+
if (isEmpty(segments)) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return first(segments);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const getArrivalSegment = (flight: FlightSearchResponseFlight | undefined): FlightSearchResponseFlightSegment | undefined => {
|
|
52
|
+
const segments = getFlightSegments(flight);
|
|
53
|
+
if (isEmpty(segments)) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return last(segments);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export const getNumberOfStops = (flight: FlightSearchResponseFlight | undefined): number => {
|
|
61
|
+
const segments = getFlightSegments(flight);
|
|
62
|
+
if (isEmpty(segments)) {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
return segments.length - 1;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getNumberOfStopsLabel = (flight: FlightSearchResponseFlight | undefined, directLabel: string, stopsLabel: string, stopLabel: string): string => {
|
|
69
|
+
const numberOfStops = getNumberOfStops(flight);
|
|
70
|
+
|
|
71
|
+
if (numberOfStops === 0) {
|
|
72
|
+
return directLabel;
|
|
73
|
+
} else if (numberOfStops === 1) {
|
|
74
|
+
return `${numberOfStops} ${stopLabel}`;
|
|
75
|
+
} else {
|
|
76
|
+
return `${numberOfStops} ${stopsLabel}`;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const getDepartureRangeName = (translations: any, range: DepartureRange | undefined): string => {
|
|
81
|
+
switch (range) {
|
|
82
|
+
case DepartureRange.Morning:
|
|
83
|
+
return translations.FLIGHTS_FORM.MORNING_DEPARTURE;
|
|
84
|
+
case DepartureRange.Afternoon:
|
|
85
|
+
return translations.FLIGHTS_FORM.AFTERNOON_DEPARTURE;
|
|
86
|
+
case DepartureRange.Evening:
|
|
87
|
+
return translations.FLIGHTS_FORM.EVENING_DEPARTURE;
|
|
88
|
+
case DepartureRange.Night:
|
|
89
|
+
return translations.FLIGHTS_FORM.NIGHT_DEPARTURE;
|
|
90
|
+
default:
|
|
91
|
+
return '';
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const getSortingName = (translations: any, sortByType: SortByType): string => {
|
|
96
|
+
switch (sortByType.label) {
|
|
97
|
+
case 'price':
|
|
98
|
+
return sortByType.direction === 'asc' ? translations.SRP.PRICE_ASC : translations.SRP.PRICE_DESC;
|
|
99
|
+
case 'departureTime':
|
|
100
|
+
return sortByType.direction === 'asc' ? translations.SRP.DEPARTURE_TIME_ASC : translations.SRP.DEPARTURE_TIME_DESC;
|
|
101
|
+
case 'durationInTicks':
|
|
102
|
+
return sortByType.direction === 'asc' ? translations.SRP.DURATION_ASC : translations.SRP.DURATION_DESC;
|
|
103
|
+
default:
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
};
|