@qite/tide-booking-component 1.4.93 → 1.4.95
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/.prettierrc +9 -9
- package/.vs/ProjectSettings.json +3 -3
- package/.vs/VSWorkspaceState.json +5 -5
- package/build/build-cjs/index.js +81 -27
- package/build/build-cjs/src/booking-wizard/features/booking/booking-slice.d.ts +2 -1
- package/build/build-cjs/src/booking-wizard/features/booking/selectors.d.ts +4 -3
- package/build/build-cjs/src/booking-wizard/features/price-details/price-details-slice.d.ts +1 -0
- package/build/build-cjs/src/booking-wizard/features/price-details/selectors.d.ts +1 -0
- package/build/build-cjs/src/booking-wizard/features/sidebar/sidebar.d.ts +1 -0
- package/build/build-cjs/src/booking-wizard/types.d.ts +1 -0
- package/build/build-cjs/src/shared/utils/localization-util.d.ts +1 -0
- package/build/build-esm/index.js +81 -27
- package/build/build-esm/src/booking-wizard/features/booking/booking-slice.d.ts +2 -1
- package/build/build-esm/src/booking-wizard/features/booking/selectors.d.ts +4 -3
- package/build/build-esm/src/booking-wizard/features/price-details/price-details-slice.d.ts +1 -0
- package/build/build-esm/src/booking-wizard/features/price-details/selectors.d.ts +1 -0
- package/build/build-esm/src/booking-wizard/features/sidebar/sidebar.d.ts +1 -0
- package/build/build-esm/src/booking-wizard/types.d.ts +1 -0
- package/build/build-esm/src/shared/utils/localization-util.d.ts +1 -0
- package/package.json +83 -83
- package/src/booking-product/components/age-select.tsx +35 -35
- package/src/booking-product/components/amount-input.tsx +51 -51
- package/src/booking-product/components/date-range-picker/calendar.tsx +155 -155
- package/src/booking-product/components/footer.tsx +54 -54
- package/src/booking-product/components/header.tsx +57 -57
- package/src/booking-product/components/icon.tsx +200 -200
- package/src/booking-product/components/list-view.tsx +54 -54
- package/src/booking-product/components/rating.tsx +21 -21
- package/src/booking-product/components/rooms.tsx +171 -171
- package/src/booking-product/constants.ts +1 -1
- package/src/booking-product/index.tsx +21 -21
- package/src/booking-product/settings-context.ts +16 -16
- package/src/booking-product/types.ts +30 -30
- package/src/booking-product/utils/api.ts +26 -26
- package/src/booking-product/utils/price.ts +28 -28
- package/src/booking-wizard/api-settings-slice.ts +24 -24
- package/src/booking-wizard/components/icon.tsx +398 -398
- package/src/booking-wizard/components/labeled-input.tsx +56 -56
- package/src/booking-wizard/components/labeled-select.tsx +54 -54
- package/src/booking-wizard/components/message.tsx +21 -21
- package/src/booking-wizard/components/multi-range-filter.tsx +99 -99
- package/src/booking-wizard/components/phone-input.tsx +146 -146
- package/src/booking-wizard/components/print-offer-button.tsx +53 -53
- package/src/booking-wizard/components/product-card.tsx +23 -23
- package/src/booking-wizard/declarations.d.ts +4 -4
- package/src/booking-wizard/features/booking/booking-self-contained.tsx +16 -1
- package/src/booking-wizard/features/booking/booking-slice.ts +9 -1
- package/src/booking-wizard/features/booking/booking.tsx +16 -1
- package/src/booking-wizard/features/booking/selectors.ts +5 -0
- package/src/booking-wizard/features/flight-options/flight-filter.tsx +371 -371
- package/src/booking-wizard/features/flight-options/flight-option-flight.tsx +354 -354
- package/src/booking-wizard/features/flight-options/flight-option-modal.tsx +211 -211
- package/src/booking-wizard/features/flight-options/flight-option.tsx +57 -57
- package/src/booking-wizard/features/flight-options/flight-utils.ts +423 -423
- package/src/booking-wizard/features/price-details/price-details-api.ts +20 -20
- package/src/booking-wizard/features/price-details/price-details-slice.ts +2 -0
- package/src/booking-wizard/features/price-details/selectors.ts +1 -0
- package/src/booking-wizard/features/price-details/util.ts +115 -115
- package/src/booking-wizard/features/product-options/no-options.tsx +18 -18
- package/src/booking-wizard/features/product-options/none-option.tsx +73 -73
- package/src/booking-wizard/features/product-options/option-booking-airline-group.tsx +53 -53
- package/src/booking-wizard/features/product-options/option-booking-group.tsx +152 -152
- package/src/booking-wizard/features/product-options/option-item.tsx +236 -236
- package/src/booking-wizard/features/product-options/option-pax-card.tsx +159 -159
- package/src/booking-wizard/features/product-options/option-pax-group.tsx +122 -122
- package/src/booking-wizard/features/product-options/option-room.tsx +226 -226
- package/src/booking-wizard/features/product-options/option-unit-group.tsx +138 -138
- package/src/booking-wizard/features/room-options/room-utils.ts +154 -154
- package/src/booking-wizard/features/room-options/room.tsx +123 -123
- package/src/booking-wizard/features/room-options/traveler-rooms.tsx +64 -64
- package/src/booking-wizard/features/sidebar/index.tsx +2 -0
- package/src/booking-wizard/features/sidebar/sidebar-flight.tsx +66 -66
- package/src/booking-wizard/features/sidebar/sidebar.tsx +17 -1
- package/src/booking-wizard/features/summary/summary-booking-option-pax.tsx +23 -23
- package/src/booking-wizard/features/summary/summary-booking-option-unit.tsx +23 -23
- package/src/booking-wizard/features/summary/summary-flight.tsx +36 -36
- package/src/booking-wizard/features/summary/summary-per-booking-option-group.tsx +60 -60
- package/src/booking-wizard/features/summary/summary-per-pax-option-group.tsx +56 -56
- package/src/booking-wizard/features/summary/summary-per-unit-option-group.tsx +58 -58
- package/src/booking-wizard/features/summary/summary-slice.ts +27 -27
- package/src/booking-wizard/features/travelers-form/travelers-form-slice.ts +157 -157
- package/src/booking-wizard/features/travelers-form/travelers-form-util.ts +10 -10
- package/src/booking-wizard/features/travelers-form/type-ahead-input.tsx +85 -85
- package/src/booking-wizard/features/travelers-form/validate-form.ts +178 -178
- package/src/booking-wizard/index.tsx +27 -27
- package/src/booking-wizard/store.ts +26 -26
- package/src/booking-wizard/types.ts +1 -0
- package/src/booking-wizard/use-offer-printer.ts +108 -108
- package/src/content/components/LanguageSwitcher.tsx +158 -158
- package/src/content/components/accordion.tsx +30 -30
- package/src/content/components/contact.tsx +211 -211
- package/src/content/components/personal-contact-form.tsx +809 -809
- package/src/content/header/index.tsx +43 -43
- package/src/content/header/types.ts +26 -26
- package/src/qsm/components/date-picker/index.tsx +152 -152
- package/src/qsm/components/date-range-picker/calendar-day.tsx +49 -49
- package/src/qsm/components/date-range-picker/calendar.tsx +211 -211
- package/src/qsm/components/date-range-picker/index.tsx +404 -404
- package/src/qsm/index.tsx +26 -26
- package/src/qsm/store/qsm-store.ts +13 -13
- package/src/search-results/components/flight/flight-card.tsx +38 -38
- package/src/search-results/components/flight/flight-leg.tsx +61 -61
- package/src/search-results/components/flight/flight-path.tsx +23 -23
- package/src/search-results/components/multi-range-filter.tsx +104 -104
- package/src/search-results/components/search-results-container/search-results-container.tsx +2 -2
- package/src/search-results/index.tsx +24 -24
- package/src/search-results/search-results-configuration-context.ts +6 -6
- package/src/search-results/store/search-results-store.ts +13 -13
- package/src/shared/components/loader.tsx +16 -16
- package/src/shared/translations/ar-SA.json +2 -1
- package/src/shared/translations/da-DK.json +2 -1
- package/src/shared/translations/de-DE.json +2 -1
- package/src/shared/translations/en-GB.json +2 -1
- package/src/shared/translations/es-ES.json +2 -1
- package/src/shared/translations/fr-BE.json +2 -1
- package/src/shared/translations/fr-FR.json +2 -1
- package/src/shared/translations/is-IS.json +2 -1
- package/src/shared/translations/it-IT.json +2 -1
- package/src/shared/translations/ja-JP.json +2 -1
- package/src/shared/translations/nl-BE.json +2 -1
- package/src/shared/translations/nl-NL.json +2 -1
- package/src/shared/translations/no-NO.json +2 -1
- package/src/shared/translations/pl-PL.json +2 -1
- package/src/shared/translations/pt-PT.json +2 -1
- package/src/shared/translations/sv-SE.json +2 -1
- package/src/shared/utils/class-util.ts +7 -7
- package/src/shared/utils/query-string-util.ts +91 -91
- package/src/shared/utils/tide-api-utils.ts +34 -34
- package/src/shared/utils/use-media-query-util.ts +19 -19
- package/styles/abstracts/_mixins.scss +74 -74
- package/styles/abstracts/_variables.scss +57 -57
- package/styles/base/_fonts.scss +2 -2
- package/styles/base/_normalize.scss +227 -227
- package/styles/base/_typography.scss +35 -35
- package/styles/booking-joker-variables.scss +596 -596
- package/styles/booking-product-variables.scss +330 -330
- package/styles/booking-product.scss +438 -438
- package/styles/booking-qsm-variables.scss +501 -501
- package/styles/booking-qsm.scss +52 -52
- package/styles/booking-wizard-variables.scss +603 -603
- package/styles/booking-wizard.scss +61 -61
- package/styles/components/_accordion.scss +67 -67
- package/styles/components/_animations.scss +39 -39
- package/styles/components/_base.scss +107 -107
- package/styles/components/_breadcrumb.scss +92 -92
- package/styles/components/_button.scss +238 -238
- package/styles/components/_checkbox.scss +230 -230
- package/styles/components/_contact.scss +239 -239
- package/styles/components/_cta.scss +238 -238
- package/styles/components/_date-list.scss +41 -41
- package/styles/components/_date-range-picker.scss +223 -223
- package/styles/components/_decrement-increment.scss +35 -35
- package/styles/components/_dropdown.scss +72 -72
- package/styles/components/_faq.scss +27 -27
- package/styles/components/_flight-option.scss +1419 -1419
- package/styles/components/_gallery.scss +314 -314
- package/styles/components/_header.scss +113 -113
- package/styles/components/_img-slider.scss +175 -175
- package/styles/components/_info-message.scss +75 -75
- package/styles/components/_input.scss +35 -35
- package/styles/components/_list.scss +185 -185
- package/styles/components/_loader.scss +70 -70
- package/styles/components/_mixins.scss +579 -579
- package/styles/components/_passenger-picker.scss +306 -306
- package/styles/components/_phone-input.scss +8 -8
- package/styles/components/_placeholders.scss +165 -165
- package/styles/components/_qsm.scss +17 -17
- package/styles/components/_radiobutton.scss +170 -170
- package/styles/components/_select-wrapper.scss +76 -76
- package/styles/components/_slider.scss +128 -128
- package/styles/components/_spinner.scss +29 -29
- package/styles/components/_step-indicators.scss +161 -161
- package/styles/components/_table.scss +81 -81
- package/styles/components/_typeahead.scss +275 -275
- package/styles/components/_variables.scss +89 -89
- package/styles/content-blocks-variables.scss +507 -507
- package/styles/font.scss +2 -2
- package/styles/qsm/_calendar.scss +274 -274
- package/styles/qsm/_qsm.scss +1094 -1094
- package/styles/search.scss +1200 -1200
- package/tsconfig.json +24 -24
package/src/qsm/index.tsx
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Provider } from 'react-redux';
|
|
3
|
-
import QSMConfigurationContext from './qsm-configuration-context';
|
|
4
|
-
import { QSMConfiguration } from './types';
|
|
5
|
-
import QSMContainer from './components/QSMContainer/qsm-container';
|
|
6
|
-
import { createQSMStore } from './store/qsm-store';
|
|
7
|
-
|
|
8
|
-
interface QSMProps {
|
|
9
|
-
configuration: QSMConfiguration;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const QSM: React.FC<QSMProps> = ({ configuration }) => {
|
|
13
|
-
const store = React.useMemo(() => createQSMStore(), []);
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div id="booking-qsm">
|
|
17
|
-
<Provider store={store}>
|
|
18
|
-
<QSMConfigurationContext.Provider value={configuration}>
|
|
19
|
-
<QSMContainer />
|
|
20
|
-
</QSMConfigurationContext.Provider>
|
|
21
|
-
</Provider>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export default QSM;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Provider } from 'react-redux';
|
|
3
|
+
import QSMConfigurationContext from './qsm-configuration-context';
|
|
4
|
+
import { QSMConfiguration } from './types';
|
|
5
|
+
import QSMContainer from './components/QSMContainer/qsm-container';
|
|
6
|
+
import { createQSMStore } from './store/qsm-store';
|
|
7
|
+
|
|
8
|
+
interface QSMProps {
|
|
9
|
+
configuration: QSMConfiguration;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const QSM: React.FC<QSMProps> = ({ configuration }) => {
|
|
13
|
+
const store = React.useMemo(() => createQSMStore(), []);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div id="booking-qsm">
|
|
17
|
+
<Provider store={store}>
|
|
18
|
+
<QSMConfigurationContext.Provider value={configuration}>
|
|
19
|
+
<QSMContainer />
|
|
20
|
+
</QSMConfigurationContext.Provider>
|
|
21
|
+
</Provider>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default QSM;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import qsmReducer from './qsm-slice';
|
|
3
|
-
|
|
4
|
-
export const createQSMStore = () =>
|
|
5
|
-
configureStore({
|
|
6
|
-
reducer: {
|
|
7
|
-
qsm: qsmReducer
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export type QSMStore = ReturnType<typeof createQSMStore>;
|
|
12
|
-
export type QSMRootState = ReturnType<QSMStore['getState']>;
|
|
13
|
-
export type QSMDispatch = QSMStore['dispatch'];
|
|
1
|
+
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
+
import qsmReducer from './qsm-slice';
|
|
3
|
+
|
|
4
|
+
export const createQSMStore = () =>
|
|
5
|
+
configureStore({
|
|
6
|
+
reducer: {
|
|
7
|
+
qsm: qsmReducer
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type QSMStore = ReturnType<typeof createQSMStore>;
|
|
12
|
+
export type QSMRootState = ReturnType<QSMStore['getState']>;
|
|
13
|
+
export type QSMDispatch = QSMStore['dispatch'];
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import React, { useContext } from 'react';
|
|
2
|
-
import { FlightResult } from '../../types';
|
|
3
|
-
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
|
|
4
|
-
import FlightLegComponent from './flight-leg';
|
|
5
|
-
|
|
6
|
-
interface FlightCardProps {
|
|
7
|
-
result: FlightResult;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const FlightCard: React.FC<FlightCardProps> = ({ result }) => {
|
|
11
|
-
const context = useContext(SearchResultsConfigurationContext);
|
|
12
|
-
return (
|
|
13
|
-
<div className="search__result search__result--flight">
|
|
14
|
-
{/* -------------------- flightcard -------------------- */}
|
|
15
|
-
<div className="search__flight-card">
|
|
16
|
-
{/* outbound part */}
|
|
17
|
-
<FlightLegComponent leg={result.outbound} />
|
|
18
|
-
|
|
19
|
-
{/* return part */}
|
|
20
|
-
<FlightLegComponent leg={result.return} />
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
{/* -------------------- pricecard -------------------- */}
|
|
24
|
-
<div className="search__price-card">
|
|
25
|
-
<div className="search__price-card-price-wrapper">
|
|
26
|
-
<p className="search__price-card-price">{result.price}</p>
|
|
27
|
-
</div>
|
|
28
|
-
<div>
|
|
29
|
-
<button className="search__price-card-button" onClick={() => console.log('clicked result with ID:', result.id)}>
|
|
30
|
-
{result.ctaText}
|
|
31
|
-
</button>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export default FlightCard;
|
|
1
|
+
import React, { useContext } from 'react';
|
|
2
|
+
import { FlightResult } from '../../types';
|
|
3
|
+
import SearchResultsConfigurationContext from '../../search-results-configuration-context';
|
|
4
|
+
import FlightLegComponent from './flight-leg';
|
|
5
|
+
|
|
6
|
+
interface FlightCardProps {
|
|
7
|
+
result: FlightResult;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const FlightCard: React.FC<FlightCardProps> = ({ result }) => {
|
|
11
|
+
const context = useContext(SearchResultsConfigurationContext);
|
|
12
|
+
return (
|
|
13
|
+
<div className="search__result search__result--flight">
|
|
14
|
+
{/* -------------------- flightcard -------------------- */}
|
|
15
|
+
<div className="search__flight-card">
|
|
16
|
+
{/* outbound part */}
|
|
17
|
+
<FlightLegComponent leg={result.outbound} />
|
|
18
|
+
|
|
19
|
+
{/* return part */}
|
|
20
|
+
<FlightLegComponent leg={result.return} />
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
{/* -------------------- pricecard -------------------- */}
|
|
24
|
+
<div className="search__price-card">
|
|
25
|
+
<div className="search__price-card-price-wrapper">
|
|
26
|
+
<p className="search__price-card-price">{result.price}</p>
|
|
27
|
+
</div>
|
|
28
|
+
<div>
|
|
29
|
+
<button className="search__price-card-button" onClick={() => console.log('clicked result with ID:', result.id)}>
|
|
30
|
+
{result.ctaText}
|
|
31
|
+
</button>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default FlightCard;
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { FlightLeg } from '../../types';
|
|
3
|
-
import { formatDate, formatTime } from '../../../shared/utils/localization-util';
|
|
4
|
-
import FlightPath from './flight-path';
|
|
5
|
-
import FlightBannerComponent from './flight-banner';
|
|
6
|
-
|
|
7
|
-
interface FlightLegProps {
|
|
8
|
-
leg: FlightLeg;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const FlightLegComponent: React.FC<FlightLegProps> = ({ leg }) => {
|
|
12
|
-
return leg ? (
|
|
13
|
-
<div className="search__flight-card-content-top">
|
|
14
|
-
<div className="search__flight-card-content">
|
|
15
|
-
<div className="search__flight-card-content-start">
|
|
16
|
-
<div className="search__flight-card-content-start-time">
|
|
17
|
-
<svg className="search__flight-card-content-icon" id="search-flightLeg-plane-depart-icon" viewBox="0 0 11.477 9.98" width={11.48} height={9.98}>
|
|
18
|
-
<path
|
|
19
|
-
id="connecting_airports_16dp_UNDEFINED_FILL0_wght400_GRAD0_opsz20"
|
|
20
|
-
d="M106.978-871.035l-2.245-3.493h-2.994a1.2,1.2,0,0,1-.884-.364,1.2,1.2,0,0,1-.364-.884,1.2,1.2,0,0,1,.364-.884,1.2,1.2,0,0,1,.884-.364H104.4l2.578-3.992h1.5l-1.247,3.992h2.162l1.081-1.5h1.5l-1,2.744,1,2.744h-1.5l-1.081-1.5h-2l1.081,3.493Z"
|
|
21
|
-
transform="translate(111.967 -871.035) rotate(180)"
|
|
22
|
-
fill="#57abb2"
|
|
23
|
-
/>
|
|
24
|
-
</svg>
|
|
25
|
-
<h5>{formatTime(leg.departureDateTime)}</h5>
|
|
26
|
-
</div>
|
|
27
|
-
<p className="search__flight-card-content-start-destination">{leg.departureAirport}</p>
|
|
28
|
-
<p className="search__flight-card-content-start-date">{formatDate(leg.departureDateTime)}</p>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<div className="search__flight-card-content-stops">
|
|
32
|
-
<p className="search__flight-card-content-stops-info-hour">{leg.duration}</p>
|
|
33
|
-
<FlightPath stops={leg.stops} />
|
|
34
|
-
<div className="search__flight-card-content-stops-info">
|
|
35
|
-
<svg className="search__flight-card-content-icon" id="search-flightLeg-stop-icon" viewBox="0 0 14.969 10.978" width={14.97} height={10.98}>
|
|
36
|
-
<path
|
|
37
|
-
id="airline_stops_16dp_UNDEFINED_FILL0_wght400_GRAD0_opsz20"
|
|
38
|
-
d="M101.738-733.022v-1.5h1.5a5.842,5.842,0,0,0-2.162-4.647A7.583,7.583,0,0,0,96-741.006v-1.5a9.357,9.357,0,0,1,4.709,1.237,7.929,7.929,0,0,1,3.275,3.5,8.25,8.25,0,0,1,2-2.692A20.272,20.272,0,0,1,108.7-742.5h-3.223V-744h5.489v5.489h-1.5v-2.724a13.531,13.531,0,0,0-3.327,2.838,5.83,5.83,0,0,0-1.414,3.878h1.5v1.5Z"
|
|
39
|
-
transform="translate(-96 744)"
|
|
40
|
-
fill="#57abb2"
|
|
41
|
-
/>
|
|
42
|
-
</svg>
|
|
43
|
-
<p className="search__flight-card-content-stops-info-text">
|
|
44
|
-
{leg.stops} stop{leg.stops !== 1 ? 's' : ''}
|
|
45
|
-
</p>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<div className="search__flight-card-content-end">
|
|
50
|
-
<h5 className="search__flight-card-content-end-time">{formatTime(leg.arrivalDateTime)}</h5>
|
|
51
|
-
<p className="search__flight-card-content-end-destination">{leg.arrivalAirport}</p>
|
|
52
|
-
<p className="search__flight-card-content-end-date">{formatDate(leg.arrivalDateTime)}</p>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<FlightBannerComponent tag={leg.airline} luggageIncluded={leg.luggageIncluded} />
|
|
57
|
-
</div>
|
|
58
|
-
) : null;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export default FlightLegComponent;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlightLeg } from '../../types';
|
|
3
|
+
import { formatDate, formatTime } from '../../../shared/utils/localization-util';
|
|
4
|
+
import FlightPath from './flight-path';
|
|
5
|
+
import FlightBannerComponent from './flight-banner';
|
|
6
|
+
|
|
7
|
+
interface FlightLegProps {
|
|
8
|
+
leg: FlightLeg;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const FlightLegComponent: React.FC<FlightLegProps> = ({ leg }) => {
|
|
12
|
+
return leg ? (
|
|
13
|
+
<div className="search__flight-card-content-top">
|
|
14
|
+
<div className="search__flight-card-content">
|
|
15
|
+
<div className="search__flight-card-content-start">
|
|
16
|
+
<div className="search__flight-card-content-start-time">
|
|
17
|
+
<svg className="search__flight-card-content-icon" id="search-flightLeg-plane-depart-icon" viewBox="0 0 11.477 9.98" width={11.48} height={9.98}>
|
|
18
|
+
<path
|
|
19
|
+
id="connecting_airports_16dp_UNDEFINED_FILL0_wght400_GRAD0_opsz20"
|
|
20
|
+
d="M106.978-871.035l-2.245-3.493h-2.994a1.2,1.2,0,0,1-.884-.364,1.2,1.2,0,0,1-.364-.884,1.2,1.2,0,0,1,.364-.884,1.2,1.2,0,0,1,.884-.364H104.4l2.578-3.992h1.5l-1.247,3.992h2.162l1.081-1.5h1.5l-1,2.744,1,2.744h-1.5l-1.081-1.5h-2l1.081,3.493Z"
|
|
21
|
+
transform="translate(111.967 -871.035) rotate(180)"
|
|
22
|
+
fill="#57abb2"
|
|
23
|
+
/>
|
|
24
|
+
</svg>
|
|
25
|
+
<h5>{formatTime(leg.departureDateTime)}</h5>
|
|
26
|
+
</div>
|
|
27
|
+
<p className="search__flight-card-content-start-destination">{leg.departureAirport}</p>
|
|
28
|
+
<p className="search__flight-card-content-start-date">{formatDate(leg.departureDateTime)}</p>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div className="search__flight-card-content-stops">
|
|
32
|
+
<p className="search__flight-card-content-stops-info-hour">{leg.duration}</p>
|
|
33
|
+
<FlightPath stops={leg.stops} />
|
|
34
|
+
<div className="search__flight-card-content-stops-info">
|
|
35
|
+
<svg className="search__flight-card-content-icon" id="search-flightLeg-stop-icon" viewBox="0 0 14.969 10.978" width={14.97} height={10.98}>
|
|
36
|
+
<path
|
|
37
|
+
id="airline_stops_16dp_UNDEFINED_FILL0_wght400_GRAD0_opsz20"
|
|
38
|
+
d="M101.738-733.022v-1.5h1.5a5.842,5.842,0,0,0-2.162-4.647A7.583,7.583,0,0,0,96-741.006v-1.5a9.357,9.357,0,0,1,4.709,1.237,7.929,7.929,0,0,1,3.275,3.5,8.25,8.25,0,0,1,2-2.692A20.272,20.272,0,0,1,108.7-742.5h-3.223V-744h5.489v5.489h-1.5v-2.724a13.531,13.531,0,0,0-3.327,2.838,5.83,5.83,0,0,0-1.414,3.878h1.5v1.5Z"
|
|
39
|
+
transform="translate(-96 744)"
|
|
40
|
+
fill="#57abb2"
|
|
41
|
+
/>
|
|
42
|
+
</svg>
|
|
43
|
+
<p className="search__flight-card-content-stops-info-text">
|
|
44
|
+
{leg.stops} stop{leg.stops !== 1 ? 's' : ''}
|
|
45
|
+
</p>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div className="search__flight-card-content-end">
|
|
50
|
+
<h5 className="search__flight-card-content-end-time">{formatTime(leg.arrivalDateTime)}</h5>
|
|
51
|
+
<p className="search__flight-card-content-end-destination">{leg.arrivalAirport}</p>
|
|
52
|
+
<p className="search__flight-card-content-end-date">{formatDate(leg.arrivalDateTime)}</p>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<FlightBannerComponent tag={leg.airline} luggageIncluded={leg.luggageIncluded} />
|
|
57
|
+
</div>
|
|
58
|
+
) : null;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default FlightLegComponent;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
interface FlightPathProps {
|
|
4
|
-
stops?: number;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const FlightPath: React.FC<FlightPathProps> = ({ stops = 0 }) => {
|
|
8
|
-
return (
|
|
9
|
-
<div className="flight-path">
|
|
10
|
-
<div className="flight-path__point flight-path__point--start"></div>
|
|
11
|
-
|
|
12
|
-
<div className="flight-path__line">
|
|
13
|
-
{Array.from({ length: stops }, (_, index) => (
|
|
14
|
-
<div key={index} className="flight-path__stop"></div>
|
|
15
|
-
))}
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<div className="flight-path__point flight-path__point--end"></div>
|
|
19
|
-
</div>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export default FlightPath;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface FlightPathProps {
|
|
4
|
+
stops?: number;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const FlightPath: React.FC<FlightPathProps> = ({ stops = 0 }) => {
|
|
8
|
+
return (
|
|
9
|
+
<div className="flight-path">
|
|
10
|
+
<div className="flight-path__point flight-path__point--start"></div>
|
|
11
|
+
|
|
12
|
+
<div className="flight-path__line">
|
|
13
|
+
{Array.from({ length: stops }, (_, index) => (
|
|
14
|
+
<div key={index} className="flight-path__stop"></div>
|
|
15
|
+
))}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div className="flight-path__point flight-path__point--end"></div>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default FlightPath;
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import React, { ChangeEvent, useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
interface MultiRangeFilterProps {
|
|
4
|
-
min: number;
|
|
5
|
-
max: number;
|
|
6
|
-
selectedMin: number;
|
|
7
|
-
selectedMax: number;
|
|
8
|
-
valueFormatter: (value: number) => string;
|
|
9
|
-
onChange: (min: number, max: number) => void;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const MultiRangeFilter: React.FC<MultiRangeFilterProps> = ({ min, max, selectedMin, selectedMax, valueFormatter, onChange }) => {
|
|
13
|
-
const [isDragging, setIsDragging] = useState(false);
|
|
14
|
-
const [leftPercentage, setLeftPercentage] = useState<number>(0);
|
|
15
|
-
const [rightPercentage, setRightPercentage] = useState<number>(0);
|
|
16
|
-
const [minVal, setMinVal] = useState(selectedMin ?? min);
|
|
17
|
-
const [maxVal, setMaxVal] = useState(selectedMax ?? max);
|
|
18
|
-
const minGap = 5;
|
|
19
|
-
|
|
20
|
-
// Sync internal state with external selectedMin/selectedMax changes
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
setMinVal(selectedMin ?? min);
|
|
23
|
-
setMaxVal(selectedMax ?? max);
|
|
24
|
-
}, [min, max, selectedMin, selectedMax]);
|
|
25
|
-
|
|
26
|
-
// Recalculate slider track whenever values change
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
const range = max - min || 1;
|
|
29
|
-
const minPercent = ((minVal - min) / range) * 100;
|
|
30
|
-
const maxPercent = ((maxVal - min) / range) * 100;
|
|
31
|
-
|
|
32
|
-
setLeftPercentage(minPercent);
|
|
33
|
-
setRightPercentage(100 - maxPercent);
|
|
34
|
-
}, [minVal, maxVal, min, max]);
|
|
35
|
-
|
|
36
|
-
const slideMin = (e: ChangeEvent<HTMLInputElement>) => {
|
|
37
|
-
const value = parseInt(e.target.value, 10);
|
|
38
|
-
|
|
39
|
-
// Ensure the thumbs don’t cross and enforce minGap
|
|
40
|
-
if (value <= maxVal - minGap) {
|
|
41
|
-
setMinVal(value);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const slideMax = (e: ChangeEvent<HTMLInputElement>) => {
|
|
46
|
-
const value = parseInt(e.target.value, 10);
|
|
47
|
-
|
|
48
|
-
// Ensure the thumbs don’t cross and enforce minGap
|
|
49
|
-
if (value >= minVal + minGap) {
|
|
50
|
-
setMaxVal(value);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const startDrag = () => {
|
|
55
|
-
setIsDragging(true);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const stopDrag = () => {
|
|
59
|
-
setIsDragging(false);
|
|
60
|
-
// Notify parent with the final values
|
|
61
|
-
onChange(minVal, maxVal);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<div className="double-slider-box">
|
|
66
|
-
<div className="input-box">
|
|
67
|
-
{/* Show currently selected range */}
|
|
68
|
-
<div className="min-box">{valueFormatter(minVal)}</div>
|
|
69
|
-
<div className="max-box">{valueFormatter(maxVal)}</div>
|
|
70
|
-
</div>
|
|
71
|
-
<div className="range-slider">
|
|
72
|
-
<div className="slider-track" style={{ left: `${leftPercentage}%`, right: `${rightPercentage}%` }} />
|
|
73
|
-
<input
|
|
74
|
-
type="range"
|
|
75
|
-
min={min}
|
|
76
|
-
max={max}
|
|
77
|
-
value={minVal}
|
|
78
|
-
onChange={slideMin}
|
|
79
|
-
onMouseDown={startDrag}
|
|
80
|
-
onMouseUp={stopDrag}
|
|
81
|
-
onTouchStart={startDrag}
|
|
82
|
-
onTouchEnd={stopDrag}
|
|
83
|
-
className="min-val"
|
|
84
|
-
/>
|
|
85
|
-
<input
|
|
86
|
-
type="range"
|
|
87
|
-
min={min}
|
|
88
|
-
max={max}
|
|
89
|
-
value={maxVal}
|
|
90
|
-
onChange={slideMax}
|
|
91
|
-
onMouseDown={startDrag}
|
|
92
|
-
onMouseUp={stopDrag}
|
|
93
|
-
onTouchStart={startDrag}
|
|
94
|
-
onTouchEnd={stopDrag}
|
|
95
|
-
className="max-val"
|
|
96
|
-
/>
|
|
97
|
-
{isDragging && <div className="min-tooltip">{valueFormatter(minVal)}</div>}
|
|
98
|
-
{isDragging && <div className="max-tooltip">{valueFormatter(maxVal)}</div>}
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export default MultiRangeFilter;
|
|
1
|
+
import React, { ChangeEvent, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
interface MultiRangeFilterProps {
|
|
4
|
+
min: number;
|
|
5
|
+
max: number;
|
|
6
|
+
selectedMin: number;
|
|
7
|
+
selectedMax: number;
|
|
8
|
+
valueFormatter: (value: number) => string;
|
|
9
|
+
onChange: (min: number, max: number) => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const MultiRangeFilter: React.FC<MultiRangeFilterProps> = ({ min, max, selectedMin, selectedMax, valueFormatter, onChange }) => {
|
|
13
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
14
|
+
const [leftPercentage, setLeftPercentage] = useState<number>(0);
|
|
15
|
+
const [rightPercentage, setRightPercentage] = useState<number>(0);
|
|
16
|
+
const [minVal, setMinVal] = useState(selectedMin ?? min);
|
|
17
|
+
const [maxVal, setMaxVal] = useState(selectedMax ?? max);
|
|
18
|
+
const minGap = 5;
|
|
19
|
+
|
|
20
|
+
// Sync internal state with external selectedMin/selectedMax changes
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setMinVal(selectedMin ?? min);
|
|
23
|
+
setMaxVal(selectedMax ?? max);
|
|
24
|
+
}, [min, max, selectedMin, selectedMax]);
|
|
25
|
+
|
|
26
|
+
// Recalculate slider track whenever values change
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const range = max - min || 1;
|
|
29
|
+
const minPercent = ((minVal - min) / range) * 100;
|
|
30
|
+
const maxPercent = ((maxVal - min) / range) * 100;
|
|
31
|
+
|
|
32
|
+
setLeftPercentage(minPercent);
|
|
33
|
+
setRightPercentage(100 - maxPercent);
|
|
34
|
+
}, [minVal, maxVal, min, max]);
|
|
35
|
+
|
|
36
|
+
const slideMin = (e: ChangeEvent<HTMLInputElement>) => {
|
|
37
|
+
const value = parseInt(e.target.value, 10);
|
|
38
|
+
|
|
39
|
+
// Ensure the thumbs don’t cross and enforce minGap
|
|
40
|
+
if (value <= maxVal - minGap) {
|
|
41
|
+
setMinVal(value);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const slideMax = (e: ChangeEvent<HTMLInputElement>) => {
|
|
46
|
+
const value = parseInt(e.target.value, 10);
|
|
47
|
+
|
|
48
|
+
// Ensure the thumbs don’t cross and enforce minGap
|
|
49
|
+
if (value >= minVal + minGap) {
|
|
50
|
+
setMaxVal(value);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const startDrag = () => {
|
|
55
|
+
setIsDragging(true);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const stopDrag = () => {
|
|
59
|
+
setIsDragging(false);
|
|
60
|
+
// Notify parent with the final values
|
|
61
|
+
onChange(minVal, maxVal);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<div className="double-slider-box">
|
|
66
|
+
<div className="input-box">
|
|
67
|
+
{/* Show currently selected range */}
|
|
68
|
+
<div className="min-box">{valueFormatter(minVal)}</div>
|
|
69
|
+
<div className="max-box">{valueFormatter(maxVal)}</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div className="range-slider">
|
|
72
|
+
<div className="slider-track" style={{ left: `${leftPercentage}%`, right: `${rightPercentage}%` }} />
|
|
73
|
+
<input
|
|
74
|
+
type="range"
|
|
75
|
+
min={min}
|
|
76
|
+
max={max}
|
|
77
|
+
value={minVal}
|
|
78
|
+
onChange={slideMin}
|
|
79
|
+
onMouseDown={startDrag}
|
|
80
|
+
onMouseUp={stopDrag}
|
|
81
|
+
onTouchStart={startDrag}
|
|
82
|
+
onTouchEnd={stopDrag}
|
|
83
|
+
className="min-val"
|
|
84
|
+
/>
|
|
85
|
+
<input
|
|
86
|
+
type="range"
|
|
87
|
+
min={min}
|
|
88
|
+
max={max}
|
|
89
|
+
value={maxVal}
|
|
90
|
+
onChange={slideMax}
|
|
91
|
+
onMouseDown={startDrag}
|
|
92
|
+
onMouseUp={stopDrag}
|
|
93
|
+
onTouchStart={startDrag}
|
|
94
|
+
onTouchEnd={stopDrag}
|
|
95
|
+
className="max-val"
|
|
96
|
+
/>
|
|
97
|
+
{isDragging && <div className="min-tooltip">{valueFormatter(minVal)}</div>}
|
|
98
|
+
{isDragging && <div className="max-tooltip">{valueFormatter(maxVal)}</div>}
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default MultiRangeFilter;
|
|
@@ -151,6 +151,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
151
151
|
|
|
152
152
|
var searchRequest = {
|
|
153
153
|
officeId: 1,
|
|
154
|
+
agentId: context?.agentId,
|
|
154
155
|
payload: {
|
|
155
156
|
catalogueIds: context!.tideConnection.catalogueIds ?? [],
|
|
156
157
|
serviceType:
|
|
@@ -228,6 +229,7 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
228
229
|
|
|
229
230
|
var searchRequest = {
|
|
230
231
|
officeId: 1,
|
|
232
|
+
agentId: context?.agentId,
|
|
231
233
|
payload: {
|
|
232
234
|
catalogueIds: context!.tideConnection.catalogueIds ?? [],
|
|
233
235
|
serviceType:
|
|
@@ -474,8 +476,6 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
474
476
|
|
|
475
477
|
searchRequest = rq;
|
|
476
478
|
}
|
|
477
|
-
|
|
478
|
-
searchRequest.agentId = context.agentId;
|
|
479
479
|
const packageSearchResults = await search(config, searchRequest);
|
|
480
480
|
|
|
481
481
|
console.log('Search results', packageSearchResults);
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Provider } from 'react-redux';
|
|
3
|
-
import SearchResultsConfigurationContext from './search-results-configuration-context';
|
|
4
|
-
import { SearchResultsConfiguration } from './types';
|
|
5
|
-
import SearchResultsContainer from './components/search-results-container/search-results-container';
|
|
6
|
-
import { createSearchResultsStore } from './store/search-results-store';
|
|
7
|
-
|
|
8
|
-
interface SearchResultsProps {
|
|
9
|
-
configuration: SearchResultsConfiguration;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const SearchResults: React.FC<SearchResultsProps> = ({ configuration }) => {
|
|
13
|
-
const store = React.useMemo(() => createSearchResultsStore(), []);
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<Provider store={store}>
|
|
17
|
-
<SearchResultsConfigurationContext.Provider value={configuration}>
|
|
18
|
-
<SearchResultsContainer />
|
|
19
|
-
</SearchResultsConfigurationContext.Provider>
|
|
20
|
-
</Provider>
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export default SearchResults;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Provider } from 'react-redux';
|
|
3
|
+
import SearchResultsConfigurationContext from './search-results-configuration-context';
|
|
4
|
+
import { SearchResultsConfiguration } from './types';
|
|
5
|
+
import SearchResultsContainer from './components/search-results-container/search-results-container';
|
|
6
|
+
import { createSearchResultsStore } from './store/search-results-store';
|
|
7
|
+
|
|
8
|
+
interface SearchResultsProps {
|
|
9
|
+
configuration: SearchResultsConfiguration;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const SearchResults: React.FC<SearchResultsProps> = ({ configuration }) => {
|
|
13
|
+
const store = React.useMemo(() => createSearchResultsStore(), []);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Provider store={store}>
|
|
17
|
+
<SearchResultsConfigurationContext.Provider value={configuration}>
|
|
18
|
+
<SearchResultsContainer />
|
|
19
|
+
</SearchResultsConfigurationContext.Provider>
|
|
20
|
+
</Provider>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default SearchResults;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { SearchResultsConfiguration } from './types';
|
|
3
|
-
|
|
4
|
-
const SearchResultsConfigurationContext = React.createContext<SearchResultsConfiguration | undefined>(undefined);
|
|
5
|
-
|
|
6
|
-
export default SearchResultsConfigurationContext;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SearchResultsConfiguration } from './types';
|
|
3
|
+
|
|
4
|
+
const SearchResultsConfigurationContext = React.createContext<SearchResultsConfiguration | undefined>(undefined);
|
|
5
|
+
|
|
6
|
+
export default SearchResultsConfigurationContext;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import searchResultsReducer from './search-results-slice';
|
|
3
|
-
|
|
4
|
-
export const createSearchResultsStore = () =>
|
|
5
|
-
configureStore({
|
|
6
|
-
reducer: {
|
|
7
|
-
searchResults: searchResultsReducer
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
export type SearchResultsStore = ReturnType<typeof createSearchResultsStore>;
|
|
12
|
-
export type SearchResultsRootState = ReturnType<SearchResultsStore['getState']>;
|
|
13
|
-
export type SearchResultsDispatch = SearchResultsStore['dispatch'];
|
|
1
|
+
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
+
import searchResultsReducer from './search-results-slice';
|
|
3
|
+
|
|
4
|
+
export const createSearchResultsStore = () =>
|
|
5
|
+
configureStore({
|
|
6
|
+
reducer: {
|
|
7
|
+
searchResults: searchResultsReducer
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type SearchResultsStore = ReturnType<typeof createSearchResultsStore>;
|
|
12
|
+
export type SearchResultsRootState = ReturnType<SearchResultsStore['getState']>;
|
|
13
|
+
export type SearchResultsDispatch = SearchResultsStore['dispatch'];
|