@qite/tide-booking-component 1.4.111 → 1.4.113
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 +320 -269
- package/build/build-cjs/src/search-results/components/search-results-container/search-results-container.d.ts +4 -1
- package/build/build-cjs/src/search-results/index.d.ts +1 -0
- package/build/build-cjs/src/shared/booking/summary.d.ts +1 -0
- package/build/build-cjs/src/shared/booking/travelers-form.d.ts +3 -3
- package/build/build-esm/index.js +319 -269
- package/build/build-esm/src/search-results/components/search-results-container/search-results-container.d.ts +4 -1
- package/build/build-esm/src/search-results/index.d.ts +1 -0
- package/build/build-esm/src/shared/booking/summary.d.ts +1 -0
- package/build/build-esm/src/shared/booking/travelers-form.d.ts +3 -3
- package/package.json +2 -2
- package/src/search-results/components/book-packaging-entry/index.tsx +90 -73
- package/src/search-results/components/search-results-container/search-results-container.tsx +19 -11
- package/src/search-results/index.tsx +3 -2
- package/src/shared/booking/booking-panel.tsx +1 -1
- package/src/shared/booking/summary.tsx +4 -1
- package/src/shared/booking/travelers-form.tsx +21 -17
- package/src/shared/translations/ar-SA.json +3 -1
- package/src/shared/translations/da-DK.json +3 -1
- package/src/shared/translations/de-DE.json +3 -1
- package/src/shared/translations/en-GB.json +3 -1
- package/src/shared/translations/es-ES.json +3 -1
- package/src/shared/translations/fr-BE.json +3 -1
- package/src/shared/translations/fr-FR.json +3 -1
- package/src/shared/translations/is-IS.json +3 -1
- package/src/shared/translations/it-IT.json +3 -1
- package/src/shared/translations/ja-JP.json +3 -1
- package/src/shared/translations/nl-BE.json +3 -1
- package/src/shared/translations/nl-NL.json +3 -1
- package/src/shared/translations/no-NO.json +3 -1
- package/src/shared/translations/pl-PL.json +3 -1
- package/src/shared/translations/pt-PT.json +3 -1
- package/src/shared/translations/sv-SE.json +3 -1
- package/styles/components/_booking.scss +43 -15
- package/styles/components/_cta.scss +2 -2
- package/styles/components/_flight-option.scss +1 -1
- package/styles/components/_step-indicators.scss +41 -15
- package/styles/components/_tree.scss +2 -2
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
interface SearchResultsContainerProps {
|
|
3
|
+
onBookingStarted?: () => void;
|
|
4
|
+
}
|
|
5
|
+
declare const SearchResultsContainer: React.FC<SearchResultsContainerProps>;
|
|
3
6
|
export default SearchResultsContainer;
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { SearchResultsConfiguration } from './types';
|
|
3
3
|
interface SearchResultsProps {
|
|
4
4
|
configuration: SearchResultsConfiguration;
|
|
5
|
+
onBookingStarted?: () => void;
|
|
5
6
|
}
|
|
6
7
|
declare const SearchResults: React.FC<SearchResultsProps>;
|
|
7
8
|
export default SearchResults;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
2
|
import { FormikProps } from 'formik';
|
|
3
3
|
import { Country, RoomTraveler, Traveler, TravelersFormValues } from '../../booking-wizard/types';
|
|
4
|
-
import { CountryItem, PackagingEntry } from '@qite/tide-client';
|
|
4
|
+
import { CountryItem, PackagingEntry, PackagingEntryPax } from '@qite/tide-client';
|
|
5
5
|
export type TravelersFormField = {
|
|
6
6
|
type: string;
|
|
7
7
|
};
|
|
@@ -56,12 +56,12 @@ export declare function createInitialValuesFromRooms(
|
|
|
56
56
|
personTranslation?: string,
|
|
57
57
|
isCompact?: boolean
|
|
58
58
|
): TravelersFormValues;
|
|
59
|
-
export declare function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry:
|
|
59
|
+
export declare function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry: PackagingEntry, agentAdressId?: number): TravelersFormValues;
|
|
60
60
|
export declare function applyTravelersFormValuesToEditablePackagingEntry(
|
|
61
61
|
editablePackagingEntry: PackagingEntry,
|
|
62
62
|
values: TravelersFormValues
|
|
63
63
|
): {
|
|
64
|
-
pax:
|
|
64
|
+
pax: PackagingEntryPax[];
|
|
65
65
|
address: {
|
|
66
66
|
street: string;
|
|
67
67
|
houseNumber: 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.113",
|
|
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.173",
|
|
33
33
|
"@reduxjs/toolkit": "^2.8.2",
|
|
34
34
|
"@rollup/plugin-commonjs": "^19.0.1",
|
|
35
35
|
"@rollup/plugin-json": "^4.1.0",
|
|
@@ -16,12 +16,9 @@ import { useFormik } from 'formik';
|
|
|
16
16
|
import { TravelersFormValues } from '../../../booking-wizard/types';
|
|
17
17
|
import { setBookingNumber, setCurrentStep, setEditablePackagingEntry } from '../../store/search-results-slice';
|
|
18
18
|
import validateForm from '../../../booking-wizard/features/travelers-form/validate-form';
|
|
19
|
-
import { bookPackagingEntry, CountryItem, getCountries, PackagingEntry, TideClientConfig } from '@qite/tide-client';
|
|
19
|
+
import { bookPackagingEntry, CountryItem, getCountries, PackagingEntry, PackagingRequestBase, TideClientConfig } from '@qite/tide-client';
|
|
20
20
|
import SharedSummary from '../../../shared/booking/summary';
|
|
21
21
|
import { renderEditablePackagingEntrySummaryOptions } from '../../../shared/utils/booking-summary';
|
|
22
|
-
|
|
23
|
-
// TODO; fix import
|
|
24
|
-
import { PackagingRequestBase } from '@qite/tide-client/build/types/booking-v2/request/packaging/packaging-request-base';
|
|
25
22
|
import SharedConfirmation from '../../../shared/booking/shared-confirmation';
|
|
26
23
|
|
|
27
24
|
interface BookPackagingEntryProps {
|
|
@@ -55,6 +52,7 @@ const travellersSettings: SharedTravelersSettings = {
|
|
|
55
52
|
const BookPackagingEntry: React.FC<BookPackagingEntryProps> = ({ activeSearchSeed, isConfirmationPage }) => {
|
|
56
53
|
const context = useContext(SearchResultsConfigurationContext);
|
|
57
54
|
const dispatch = useDispatch();
|
|
55
|
+
|
|
58
56
|
const { editablePackagingEntry, priceDetails, currentStep, bookingNumber } = useSelector((state: SearchResultsRootState) => state.searchResults);
|
|
59
57
|
|
|
60
58
|
const [countries, setCountries] = useState<CountryItem[]>([]);
|
|
@@ -62,44 +60,56 @@ const BookPackagingEntry: React.FC<BookPackagingEntryProps> = ({ activeSearchSee
|
|
|
62
60
|
const [remarks, setRemarks] = useState('');
|
|
63
61
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const config: TideClientConfig = {
|
|
68
|
-
host: context.tideConnection.host,
|
|
69
|
-
apiKey: context.tideConnection.apiKey
|
|
70
|
-
};
|
|
63
|
+
const translations = useMemo(() => getTranslations(context?.languageCode ?? 'en-GB'), [context?.languageCode]);
|
|
71
64
|
|
|
72
|
-
const translations = getTranslations(context?.languageCode ?? 'en-GB');
|
|
73
65
|
const stepLabels = [translations.STEPS.PERSONAL_DETAILS, translations.STEPS.SUMMARY, translations.STEPS.CONFIRMATION];
|
|
74
66
|
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
const config: TideClientConfig | null = useMemo(() => {
|
|
68
|
+
if (!context) return null;
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
host: context.tideConnection.host,
|
|
72
|
+
apiKey: context.tideConnection.apiKey
|
|
73
|
+
};
|
|
74
|
+
}, [context]);
|
|
75
|
+
|
|
76
|
+
const initialValues = useMemo(() => {
|
|
77
|
+
if (!editablePackagingEntry) {
|
|
78
|
+
return {} as TravelersFormValues;
|
|
79
|
+
}
|
|
77
80
|
|
|
78
|
-
|
|
81
|
+
return createInitialValuesFromEditablePackagingEntry(editablePackagingEntry);
|
|
82
|
+
}, [editablePackagingEntry?.transactionId]);
|
|
79
83
|
|
|
80
84
|
const formik = useFormik<TravelersFormValues>({
|
|
81
85
|
initialValues,
|
|
82
86
|
enableReinitialize: true,
|
|
83
87
|
validate: (values) => validateForm(values, false, 'b2c', translations, travellersSettings.formFields, travellersSettings.mainBookerFormFields),
|
|
84
88
|
onSubmit: (values) => {
|
|
89
|
+
if (!editablePackagingEntry) return;
|
|
90
|
+
|
|
85
91
|
dispatch(setEditablePackagingEntry(applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry, values)));
|
|
92
|
+
|
|
86
93
|
dispatch(setCurrentStep(1));
|
|
87
94
|
}
|
|
88
95
|
});
|
|
89
96
|
|
|
90
97
|
useEffect(() => {
|
|
91
|
-
if (!context) return;
|
|
98
|
+
if (!context || !config) return;
|
|
99
|
+
|
|
92
100
|
const controller = new AbortController();
|
|
93
101
|
|
|
94
102
|
(async () => {
|
|
95
103
|
try {
|
|
96
104
|
const result = await getCountries(config, controller.signal);
|
|
97
105
|
setCountries(result.items);
|
|
98
|
-
} catch {
|
|
106
|
+
} catch {
|
|
107
|
+
// optionally handle error
|
|
108
|
+
}
|
|
99
109
|
})();
|
|
100
110
|
|
|
101
111
|
return () => controller.abort();
|
|
102
|
-
}, []);
|
|
112
|
+
}, [context, config]);
|
|
103
113
|
|
|
104
114
|
useEffect(() => {
|
|
105
115
|
if (isConfirmationPage) {
|
|
@@ -107,6 +117,8 @@ const BookPackagingEntry: React.FC<BookPackagingEntryProps> = ({ activeSearchSee
|
|
|
107
117
|
}
|
|
108
118
|
}, [isConfirmationPage, dispatch]);
|
|
109
119
|
|
|
120
|
+
if (!context || !editablePackagingEntry || !priceDetails || !config) return null;
|
|
121
|
+
|
|
110
122
|
const handleSummarySubmit: React.FormEventHandler<HTMLFormElement> = async (e) => {
|
|
111
123
|
e.preventDefault();
|
|
112
124
|
|
|
@@ -144,6 +156,7 @@ const BookPackagingEntry: React.FC<BookPackagingEntryProps> = ({ activeSearchSee
|
|
|
144
156
|
agentId: context.agentId,
|
|
145
157
|
payload: updatedEditablePackagingEntry
|
|
146
158
|
} as PackagingRequestBase<PackagingEntry>;
|
|
159
|
+
|
|
147
160
|
const bookingResponse = await bookPackagingEntry(config, request);
|
|
148
161
|
|
|
149
162
|
dispatch(setBookingNumber(bookingResponse.number));
|
|
@@ -163,63 +176,67 @@ const BookPackagingEntry: React.FC<BookPackagingEntryProps> = ({ activeSearchSee
|
|
|
163
176
|
return (
|
|
164
177
|
<div className="booking">
|
|
165
178
|
<div className="booking__content">
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
179
|
+
<div className="booking__panel">
|
|
180
|
+
<BookingPanel
|
|
181
|
+
currentStep={currentStep}
|
|
182
|
+
stepLabels={stepLabels}
|
|
183
|
+
StepIndicatorsComponent={StepIndicators}
|
|
184
|
+
renderTitle={(step) => (
|
|
185
|
+
<>
|
|
186
|
+
{step + 1}. {stepLabels[step]}
|
|
187
|
+
</>
|
|
188
|
+
)}>
|
|
189
|
+
{currentStep === 0 && (
|
|
190
|
+
<SharedTravelersForm
|
|
191
|
+
formik={formik}
|
|
192
|
+
translations={translations}
|
|
193
|
+
travellersSettings={travellersSettings}
|
|
194
|
+
countries={countries}
|
|
195
|
+
travelersFirstStep={false}
|
|
196
|
+
isUnavailable={false}
|
|
197
|
+
useCompactForm={false}
|
|
198
|
+
showAgentSelection={false}
|
|
199
|
+
/>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
{currentStep === 1 && (
|
|
203
|
+
<SharedSummary
|
|
204
|
+
translations={translations}
|
|
205
|
+
travelerFormValues={formik.values}
|
|
206
|
+
isSubmitting={isSubmitting}
|
|
207
|
+
skipPayment={!context.generatePaymentUrl}
|
|
208
|
+
userValidated={userValidated}
|
|
209
|
+
remarks={remarks}
|
|
210
|
+
enableVoucher={false}
|
|
211
|
+
allowOption={false}
|
|
212
|
+
isOffer={false}
|
|
213
|
+
onUserValidatedChange={setUserValidated}
|
|
214
|
+
onRemarksChange={setRemarks}
|
|
215
|
+
onSubmit={handleSummarySubmit}
|
|
216
|
+
renderOptions={() => renderEditablePackagingEntrySummaryOptions(editablePackagingEntry, priceDetails, translations)}
|
|
217
|
+
renderPreviousButton={() => (
|
|
218
|
+
<button type="button" title={translations.STEPS.PREVIOUS} onClick={() => dispatch(setCurrentStep(0))} className="cta cta--secondary">
|
|
219
|
+
{translations.STEPS.PREVIOUS}
|
|
220
|
+
</button>
|
|
221
|
+
)}
|
|
222
|
+
/>
|
|
223
|
+
)}
|
|
224
|
+
|
|
225
|
+
{currentStep === 2 && (
|
|
226
|
+
<SharedConfirmation
|
|
227
|
+
bookingNumber={bookingNumber ?? editablePackagingEntry?.dossierNumber ?? ''}
|
|
228
|
+
isOption={false}
|
|
229
|
+
isOffer={false}
|
|
230
|
+
translations={translations.CONFIRMATION}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
|
|
234
|
+
{currentStep === 3 && <div>{/* error */}</div>}
|
|
235
|
+
</BookingPanel>
|
|
236
|
+
</div>
|
|
237
|
+
|
|
222
238
|
<div className="backdrop" id="backdrop"></div>
|
|
239
|
+
|
|
223
240
|
<WLSidebar activeSearchSeed={activeSearchSeed} />
|
|
224
241
|
</div>
|
|
225
242
|
</div>
|
|
@@ -62,7 +62,8 @@ import {
|
|
|
62
62
|
PackagingEntryLineFlightLine,
|
|
63
63
|
PackagingEntryAddress,
|
|
64
64
|
PackagingEntryPax,
|
|
65
|
-
PackagingEntryRoom
|
|
65
|
+
PackagingEntryRoom,
|
|
66
|
+
PackagingRequestBase
|
|
66
67
|
} from '@qite/tide-client';
|
|
67
68
|
import { getDateFromParams, getNumberFromParams, getRoomsFromParams, getStringFromParams } from '../../../shared/utils/query-string-util';
|
|
68
69
|
import { concat, first, isEmpty, last, range } from 'lodash';
|
|
@@ -116,9 +117,6 @@ import DayByDayExcursions from '../excursions/day-by-day-excursions';
|
|
|
116
117
|
import BookPackagingEntry from '../book-packaging-entry';
|
|
117
118
|
import { format } from 'date-fns';
|
|
118
119
|
|
|
119
|
-
// TODO; fix import
|
|
120
|
-
import { PackagingRequestBase } from '@qite/tide-client/build/types/booking-v2/request/packaging/packaging-request-base';
|
|
121
|
-
|
|
122
120
|
type BuildPackagingEntryPartialArgs = {
|
|
123
121
|
sourceEntry: PackagingEntry | null | undefined;
|
|
124
122
|
selectedHotelCode: string | null | undefined;
|
|
@@ -130,7 +128,11 @@ type BuildPackagingEntryPartialArgs = {
|
|
|
130
128
|
language: string;
|
|
131
129
|
};
|
|
132
130
|
|
|
133
|
-
|
|
131
|
+
interface SearchResultsContainerProps {
|
|
132
|
+
onBookingStarted?: () => void;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const SearchResultsContainer: React.FC<SearchResultsContainerProps> = ({ onBookingStarted }) => {
|
|
134
136
|
const currentSearch = typeof window !== 'undefined' ? window.location.search : '';
|
|
135
137
|
|
|
136
138
|
const dispatch = useDispatch();
|
|
@@ -363,8 +365,8 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
363
365
|
if (typeof window !== 'undefined') {
|
|
364
366
|
window.scrollTo(0, 0);
|
|
365
367
|
}
|
|
366
|
-
var adults = seed.rooms.flatMap((x) => x.pax).filter((x) => x.age! >=
|
|
367
|
-
var kids = seed.rooms.flatMap((x) => x.pax).filter((x) => x.age! >= 2 && x.age! <
|
|
368
|
+
var adults = seed.rooms.flatMap((x) => x.pax).filter((x) => x.age! >= 12).length;
|
|
369
|
+
var kids = seed.rooms.flatMap((x) => x.pax).filter((x) => x.age! >= 2 && x.age! < 12).length;
|
|
368
370
|
var babies = seed.rooms.flatMap((x) => x.pax).filter((x) => x.age! < 2).length;
|
|
369
371
|
|
|
370
372
|
return {
|
|
@@ -814,6 +816,12 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
814
816
|
}
|
|
815
817
|
}, [context?.packagingEntry]);
|
|
816
818
|
|
|
819
|
+
useEffect(() => {
|
|
820
|
+
if (bookPackagingEntry && onBookingStarted) {
|
|
821
|
+
onBookingStarted();
|
|
822
|
+
}
|
|
823
|
+
}, [bookPackagingEntry, onBookingStarted]);
|
|
824
|
+
|
|
817
825
|
// separate detailsCall
|
|
818
826
|
useEffect(() => {
|
|
819
827
|
const fetchDetails = async () => {
|
|
@@ -1437,12 +1445,12 @@ const SearchResultsContainer: React.FC = () => {
|
|
|
1437
1445
|
seed.rooms?.forEach((room, roomIndex) => {
|
|
1438
1446
|
const paxIds = room.pax.map((_, paxIndex) => {
|
|
1439
1447
|
const id = paxId++;
|
|
1440
|
-
|
|
1441
1448
|
pax.push({
|
|
1442
1449
|
id,
|
|
1443
|
-
firstName: '',
|
|
1444
|
-
lastName: '',
|
|
1445
|
-
dateOfBirth: null,
|
|
1450
|
+
firstName: _.firstName || '',
|
|
1451
|
+
lastName: _.lastName || '',
|
|
1452
|
+
dateOfBirth: _.dateOfBirth || null,
|
|
1453
|
+
age: _.age || null,
|
|
1446
1454
|
isMainBooker: roomIndex === 0 && paxIndex === 0
|
|
1447
1455
|
});
|
|
1448
1456
|
|
|
@@ -7,15 +7,16 @@ import { createSearchResultsStore } from './store/search-results-store';
|
|
|
7
7
|
|
|
8
8
|
interface SearchResultsProps {
|
|
9
9
|
configuration: SearchResultsConfiguration;
|
|
10
|
+
onBookingStarted?: () => void;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const SearchResults: React.FC<SearchResultsProps> = ({ configuration }) => {
|
|
13
|
+
const SearchResults: React.FC<SearchResultsProps> = ({ configuration, onBookingStarted }) => {
|
|
13
14
|
const store = React.useMemo(() => createSearchResultsStore(), []);
|
|
14
15
|
|
|
15
16
|
return (
|
|
16
17
|
<Provider store={store}>
|
|
17
18
|
<SearchResultsConfigurationContext.Provider value={configuration}>
|
|
18
|
-
<SearchResultsContainer />
|
|
19
|
+
<SearchResultsContainer onBookingStarted={onBookingStarted} />
|
|
19
20
|
</SearchResultsConfigurationContext.Provider>
|
|
20
21
|
</Provider>
|
|
21
22
|
);
|
|
@@ -10,7 +10,7 @@ interface BookingPanelProps {
|
|
|
10
10
|
|
|
11
11
|
const BookingPanel: React.FC<BookingPanelProps> = ({ currentStep, stepLabels, renderTitle, children, StepIndicatorsComponent }) => {
|
|
12
12
|
return (
|
|
13
|
-
<div className="
|
|
13
|
+
<div className="booking__panel__wrapper">
|
|
14
14
|
<StepIndicatorsComponent currentStep={currentStep} stepLabels={stepLabels} />
|
|
15
15
|
<div className="booking__panel-frame booking__panel-frame--transparent">
|
|
16
16
|
<div className="booking__panel-heading">
|
|
@@ -4,6 +4,7 @@ import { SummaryCheckbox, TravelersFormValues } from '../../booking-wizard/types
|
|
|
4
4
|
import Loader from '../components/loader';
|
|
5
5
|
import { buildClassName } from '../utils/class-util';
|
|
6
6
|
import Icon from '../components/icon';
|
|
7
|
+
import Spinner from '../../search-results/components/spinner/spinner';
|
|
7
8
|
|
|
8
9
|
export interface SummaryNotification {
|
|
9
10
|
id: number;
|
|
@@ -32,6 +33,7 @@ export interface SharedSummaryProps {
|
|
|
32
33
|
isOffer?: boolean;
|
|
33
34
|
customValidateText?: string;
|
|
34
35
|
isSubmitting?: boolean;
|
|
36
|
+
skipPayment?: boolean;
|
|
35
37
|
userValidated?: boolean;
|
|
36
38
|
renderOptions: () => ReactNode;
|
|
37
39
|
renderPreviousButton: () => ReactNode;
|
|
@@ -66,6 +68,7 @@ const SharedSummary: React.FC<SharedSummaryProps> = ({
|
|
|
66
68
|
isOffer = false,
|
|
67
69
|
customValidateText,
|
|
68
70
|
isSubmitting = false,
|
|
71
|
+
skipPayment = false,
|
|
69
72
|
userValidated = true,
|
|
70
73
|
renderOptions,
|
|
71
74
|
renderPreviousButton,
|
|
@@ -122,7 +125,7 @@ const SharedSummary: React.FC<SharedSummaryProps> = ({
|
|
|
122
125
|
|
|
123
126
|
return (
|
|
124
127
|
<>
|
|
125
|
-
{isSubmitting &&
|
|
128
|
+
{isSubmitting && <Spinner label={skipPayment ? translations.SUMMARY.PROCESS_BOOKING : translations.SUMMARY.REDIRECT} />}
|
|
126
129
|
{!isSubmitting && (
|
|
127
130
|
<form className="form" name="booking--summary" id="booking--summary" onSubmit={onSubmit}>
|
|
128
131
|
<div className="form__booking--summary">
|
|
@@ -10,7 +10,7 @@ import PhoneInput from '../../booking-wizard/components/phone-input';
|
|
|
10
10
|
import GenderControl from '../../booking-wizard/features/travelers-form/controls/gender-control';
|
|
11
11
|
import TypeAheadInput from '../../booking-wizard/features/travelers-form/type-ahead-input';
|
|
12
12
|
import { buildClassName } from '../utils/class-util';
|
|
13
|
-
import { CountryItem, PackagingEntry } from '@qite/tide-client';
|
|
13
|
+
import { CountryItem, PackagingEntry, PackagingEntryPax } from '@qite/tide-client';
|
|
14
14
|
|
|
15
15
|
export type TravelersFormField = { type: string };
|
|
16
16
|
export type AgentOption = { id: number | string; name: string; postalCode?: string; location?: string };
|
|
@@ -97,25 +97,31 @@ export function createInitialValuesFromRooms(
|
|
|
97
97
|
return initialValues;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
export function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry:
|
|
101
|
-
const accommodationLine = editablePackagingEntry?.lines?.find((line: any) => line.pax?.length);
|
|
100
|
+
export function createInitialValuesFromEditablePackagingEntry(editablePackagingEntry: PackagingEntry, agentAdressId?: number): TravelersFormValues {
|
|
102
101
|
const pax = editablePackagingEntry?.pax ?? [];
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
102
|
+
const rooms = editablePackagingEntry.rooms.map((room) => {
|
|
103
|
+
const roomPax = pax.filter((x: PackagingEntryPax) => room.paxIds.includes(x.id));
|
|
104
|
+
const adults = roomPax.filter((x: PackagingEntryPax) => x.age! >= 18);
|
|
105
|
+
const children = roomPax.filter((x: PackagingEntryPax) => x.age! < 18);
|
|
107
106
|
return {
|
|
108
|
-
adults:
|
|
109
|
-
const entryPax = pax.find((x: any) => x.id === roomTraveler.paxId) ?? {};
|
|
107
|
+
adults: adults.map((roomTraveler: PackagingEntryPax) => {
|
|
110
108
|
return {
|
|
111
|
-
id:
|
|
112
|
-
firstName:
|
|
113
|
-
lastName:
|
|
114
|
-
birthDate:
|
|
115
|
-
gender:
|
|
109
|
+
id: roomTraveler.id,
|
|
110
|
+
firstName: roomTraveler.firstName ?? '',
|
|
111
|
+
lastName: roomTraveler.lastName ?? '',
|
|
112
|
+
birthDate: roomTraveler.dateOfBirth ? format(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
113
|
+
gender: ''
|
|
116
114
|
} as Traveler;
|
|
117
115
|
}),
|
|
118
|
-
children:
|
|
116
|
+
children: children.map((roomTraveler: PackagingEntryPax) => {
|
|
117
|
+
return {
|
|
118
|
+
id: roomTraveler.id,
|
|
119
|
+
firstName: roomTraveler.firstName ?? '',
|
|
120
|
+
lastName: roomTraveler.lastName ?? '',
|
|
121
|
+
birthDate: roomTraveler.dateOfBirth ? format(new Date(roomTraveler.dateOfBirth), 'yyyy-MM-dd') : '',
|
|
122
|
+
gender: ''
|
|
123
|
+
} as Traveler;
|
|
124
|
+
})
|
|
119
125
|
};
|
|
120
126
|
});
|
|
121
127
|
|
|
@@ -146,8 +152,6 @@ export function createInitialValuesFromEditablePackagingEntry(editablePackagingE
|
|
|
146
152
|
|
|
147
153
|
export function applyTravelersFormValuesToEditablePackagingEntry(editablePackagingEntry: PackagingEntry, values: TravelersFormValues) {
|
|
148
154
|
const travelers = values.rooms.flatMap((room) => [...room.adults, ...room.children]);
|
|
149
|
-
console.log('Applying form values:', values);
|
|
150
|
-
console.log('editablePackagingEntry:', editablePackagingEntry);
|
|
151
155
|
|
|
152
156
|
return {
|
|
153
157
|
...editablePackagingEntry,
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "تحقق من القسيمة",
|
|
226
226
|
"ADD_VOUCHER": "إضافة قسيمة",
|
|
227
227
|
"VOUCHER_VALID": "القسيمة صالحة",
|
|
228
|
-
"VOUCHER_INVALID": "القسيمة غير صالحة"
|
|
228
|
+
"VOUCHER_INVALID": "القسيمة غير صالحة",
|
|
229
|
+
"REDIRECT": "إعادة التوجيه إلى مزود الدفع...",
|
|
230
|
+
"PROCESS_BOOKING": "يرجى الانتظار، جاري معالجة حجزك"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "تم طلب عرضك رقم {0}",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Valider voucher",
|
|
226
226
|
"ADD_VOUCHER": "Tilføj voucher",
|
|
227
227
|
"VOUCHER_VALID": "Voucher er gyldig",
|
|
228
|
-
"VOUCHER_INVALID": "Voucher er ikke gyldig"
|
|
228
|
+
"VOUCHER_INVALID": "Voucher er ikke gyldig",
|
|
229
|
+
"REDIRECT": "Omdirigerer til betalingsudbyder...",
|
|
230
|
+
"PROCESS_BOOKING": "Vent venligst, din booking behandles"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Dit tilbud med nummer {0} er blevet anmodet",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Gutschein prüfen",
|
|
226
226
|
"ADD_VOUCHER": "Gutschein hinzufügen",
|
|
227
227
|
"VOUCHER_VALID": "Gutschein ist gültig",
|
|
228
|
-
"VOUCHER_INVALID": "Gutschein ist ungültig"
|
|
228
|
+
"VOUCHER_INVALID": "Gutschein ist ungültig",
|
|
229
|
+
"REDIRECT": "Weiterleitung zum Zahlungsanbieter...",
|
|
230
|
+
"PROCESS_BOOKING": "Bitte warten Sie, Ihre Buchung wird bearbeitet"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Ihr Angebot mit der Nummer {0} wurde angefordert",
|
|
@@ -229,7 +229,9 @@
|
|
|
229
229
|
"VOUCHER_VALIDATE": "Validate voucher",
|
|
230
230
|
"ADD_VOUCHER": "Add voucher",
|
|
231
231
|
"VOUCHER_VALID": "Voucher is valid",
|
|
232
|
-
"VOUCHER_INVALID": "Voucher is not valid"
|
|
232
|
+
"VOUCHER_INVALID": "Voucher is not valid",
|
|
233
|
+
"REDIRECT": "Redirecting to payment provider...",
|
|
234
|
+
"PROCESS_BOOKING": "Please wait, your booking is being processed"
|
|
233
235
|
},
|
|
234
236
|
"CONFIRMATION": {
|
|
235
237
|
"TITLE_TEXT_OFFER": "Your quote with number {0} has been requested",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Validar vale",
|
|
226
226
|
"ADD_VOUCHER": "Agregar vale",
|
|
227
227
|
"VOUCHER_VALID": "Vale válido",
|
|
228
|
-
"VOUCHER_INVALID": "Vale no válido"
|
|
228
|
+
"VOUCHER_INVALID": "Vale no válido",
|
|
229
|
+
"REDIRECT": "Redirigiendo al proveedor de pagos...",
|
|
230
|
+
"PROCESS_BOOKING": "Por favor, espere, su reserva se está procesando"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Su presupuesto con número {0} ha sido solicitado",
|
|
@@ -229,7 +229,9 @@
|
|
|
229
229
|
"VOUCHER_VALIDATE": "Valider le bon",
|
|
230
230
|
"ADD_VOUCHER": "Ajouter un bon",
|
|
231
231
|
"VOUCHER_VALID": "Bon valide",
|
|
232
|
-
"VOUCHER_INVALID": "Bon invalide"
|
|
232
|
+
"VOUCHER_INVALID": "Bon invalide",
|
|
233
|
+
"REDIRECT": "Redirection vers le fournisseur de paiement...",
|
|
234
|
+
"PROCESS_BOOKING": "Veuillez patienter, votre réservation est en cours de traitement"
|
|
233
235
|
},
|
|
234
236
|
"CONFIRMATION": {
|
|
235
237
|
"TITLE_TEXT_OFFER": "Votre devis numéro {0} a été demandé",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Valider le bon",
|
|
226
226
|
"ADD_VOUCHER": "Ajouter un bon",
|
|
227
227
|
"VOUCHER_VALID": "Bon valide",
|
|
228
|
-
"VOUCHER_INVALID": "Bon invalide"
|
|
228
|
+
"VOUCHER_INVALID": "Bon invalide",
|
|
229
|
+
"REDIRECT": "Redirection vers le fournisseur de paiement...",
|
|
230
|
+
"PROCESS_BOOKING": "Veuillez patienter, votre réservation est en cours de traitement"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Votre devis numéro {0} a été demandé",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Staðfesta miða",
|
|
226
226
|
"ADD_VOUCHER": "Bæta við miða",
|
|
227
227
|
"VOUCHER_VALID": "Miðinn er gildur",
|
|
228
|
-
"VOUCHER_INVALID": "Miðinn er ógildur"
|
|
228
|
+
"VOUCHER_INVALID": "Miðinn er ógildur",
|
|
229
|
+
"REDIRECT": "Beinir á greiðsluaðila...",
|
|
230
|
+
"PROCESS_BOOKING": "Vinsamlegast bíðið, pöntunin þín er í vinnslu"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Tilboð þitt nr. {0} hefur verið beðið um",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "Valida voucher",
|
|
226
226
|
"ADD_VOUCHER": "Aggiungi voucher",
|
|
227
227
|
"VOUCHER_VALID": "Voucher valido",
|
|
228
|
-
"VOUCHER_INVALID": "Voucher non valido"
|
|
228
|
+
"VOUCHER_INVALID": "Voucher non valido",
|
|
229
|
+
"REDIRECT": "Reindirizzamento al fornitore di pagamento...",
|
|
230
|
+
"PROCESS_BOOKING": "Attendere prego, la tua prenotazione è in fase di elaborazione"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "Il tuo preventivo numero {0} è stato richiesto",
|
|
@@ -225,7 +225,9 @@
|
|
|
225
225
|
"VOUCHER_VALIDATE": "バウチャーを確認",
|
|
226
226
|
"ADD_VOUCHER": "バウチャーを追加",
|
|
227
227
|
"VOUCHER_VALID": "バウチャーは有効です",
|
|
228
|
-
"VOUCHER_INVALID": "バウチャーは無効です"
|
|
228
|
+
"VOUCHER_INVALID": "バウチャーは無効です",
|
|
229
|
+
"REDIRECT": "支払いプロバイダーにリダイレクト中...",
|
|
230
|
+
"PROCESS_BOOKING": "お待ちください、予約を処理中です"
|
|
229
231
|
},
|
|
230
232
|
"CONFIRMATION": {
|
|
231
233
|
"TITLE_TEXT_OFFER": "見積もり番号 {0} の依頼を受け付けました",
|
|
@@ -229,7 +229,9 @@
|
|
|
229
229
|
"VOUCHER_VALIDATE": "Valideer voucher",
|
|
230
230
|
"ADD_VOUCHER": "Voucher toevoegen",
|
|
231
231
|
"VOUCHER_VALID": "Voucher is geldig",
|
|
232
|
-
"VOUCHER_INVALID": "Voucher is niet geldig"
|
|
232
|
+
"VOUCHER_INVALID": "Voucher is niet geldig",
|
|
233
|
+
"REDIRECT": "Redirecten naar betalingsprovider...",
|
|
234
|
+
"PROCESS_BOOKING": "Even geduld, we verwerken je boeking"
|
|
233
235
|
},
|
|
234
236
|
"CONFIRMATION": {
|
|
235
237
|
"TITLE_TEXT_OFFER": "Je offerte met nummer {0} is aangevraagd",
|