@qite/tide-booking-component 1.4.33 → 1.4.35
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 +1674 -416
- package/build/build-cjs/qsm/types.d.ts +0 -1
- package/build/build-cjs/search-results/components/filters/filters.d.ts +2 -2
- package/build/build-cjs/search-results/components/flight/flight-results.d.ts +2 -0
- package/build/build-cjs/search-results/components/hotel/hotel-card.d.ts +1 -0
- package/build/build-cjs/search-results/components/itinerary/index.d.ts +2 -2
- package/build/build-cjs/search-results/store/search-results-slice.d.ts +11 -2
- package/build/build-cjs/search-results/types.d.ts +0 -14
- package/build/build-esm/index.js +1674 -416
- package/build/build-esm/qsm/types.d.ts +0 -1
- package/build/build-esm/search-results/components/filters/filters.d.ts +2 -2
- package/build/build-esm/search-results/components/flight/flight-results.d.ts +2 -0
- package/build/build-esm/search-results/components/hotel/hotel-card.d.ts +1 -0
- package/build/build-esm/search-results/components/itinerary/index.d.ts +2 -2
- package/build/build-esm/search-results/store/search-results-slice.d.ts +11 -2
- package/build/build-esm/search-results/types.d.ts +0 -14
- package/package.json +77 -77
- package/src/booking-product/components/product.tsx +26 -22
- package/src/booking-wizard/features/booking/booking-self-contained.tsx +303 -304
- package/src/booking-wizard/features/travelers-form/controls/gender-control.tsx +5 -5
- package/src/booking-wizard/features/travelers-form/travelers-form.tsx +10 -10
- package/src/content/components/icon.tsx +1 -1
- package/src/content/features/content-page/content-page-self-contained.tsx +0 -1
- package/src/qsm/components/QSMContainer/qsm-container.tsx +217 -218
- package/src/qsm/components/mobile-filter-modal/index.tsx +12 -10
- package/src/qsm/components/travel-class-picker/index.tsx +5 -3
- package/src/qsm/components/travel-input/index.tsx +15 -12
- package/src/qsm/components/travel-input-group/index.tsx +14 -3
- package/src/qsm/components/travel-nationality-picker/index.tsx +5 -3
- package/src/qsm/components/travel-type-picker/index.tsx +5 -3
- package/src/qsm/qsm-configuration-context.ts +0 -1
- package/src/qsm/store/qsm-slice.ts +261 -261
- package/src/qsm/types.ts +144 -145
- package/src/search-results/components/filters/filters.tsx +15 -16
- package/src/search-results/components/flight/flight-results.tsx +168 -1099
- package/src/search-results/components/hotel/hotel-accommodation-results.tsx +21 -24
- package/src/search-results/components/hotel/hotel-card.tsx +4 -3
- package/src/search-results/components/icon.tsx +1 -1
- package/src/search-results/components/itinerary/index.tsx +229 -129
- package/src/search-results/components/round-trip/round-trip-results.tsx +1 -1
- package/src/search-results/components/search-results-container/search-results-container.tsx +353 -337
- package/src/search-results/components/spinner/spinner.tsx +3 -1
- package/src/search-results/components/tab-views/index.tsx +13 -7
- package/src/search-results/features/flights/flight-search-results-self-contained.tsx +1 -14
- package/src/search-results/features/hotels/hotel-search-results-self-contained.tsx +1 -14
- package/src/search-results/store/search-results-slice.ts +37 -3
- package/src/search-results/types.ts +0 -15
- package/src/shared/translations/ar-SA.json +70 -0
- package/src/shared/translations/da-DK.json +70 -0
- package/src/shared/translations/de-DE.json +70 -0
- package/src/shared/translations/en-GB.json +71 -1
- package/src/shared/translations/es-ES.json +70 -0
- package/src/shared/translations/fr-BE.json +71 -1
- package/src/shared/translations/fr-FR.json +70 -0
- package/src/shared/translations/is-IS.json +72 -2
- package/src/shared/translations/it-IT.json +70 -0
- package/src/shared/translations/ja-JP.json +72 -2
- package/src/shared/translations/nl-BE.json +70 -0
- package/src/shared/translations/nl-NL.json +70 -0
- package/src/shared/translations/no-NO.json +72 -2
- package/src/shared/translations/pl-PL.json +70 -0
- package/src/shared/translations/pt-PT.json +70 -0
- package/src/shared/translations/sv-SE.json +72 -2
- package/styles/components/_search.scss +7 -1
|
@@ -615,7 +615,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
615
615
|
<>
|
|
616
616
|
<div className="form__row">
|
|
617
617
|
<div className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].adults[${index}].gender`) && 'form__group--error'])}>
|
|
618
|
-
<label className="form__label">{translations.TRAVELERS_FORM.
|
|
618
|
+
<label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
|
|
619
619
|
<div className="radiobutton-group">
|
|
620
620
|
<div className="radiobutton">
|
|
621
621
|
<label className="radiobutton__label">
|
|
@@ -628,7 +628,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
628
628
|
value="m"
|
|
629
629
|
checked={travelerValues.gender === 'm'}
|
|
630
630
|
/>
|
|
631
|
-
{translations.TRAVELERS_FORM.
|
|
631
|
+
{translations.TRAVELERS_FORM.MALE_GENDER}
|
|
632
632
|
</label>
|
|
633
633
|
</div>
|
|
634
634
|
|
|
@@ -643,11 +643,11 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
643
643
|
value="f"
|
|
644
644
|
checked={travelerValues.gender === 'f'}
|
|
645
645
|
/>
|
|
646
|
-
{translations.TRAVELERS_FORM.
|
|
646
|
+
{translations.TRAVELERS_FORM.FEMALE_GENDER}
|
|
647
647
|
</label>
|
|
648
648
|
</div>
|
|
649
649
|
|
|
650
|
-
<div className="radiobutton">
|
|
650
|
+
{/* <div className="radiobutton">
|
|
651
651
|
<label className="radiobutton__label">
|
|
652
652
|
<input
|
|
653
653
|
type="radio"
|
|
@@ -660,7 +660,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
660
660
|
/>
|
|
661
661
|
{translations.TRAVELERS_FORM.OTHER}
|
|
662
662
|
</label>
|
|
663
|
-
</div>
|
|
663
|
+
</div> */}
|
|
664
664
|
</div>
|
|
665
665
|
</div>
|
|
666
666
|
</div>
|
|
@@ -729,7 +729,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
729
729
|
<div className="form__row">
|
|
730
730
|
<div
|
|
731
731
|
className={buildClassName(['form__group', hasVisibleError(`rooms[${rIndex}].children[${index}].gender`) && 'form__group--error'])}>
|
|
732
|
-
<label className="form__label">{translations.TRAVELERS_FORM.
|
|
732
|
+
<label className="form__label">{translations.TRAVELERS_FORM.GENDER_ID} *</label>
|
|
733
733
|
<div className="radiobutton-group">
|
|
734
734
|
<div className="radiobutton">
|
|
735
735
|
<label className="radiobutton__label">
|
|
@@ -742,7 +742,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
742
742
|
value="m"
|
|
743
743
|
checked={travelerValues.gender === 'm'}
|
|
744
744
|
/>
|
|
745
|
-
{translations.TRAVELERS_FORM.
|
|
745
|
+
{translations.TRAVELERS_FORM.MALE_GENDER}
|
|
746
746
|
</label>
|
|
747
747
|
</div>
|
|
748
748
|
|
|
@@ -757,11 +757,11 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
757
757
|
value="f"
|
|
758
758
|
checked={travelerValues.gender === 'f'}
|
|
759
759
|
/>
|
|
760
|
-
{translations.TRAVELERS_FORM.
|
|
760
|
+
{translations.TRAVELERS_FORM.FEMALE_GENDER}
|
|
761
761
|
</label>
|
|
762
762
|
</div>
|
|
763
763
|
|
|
764
|
-
<div className="radiobutton">
|
|
764
|
+
{/* <div className="radiobutton">
|
|
765
765
|
<label className="radiobutton__label">
|
|
766
766
|
<input
|
|
767
767
|
type="radio"
|
|
@@ -774,7 +774,7 @@ const TravelersForm: React.FC<TravelersFormProps> = () => {
|
|
|
774
774
|
/>
|
|
775
775
|
{translations.TRAVELERS_FORM.OTHER}
|
|
776
776
|
</label>
|
|
777
|
-
</div>
|
|
777
|
+
</div> */}
|
|
778
778
|
</div>
|
|
779
779
|
</div>
|
|
780
780
|
</div>
|
|
@@ -530,7 +530,7 @@ const Icon: React.FC<IconProps> = ({ name, className, title, width, height }) =>
|
|
|
530
530
|
</svg>
|
|
531
531
|
);
|
|
532
532
|
|
|
533
|
-
case 'ui-
|
|
533
|
+
case 'ui-list':
|
|
534
534
|
return (
|
|
535
535
|
<svg
|
|
536
536
|
className={['icon', `icon--${name}`, className].filter((className) => !isEmpty(className)).join(' ')}
|
|
@@ -1,218 +1,217 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useMemo } from 'react';
|
|
2
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
3
|
-
import { QSMRootState } from '../../store/qsm-store';
|
|
4
|
-
import QSMConfigurationContext from '../../qsm-configuration-context';
|
|
5
|
-
import useMediaQuery from '../../../shared/utils/use-media-query-util';
|
|
6
|
-
import MobileFilterModal from '../mobile-filter-modal';
|
|
7
|
-
import SearchInputGroup from '../search-input-group';
|
|
8
|
-
import DoubleSearchInputGroup from '../double-search-input-group';
|
|
9
|
-
import Dates from '../../../booking-product/components/dates';
|
|
10
|
-
import TravelInputGroup from '../travel-input-group';
|
|
11
|
-
import TravelClassPicker from '../travel-class-picker';
|
|
12
|
-
import TravelTypePicker from '../travel-type-picker';
|
|
13
|
-
import Icon from '../icon';
|
|
14
|
-
import TravelNationalityPicker from '../travel-nationality-picker';
|
|
15
|
-
import { addDays, addMonths } from 'date-fns';
|
|
16
|
-
import { DateRange } from '../../../booking-product/types';
|
|
17
|
-
import { QSMState, setFromDate, setToDate } from '../../store/qsm-slice';
|
|
18
|
-
import { FieldConfig } from '../../types';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rooms
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
<
|
|
191
|
-
<
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
export default QSMContainer;
|
|
1
|
+
import React, { useContext, useEffect, useMemo } from 'react';
|
|
2
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
3
|
+
import { QSMRootState } from '../../store/qsm-store';
|
|
4
|
+
import QSMConfigurationContext from '../../qsm-configuration-context';
|
|
5
|
+
import useMediaQuery from '../../../shared/utils/use-media-query-util';
|
|
6
|
+
import MobileFilterModal from '../mobile-filter-modal';
|
|
7
|
+
import SearchInputGroup from '../search-input-group';
|
|
8
|
+
import DoubleSearchInputGroup from '../double-search-input-group';
|
|
9
|
+
import Dates from '../../../booking-product/components/dates';
|
|
10
|
+
import TravelInputGroup from '../travel-input-group';
|
|
11
|
+
import TravelClassPicker from '../travel-class-picker';
|
|
12
|
+
import TravelTypePicker from '../travel-type-picker';
|
|
13
|
+
import Icon from '../icon';
|
|
14
|
+
import TravelNationalityPicker from '../travel-nationality-picker';
|
|
15
|
+
import { addDays, addMonths } from 'date-fns';
|
|
16
|
+
import { DateRange } from '../../../booking-product/types';
|
|
17
|
+
import { QSMState, setFromDate, setToDate } from '../../store/qsm-slice';
|
|
18
|
+
import { FieldConfig } from '../../types';
|
|
19
|
+
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
20
|
+
|
|
21
|
+
const QSMContainer: React.FC = () => {
|
|
22
|
+
const dispatch = useDispatch();
|
|
23
|
+
const isMobile = useMediaQuery('(max-width: 768px)');
|
|
24
|
+
const qsmState = useSelector((state: QSMRootState) => state.qsm);
|
|
25
|
+
const { mobileFilterType, fromDate, toDate } = qsmState;
|
|
26
|
+
const { searchFields, askTravelers, submitIcon, onSubmit, travelTypes, languageCode } = useContext(QSMConfigurationContext);
|
|
27
|
+
const translations = getTranslations(languageCode ?? 'en-GB');
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (fromDate || toDate) return;
|
|
31
|
+
|
|
32
|
+
const startDate = addMonths(new Date(), 1);
|
|
33
|
+
const endDate = addDays(startDate, 7);
|
|
34
|
+
|
|
35
|
+
dispatch(setFromDate(startDate.toISOString()));
|
|
36
|
+
dispatch(setToDate(endDate.toISOString()));
|
|
37
|
+
}, [fromDate, toDate, dispatch]);
|
|
38
|
+
|
|
39
|
+
const dateRange = useMemo<DateRange | undefined>(() => {
|
|
40
|
+
if (!fromDate || !toDate) return undefined;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
fromDate: new Date(fromDate),
|
|
44
|
+
toDate: new Date(toDate)
|
|
45
|
+
};
|
|
46
|
+
}, [fromDate, toDate]);
|
|
47
|
+
|
|
48
|
+
const handleDateChange = (value: DateRange) => {
|
|
49
|
+
dispatch(setFromDate(value.fromDate?.toISOString()));
|
|
50
|
+
dispatch(setToDate(value.toDate?.toISOString()));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleSubmit = () => {
|
|
54
|
+
if (!onSubmit) return;
|
|
55
|
+
|
|
56
|
+
const { fromDate, toDate, travelers, selectedTravelClass, selectedTravelType, selectedNationality, adults, kids, babies, rooms, selectedFlexRange } =
|
|
57
|
+
qsmState;
|
|
58
|
+
|
|
59
|
+
const selectedTravelTypeValue = travelTypes.find((t) => t.label === selectedTravelType);
|
|
60
|
+
|
|
61
|
+
const payload = {
|
|
62
|
+
fromDate,
|
|
63
|
+
toDate,
|
|
64
|
+
travelClass: selectedTravelClass,
|
|
65
|
+
travelType: selectedTravelTypeValue,
|
|
66
|
+
nationality: selectedNationality,
|
|
67
|
+
rooms
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
addSearchFieldsToPayload(payload, searchFields, qsmState);
|
|
71
|
+
onSubmit(payload);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const addSearchFieldsToPayload = (payload: any, fields: FieldConfig[], state: QSMState) => {
|
|
75
|
+
fields.forEach((field) => {
|
|
76
|
+
if (field.type === 'single') {
|
|
77
|
+
const key = field.fieldKey;
|
|
78
|
+
const option = field.options.find((opt) => opt.value === state[key]);
|
|
79
|
+
payload[key] = option ?? state[key];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (field.type === 'double' && field.fields) {
|
|
83
|
+
// recursively add each nested field
|
|
84
|
+
field.fields.forEach((nestedField) => {
|
|
85
|
+
const key = nestedField.fieldKey;
|
|
86
|
+
const option = nestedField.options.find((opt) => opt.value === state[key]);
|
|
87
|
+
payload[key] = option ?? state[key];
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div className="qsm">
|
|
95
|
+
<div className="qsm__content">
|
|
96
|
+
<div className="qsm__tabs">
|
|
97
|
+
<button type="button" className="qsm__tab">
|
|
98
|
+
<span className="qsm__tab__icons">
|
|
99
|
+
<Icon name="ui-location" height={16} />
|
|
100
|
+
</span>
|
|
101
|
+
{translations.QSM.MULTIDESTINATION}
|
|
102
|
+
</button>
|
|
103
|
+
<button type="button" className="qsm__tab">
|
|
104
|
+
<span className="qsm__tab__icons">
|
|
105
|
+
<Icon name="ui-suitcase" height={16} />
|
|
106
|
+
</span>
|
|
107
|
+
{translations.QSM.PACKAGES}
|
|
108
|
+
</button>
|
|
109
|
+
<button type="button" className="qsm__tab qsm__tab--active">
|
|
110
|
+
<span className="qsm__tab__icons">
|
|
111
|
+
<Icon name="ui-backforward" height={14} />
|
|
112
|
+
+
|
|
113
|
+
<Icon name="ui-bed" height={14} />
|
|
114
|
+
</span>
|
|
115
|
+
{translations.QSM.TRANSPORT_HOTEL}
|
|
116
|
+
</button>
|
|
117
|
+
<button type="button" className="qsm__tab">
|
|
118
|
+
<span className="qsm__tab__icons">
|
|
119
|
+
<Icon name="ui-bed" height={16} />
|
|
120
|
+
</span>
|
|
121
|
+
{translations.QSM.ACCOMMODATION}
|
|
122
|
+
</button>
|
|
123
|
+
<button type="button" className="qsm__tab">
|
|
124
|
+
<span className="qsm__tab__icons">
|
|
125
|
+
<Icon name="ui-flight" height={16} />
|
|
126
|
+
</span>
|
|
127
|
+
{translations.QSM.TRANSPORTS}
|
|
128
|
+
</button>
|
|
129
|
+
<button type="button" className="qsm__tab">
|
|
130
|
+
<span className="qsm__tab__icons">
|
|
131
|
+
<Icon name="ui-ticket" height={16} />
|
|
132
|
+
</span>
|
|
133
|
+
{translations.QSM.TICKET_ONLY}
|
|
134
|
+
</button>
|
|
135
|
+
<button type="button" className="qsm__tab">
|
|
136
|
+
<span className="qsm__tab__icons">
|
|
137
|
+
<Icon name="ui-car" height={16} />
|
|
138
|
+
</span>
|
|
139
|
+
{translations.QSM.RENT_A_CAR}
|
|
140
|
+
</button>
|
|
141
|
+
<button type="button" className="qsm__tab">
|
|
142
|
+
<span className="qsm__tab__icons">
|
|
143
|
+
<Icon name="ui-backforward" height={16} />
|
|
144
|
+
</span>
|
|
145
|
+
{translations.QSM.TRANSFERS}
|
|
146
|
+
</button>
|
|
147
|
+
<button type="button" className="qsm__tab">
|
|
148
|
+
<span className="qsm__tab__icons">
|
|
149
|
+
<Icon name="ui-ship" height={16} />
|
|
150
|
+
</span>
|
|
151
|
+
{translations.QSM.CRUISES}
|
|
152
|
+
</button>
|
|
153
|
+
</div>
|
|
154
|
+
<div className="qsm__filter">
|
|
155
|
+
<div className="radiobutton-group qsm__filter__inputgroup">
|
|
156
|
+
<div className="radiobutton">
|
|
157
|
+
<label className="radiobutton__label">
|
|
158
|
+
<input
|
|
159
|
+
type="radio"
|
|
160
|
+
name="mainBookerId"
|
|
161
|
+
// onChange={handleMainBookerChange}
|
|
162
|
+
// onBlur={formik.handleBlur}
|
|
163
|
+
value=""
|
|
164
|
+
// checked={formik.values.mainBookerId === travelerValues.id}
|
|
165
|
+
checked={true}
|
|
166
|
+
readOnly
|
|
167
|
+
className="radiobutton__input"
|
|
168
|
+
/>
|
|
169
|
+
<span>{translations.QSM.ONE_ACCOMMODATION}</span>
|
|
170
|
+
</label>
|
|
171
|
+
</div>
|
|
172
|
+
<div className="radiobutton">
|
|
173
|
+
<label className="radiobutton__label">
|
|
174
|
+
<input
|
|
175
|
+
type="radio"
|
|
176
|
+
name="mainBookerId"
|
|
177
|
+
// onChange={handleMainBookerChange}
|
|
178
|
+
// onBlur={formik.handleBlur}
|
|
179
|
+
value=""
|
|
180
|
+
// checked={formik.values.mainBookerId === travelerValues.id}
|
|
181
|
+
className="radiobutton__input"
|
|
182
|
+
disabled={true}
|
|
183
|
+
/>
|
|
184
|
+
<span>{translations.QSM.MULTIPLE_ACCOMMODATIONS}</span>
|
|
185
|
+
</label>
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
<div className="qsm__filter__classgroup">
|
|
189
|
+
<TravelClassPicker />
|
|
190
|
+
<TravelTypePicker />
|
|
191
|
+
<TravelNationalityPicker />
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
<div className="qsm__input-group">
|
|
195
|
+
{searchFields.map((field, idx) => {
|
|
196
|
+
if (field.type === 'double') {
|
|
197
|
+
return <DoubleSearchInputGroup key={idx} fieldKey={field.fieldKey} showReverse={field.showReverse} />;
|
|
198
|
+
}
|
|
199
|
+
return <SearchInputGroup key={idx} fieldKey={field.fieldKey} />;
|
|
200
|
+
})}
|
|
201
|
+
|
|
202
|
+
<Dates value={dateRange} onChange={handleDateChange} />
|
|
203
|
+
|
|
204
|
+
{askTravelers && <TravelInputGroup />}
|
|
205
|
+
|
|
206
|
+
<button type="button" className="cta" onClick={handleSubmit}>
|
|
207
|
+
{submitIcon && submitIcon.toString().length > 0 && <span>{submitIcon}</span>}
|
|
208
|
+
<span>{translations.QSM.CONFIRM}</span>
|
|
209
|
+
</button>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
{isMobile && mobileFilterType && <MobileFilterModal />}
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export default QSMContainer;
|
|
@@ -15,9 +15,11 @@ import TravelInput from '../travel-input';
|
|
|
15
15
|
import { format } from 'date-fns';
|
|
16
16
|
import QSMConfigurationContext from '../../qsm-configuration-context';
|
|
17
17
|
import { TypeaheadOption } from '../../types';
|
|
18
|
+
import { getTranslations } from '../../../shared/utils/localization-util';
|
|
18
19
|
|
|
19
20
|
const MobileFilterModal: React.FC = () => {
|
|
20
|
-
const { datesIcon } = useContext(QSMConfigurationContext);
|
|
21
|
+
const { datesIcon, languageCode } = useContext(QSMConfigurationContext);
|
|
22
|
+
const translations = getTranslations(languageCode ?? 'en-GB');
|
|
21
23
|
const dispatch = useDispatch();
|
|
22
24
|
const { mobileFilterType, mobileDatePickerMode, activeSearchFieldProps, fromDate, toDate } = useSelector((state: QSMRootState) => state.qsm);
|
|
23
25
|
|
|
@@ -103,7 +105,7 @@ const MobileFilterModal: React.FC = () => {
|
|
|
103
105
|
{/* header */}
|
|
104
106
|
<div className="mobile-qsm-filter__modal-header">
|
|
105
107
|
<div className="mobile-qsm-filter__modal-header-row">
|
|
106
|
-
<span className="mobile-qsm-filter__modal-header-title">
|
|
108
|
+
<span className="mobile-qsm-filter__modal-header-title">{translations.QSM.CHOOSE_DATES}</span>
|
|
107
109
|
<span className="mobile-qsm-filter__modal-header-close" onClick={closeModal}></span>
|
|
108
110
|
</div>
|
|
109
111
|
</div>
|
|
@@ -114,12 +116,12 @@ const MobileFilterModal: React.FC = () => {
|
|
|
114
116
|
<div className="qsm__double-input__wrapper">
|
|
115
117
|
<label className="qsm__input-wrapper">
|
|
116
118
|
{datesIcon && <span className="qsm__input-icon">{datesIcon}</span>}
|
|
117
|
-
<span className="qsm__label">
|
|
119
|
+
<span className="qsm__label">{translations.QSM.DEPARTURE_DATE}</span>
|
|
118
120
|
<input
|
|
119
121
|
type="text"
|
|
120
122
|
id="vertrek"
|
|
121
123
|
className="qsm__input u-ps-2"
|
|
122
|
-
placeholder=
|
|
124
|
+
placeholder={translations.QSM.DEPARTURE_DATE}
|
|
123
125
|
readOnly
|
|
124
126
|
value={fromDate ? format(new Date(fromDate), 'dd/MM/yyyy') : ''}
|
|
125
127
|
/>
|
|
@@ -130,12 +132,12 @@ const MobileFilterModal: React.FC = () => {
|
|
|
130
132
|
{mobileDatePickerMode === 'range' && (
|
|
131
133
|
<label className="qsm__input-wrapper">
|
|
132
134
|
{datesIcon && <span className="qsm__input-icon">{datesIcon}</span>}
|
|
133
|
-
<span className="qsm__label qsm__label--second-input-label">
|
|
135
|
+
<span className="qsm__label qsm__label--second-input-label">{translations.QSM.RETURN_DATE}</span>
|
|
134
136
|
<input
|
|
135
137
|
type="text"
|
|
136
138
|
id="retour"
|
|
137
139
|
className="qsm__input"
|
|
138
|
-
placeholder=
|
|
140
|
+
placeholder={translations.QSM.RETURN_DATE}
|
|
139
141
|
readOnly
|
|
140
142
|
value={toDate ? format(new Date(toDate), 'dd/MM/yyyy') : ''}
|
|
141
143
|
/>
|
|
@@ -171,7 +173,7 @@ const MobileFilterModal: React.FC = () => {
|
|
|
171
173
|
closeModal();
|
|
172
174
|
}
|
|
173
175
|
}}>
|
|
174
|
-
|
|
176
|
+
{translations.QSM.CONFIRM}
|
|
175
177
|
</button>
|
|
176
178
|
</div>
|
|
177
179
|
</div>
|
|
@@ -215,7 +217,7 @@ const MobileFilterModal: React.FC = () => {
|
|
|
215
217
|
</div>
|
|
216
218
|
<div className="mobile-qsm-filter__modal-footer">
|
|
217
219
|
<button className="cta" onClick={closeModal}>
|
|
218
|
-
|
|
220
|
+
{translations.QSM.CONFIRM}
|
|
219
221
|
</button>
|
|
220
222
|
</div>
|
|
221
223
|
{/* </div> */}
|
|
@@ -236,7 +238,7 @@ const MobileFilterModal: React.FC = () => {
|
|
|
236
238
|
{/* header */}
|
|
237
239
|
<div className="mobile-qsm-filter__modal-header">
|
|
238
240
|
<div className="mobile-qsm-filter__modal-header-row">
|
|
239
|
-
<span className="mobile-qsm-filter__modal-header-title">
|
|
241
|
+
<span className="mobile-qsm-filter__modal-header-title">{translations.QSM.TRAVELERS}</span>
|
|
240
242
|
<span className="mobile-qsm-filter__modal-header-close" onClick={closeModal}></span>
|
|
241
243
|
</div>
|
|
242
244
|
</div>
|
|
@@ -249,7 +251,7 @@ const MobileFilterModal: React.FC = () => {
|
|
|
249
251
|
|
|
250
252
|
<div className="mobile-qsm-filter__modal-footer">
|
|
251
253
|
<button className="cta" onClick={closeModal}>
|
|
252
|
-
|
|
254
|
+
{translations.QSM.CONFIRM}
|
|
253
255
|
</button>
|
|
254
256
|
</div>
|
|
255
257
|
</div>
|